Main.cpp revision 7727153c233679e1f0fb60702c3966b4e590956b
17727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao/*
27727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao * Copyright 2012, The Android Open Source Project
37727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao *
47727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao * Licensed under the Apache License, Version 2.0 (the "License");
57727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao * you may not use this file except in compliance with the License.
67727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao * You may obtain a copy of the License at
77727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao *
87727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao *     http://www.apache.org/licenses/LICENSE-2.0
97727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao *
107727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao * Unless required by applicable law or agreed to in writing, software
117727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao * distributed under the License is distributed on an "AS IS" BASIS,
127727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
137727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao * See the License for the specific language governing permissions and
147727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao * limitations under the License.
157727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao */
167727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
177727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#include <cerrno>
187727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#include <cstdio>
197727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#include <cstdlib>
207727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#include <cstring>
217727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
227727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#include <fcntl.h>
237727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
247727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#include "bcc/Config/Config.h"
257727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#include "bcc/Support/Initialization.h"
267727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#include "bcc/Support/Log.h"
277727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#include "bcc/AndroidBitcode/ABCCompilerDriver.h"
287727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
297727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#include <cutils/process_name.h>
307727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
317727153c233679e1f0fb60702c3966b4e590956bShih-wei Liaousing namespace bcc;
327727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
337727153c233679e1f0fb60702c3966b4e590956bShih-wei Liaostatic void usage() {
347727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  fprintf(stderr, "usage: abcc [--fd output_fd|--file output_filename]\n"
357727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#ifndef TARGET_BUILD
367727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao                  "            [--triple triple]\n"
377727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao                  "            [--android-sysroot sysroot]\n"
387727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#endif
397727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao                  "            input_filename(s) or input_fd(s)...\n");
407727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  return;
417727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao}
427727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
437727153c233679e1f0fb60702c3966b4e590956bShih-wei Liaostatic inline bool GetIntArg(const char *arg, int &result) {
447727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  char *endptr;
457727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
467727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  result = ::strtol(arg, &endptr, 0);
477727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (*endptr != '\0') {
487727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    return false;
497727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  } else {
507727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    return true;
517727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
527727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao}
537727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
547727153c233679e1f0fb60702c3966b4e590956bShih-wei Liaoenum Mode {
557727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  kUnknownMode,
567727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  kFdMode,
577727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  kFileMode
587727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao};
597727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
607727153c233679e1f0fb60702c3966b4e590956bShih-wei Liaostatic inline bool ParseArguments(int argc, const char *const *argv, Mode &mode,
617727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao                                  const char *&input, const char *&output,
627727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao                                  const char *&triple, const char *&sysroot) {
637727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (argc < 4) {
647727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    return false;
657727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
667727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
677727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  // Parse the mode in argv[1].
687727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (::strcmp(argv[1], "--fd") == 0) {
697727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    mode = kFdMode;
707727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  } else if (::strcmp(argv[1], "--file") == 0) {
717727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    mode = kFileMode;
727727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  } else {
737727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    ALOGE("Unknown mode '%s'!", argv[1]);
747727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    return false;
757727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
767727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
777727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  // output is always in argv[2].
787727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  output = argv[2];
797727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
807727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  // On-device version cannot configure the triple and sysroot.
817727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  unsigned arg_idx = 3;
827727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#ifndef TARGET_BUILD
837727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (::strcmp(argv[arg_idx], "--triple") == 0) {
847727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    if ((arg_idx + 2 /* --triple [triple] input */) >= argc) {
857727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao      ALOGE("Too few arguments when --triple was given!");
867727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao      return false;
877727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    }
887727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
897727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    triple = argv[arg_idx + 1];
907727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    arg_idx += 2;
917727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
927727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
937727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (::strcmp(argv[arg_idx], "--android-sysroot") == 0) {
947727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    if ((arg_idx + 2 /* --android-sysroot [sysroot] input */) >= argc) {
957727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao      ALOGE("Too few arguments when --android-sysroot was given!");
967727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao      return false;
977727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    }
987727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
997727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    sysroot = argv[arg_idx + 1];
1007727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    arg_idx += 2;
1017727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
1027727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao#endif
1037727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1047727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (triple == NULL) {
1057727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    triple = DEFAULT_TARGET_TRIPLE_STRING;
1067727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
1077727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1087727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (sysroot == NULL) {
1097727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    sysroot = "/";
1107727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
1117727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1127727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  ALOGD("Triple: %s, Android sysroot: %s", triple, sysroot);
1137727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1147727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  // input is in argv[arg_idx]
1157727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  // TODO: Support multiple input files.
1167727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  input = argv[arg_idx];
1177727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1187727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  return true;
1197727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao}
1207727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1217727153c233679e1f0fb60702c3966b4e590956bShih-wei Liaostatic bool Build(int input_fd, int output_fd,
1227727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao                  const char *triple, const char *sysroot) {
1237727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  ABCCompilerDriver driver(triple, sysroot);
1247727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  return driver.build(input_fd, output_fd);;
1257727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao}
1267727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1277727153c233679e1f0fb60702c3966b4e590956bShih-wei Liaostatic int ProcessFromFd(const char *input, const char *output,
1287727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao                         const char *triple, const char *sysroot) {
1297727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  int output_fd, input_fd;
1307727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1317727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (!GetIntArg(output, output_fd)) {
1327727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    ALOGE("Bad output fd '%s'", output);
1337727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    return EXIT_FAILURE;
1347727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
1357727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1367727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (!GetIntArg(input, input_fd)) {
1377727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    ALOGE("Bad input fd '%s'", input);
1387727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    return EXIT_FAILURE;
1397727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
1407727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1417727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (!Build(input_fd, output_fd, triple, sysroot)) {
1427727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    return EXIT_FAILURE;
1437727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
1447727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1457727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  return EXIT_SUCCESS;
1467727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao}
1477727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1487727153c233679e1f0fb60702c3966b4e590956bShih-wei Liaostatic int ProcessFromFile(const char *input, const char *output,
1497727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao                           const char *triple, const char *sysroot) {
1507727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  // TODO: Support multiple input files.
1517727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  int output_fd = -1, input_fd = -1;
1527727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1537727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  // Open the output file.
1547727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  output_fd = ::open(output, O_RDWR | O_CREAT | O_TRUNC, 0755);
1557727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1567727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (output_fd < 0) {
1577727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    ALOGE("Failed to open %s for output! (%s)", output, strerror(errno));
1587727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    return EXIT_FAILURE;
1597727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
1607727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1617727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  // Open the input file.
1627727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  input_fd = ::open(input, O_RDONLY);
1637727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1647727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (input_fd < 0) {
1657727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    ALOGE("Failed to open %s for input! (%s)", input, strerror(errno));
1667727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    ::close(output_fd);
1677727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    return EXIT_FAILURE;
1687727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
1697727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1707727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (!Build(input_fd, output_fd, triple, sysroot)) {
1717727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    ::close(output_fd);
1727727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    ::close(input_fd);
1737727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    return EXIT_FAILURE;
1747727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
1757727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1767727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  ::close(output_fd);
1777727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  ::close(input_fd);
1787727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1797727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  return EXIT_SUCCESS;
1807727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao}
1817727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1827727153c233679e1f0fb60702c3966b4e590956bShih-wei Liaoint main(int argc, char **argv) {
1837727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  Mode mode = kUnknownMode;
1847727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  const char *input, *output, *triple = NULL, *sysroot = NULL;
1857727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1867727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  set_process_name("abcc");
1877727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1887727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  setvbuf(stdout, NULL, _IONBF, 0);
1897727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1907727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  init::Initialize();
1917727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
1927727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  if (ParseArguments(argc, argv, mode, input, output, triple, sysroot)) {
1937727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    switch (mode) {
1947727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao      case kFdMode: {
1957727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao        return ProcessFromFd(input, output, triple, sysroot);
1967727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao      }
1977727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao      case kFileMode: {
1987727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao        return ProcessFromFile(input, output, triple, sysroot);
1997727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao      }
2007727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao      default: {
2017727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao        // Unknown mode encountered. Fall-through to print usage and return
2027727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao        // error.
2037727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao        break;
2047727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao      }
2057727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    }
2067727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao    // fall-through
2077727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  }
2087727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
2097727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  usage();
2107727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao
2117727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao  return EXIT_FAILURE;
2127727153c233679e1f0fb60702c3966b4e590956bShih-wei Liao}
213