123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857 |
- /* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <sys/stat.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <unistd.h>
- #include <dirent.h>
- #include <errno.h>
- #include <assert.h>
- #ifdef __EMX__
- # define SHELL_CMD "sh"
- # define GEN_EXPORTS "emxexp"
- # define DEF2IMPLIB_CMD "emximp"
- # define SHARE_SW "-Zdll -Zmtd"
- # define USE_OMF 1
- # define TRUNCATE_DLL_NAME
- # define DYNAMIC_LIB_EXT "dll"
- # define EXE_EXT ".exe"
- # if USE_OMF
- /* OMF is the native format under OS/2 */
- # define STATIC_LIB_EXT "lib"
- # define OBJECT_EXT "obj"
- # define LIBRARIAN "emxomfar"
- # define LIBRARIAN_OPTS "cr"
- # else
- /* but the alternative, a.out, can fork() which is sometimes necessary */
- # define STATIC_LIB_EXT "a"
- # define OBJECT_EXT "o"
- # define LIBRARIAN "ar"
- # define LIBRARIAN_OPTS "cr"
- # endif
- #endif
- #if defined(__APPLE__)
- # define SHELL_CMD "/bin/sh"
- # define DYNAMIC_LIB_EXT "dylib"
- # define MODULE_LIB_EXT "so"
- # define STATIC_LIB_EXT "a"
- # define OBJECT_EXT "o"
- # define LIBRARIAN "ar"
- # define LIBRARIAN_OPTS "cr"
- /* man libtool(1) documents ranlib option of -c. */
- # define RANLIB "ranlib"
- # define PIC_FLAG "-fPIC -fno-common"
- # define SHARED_OPTS "-dynamiclib"
- # define MODULE_OPTS "-bundle"
- # define DYNAMIC_LINK_OPTS "-flat_namespace -undefined suppress"
- # define dynamic_link_version_func darwin_dynamic_link_function
- # define DYNAMIC_INSTALL_NAME "-install_name"
- # define DYNAMIC_LINK_NO_INSTALL "-dylib_file"
- # define HAS_REALPATH
- /*-install_name /Users/jerenk/apache-2.0-cvs/lib/libapr.0.dylib -compatibility_version 1 -current_version 1.0 */
- # define LD_LIBRARY_PATH "DYLD_LIBRARY_PATH"
- #endif
- #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
- # define SHELL_CMD "/bin/sh"
- # define DYNAMIC_LIB_EXT "so"
- # define MODULE_LIB_EXT "so"
- # define STATIC_LIB_EXT "a"
- # define OBJECT_EXT "o"
- # define LIBRARIAN "ar"
- # define LIBRARIAN_OPTS "cr"
- # define RANLIB "ranlib"
- # define PIC_FLAG "-fPIC"
- # define RPATH "-rpath"
- # define SHARED_OPTS "-shared"
- # define MODULE_OPTS "-shared"
- # define DYNAMIC_LINK_OPTS "-export-dynamic"
- # define LINKER_FLAG_PREFIX "-Wl,"
- # define ADD_MINUS_L
- # define LD_RUN_PATH "LD_RUN_PATH"
- # define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
- #endif
- #if defined(sun)
- # define SHELL_CMD "/bin/sh"
- # define DYNAMIC_LIB_EXT "so"
- # define MODULE_LIB_EXT "so"
- # define STATIC_LIB_EXT "a"
- # define OBJECT_EXT "o"
- # define LIBRARIAN "ar"
- # define LIBRARIAN_OPTS "cr"
- # define RANLIB "ranlib"
- # define PIC_FLAG "-KPIC"
- # define RPATH "-R"
- # define SHARED_OPTS "-G"
- # define MODULE_OPTS "-G"
- # define DYNAMIC_LINK_OPTS ""
- # define LINKER_FLAG_NO_EQUALS
- # define ADD_MINUS_L
- # define HAS_REALPATH
- # define LD_RUN_PATH "LD_RUN_PATH"
- # define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
- #endif
- #if defined(_OSD_POSIX)
- # define SHELL_CMD "/usr/bin/sh"
- # define DYNAMIC_LIB_EXT "so"
- # define MODULE_LIB_EXT "so"
- # define STATIC_LIB_EXT "a"
- # define OBJECT_EXT "o"
- # define LIBRARIAN "ar"
- # define LIBRARIAN_OPTS "cr"
- # define SHARED_OPTS "-G"
- # define MODULE_OPTS "-G"
- # define LINKER_FLAG_PREFIX "-Wl,"
- # define NEED_SNPRINTF
- #endif
- #if defined(sinix) && defined(mips) && defined(__SNI_TARG_UNIX)
- # define SHELL_CMD "/usr/bin/sh"
- # define DYNAMIC_LIB_EXT "so"
- # define MODULE_LIB_EXT "so"
- # define STATIC_LIB_EXT "a"
- # define OBJECT_EXT "o"
- # define LIBRARIAN "ar"
- # define LIBRARIAN_OPTS "cr"
- # define RPATH "-Brpath"
- # define SHARED_OPTS "-G"
- # define MODULE_OPTS "-G"
- # define DYNAMIC_LINK_OPTS "-Wl,-Blargedynsym"
- # define LINKER_FLAG_PREFIX "-Wl,"
- # define NEED_SNPRINTF
- # define LD_RUN_PATH "LD_RUN_PATH"
- # define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
- #endif
- #ifndef SHELL_CMD
- #error Unsupported platform: Please add defines for SHELL_CMD etc. for your platform.
- #endif
- #ifdef NEED_SNPRINTF
- #include <stdarg.h>
- #endif
- #ifdef __EMX__
- #include <process.h>
- #endif
- #ifndef PATH_MAX
- #define PATH_MAX 1024
- #endif
- /* We want to say we are libtool 1.4 for shlibtool compatibility. */
- #define VERSION "1.4"
- enum tool_mode_t {
- mUnknown,
- mCompile,
- mLink,
- mInstall,
- };
- enum output_t {
- otGeneral,
- otObject,
- otProgram,
- otLibrary,
- otStaticLibraryOnly,
- otDynamicLibraryOnly,
- otModule,
- };
- enum pic_mode_e {
- pic_UNKNOWN,
- pic_PREFER,
- pic_AVOID,
- };
- enum lib_type {
- type_UNKNOWN,
- type_DYNAMIC_LIB,
- type_STATIC_LIB,
- type_MODULE_LIB,
- type_OBJECT,
- };
- typedef struct {
- const char **vals;
- int num;
- } count_chars;
- typedef struct {
- const char *normal;
- const char *install;
- } library_name;
- typedef struct {
- count_chars *normal;
- count_chars *install;
- count_chars *dependencies;
- } library_opts;
- typedef struct {
- int silent;
- int shared;
- int export_all;
- int dry_run;
- enum pic_mode_e pic_mode;
- int export_dynamic;
- int no_install;
- } options_t;
- typedef struct {
- enum tool_mode_t mode;
- enum output_t output;
- options_t options;
- char *output_name;
- char *fake_output_name;
- char *basename;
- const char *install_path;
- const char *compiler;
- const char *program;
- count_chars *program_opts;
- count_chars *arglist;
- count_chars *tmp_dirs;
- count_chars *obj_files;
- count_chars *dep_rpaths;
- count_chars *rpaths;
- library_name static_name;
- library_name shared_name;
- library_name module_name;
- library_opts static_opts;
- library_opts shared_opts;
- const char *version_info;
- } command_t;
- #ifdef RPATH
- void add_rpath(count_chars *cc, const char *path);
- #endif
- #if defined(NEED_SNPRINTF)
- /* Write at most n characters to the buffer in str, return the
- * number of chars written or -1 if the buffer would have been
- * overflowed.
- *
- * This is portable to any POSIX-compliant system has /dev/null
- */
- static FILE *f=NULL;
- static int vsnprintf( char *str, size_t n, const char *fmt, va_list ap )
- {
- int res;
- if (f == NULL)
- f = fopen("/dev/null","w");
- if (f == NULL)
- return -1;
- setvbuf( f, str, _IOFBF, n );
- res = vfprintf( f, fmt, ap );
- if ( res > 0 && res < n ) {
- res = vsprintf( str, fmt, ap );
- }
- return res;
- }
- static int snprintf( char *str, size_t n, const char *fmt, ... )
- {
- va_list ap;
- int res;
-
- va_start( ap, fmt );
- res = vsnprintf( str, n, fmt, ap );
- va_end( ap );
- return res;
- }
- #endif
- void init_count_chars(count_chars *cc)
- {
- cc->vals = (const char**)malloc(PATH_MAX);
- cc->num = 0;
- }
- void clear_count_chars(count_chars *cc)
- {
- int i;
- for (i = 0; i < cc->num; i++) {
- cc->vals[i] = 0;
- }
- cc->num = 0;
- }
- void push_count_chars(count_chars *cc, const char *newval)
- {
- cc->vals[cc->num++] = newval;
- }
- void insert_count_chars(count_chars *cc, const char *newval, int position)
- {
- int i;
- for (i = cc->num; i > position; i--) {
- cc->vals[i] = cc->vals[i-1];
- }
- cc->vals[position] = newval;
- cc->num++;
- }
- void append_count_chars(count_chars *cc, count_chars *cctoadd)
- {
- int i;
- for (i = 0; i < cctoadd->num; i++) {
- if (cctoadd->vals[i]) {
- push_count_chars(cc, cctoadd->vals[i]);
- }
- }
- }
- const char *flatten_count_chars(count_chars *cc)
- {
- int i, size;
- char *newval;
- size = 0;
- for (i = 0; i < cc->num; i++) {
- if (cc->vals[i]) {
- size += strlen(cc->vals[i]) + 1;
- }
- }
- newval = (char*)malloc(size + 1);
- newval[0] = 0;
- for (i = 0; i < cc->num; i++) {
- if (cc->vals[i]) {
- strcat(newval, cc->vals[i]);
- strcat(newval, " ");
- }
- }
- return newval;
- }
- char *shell_esc(const char *str)
- {
- int in_quote = 0;
- char *cmd;
- unsigned char *d;
- const unsigned char *s;
- cmd = (char *)malloc(2 * strlen(str) + 1);
- d = (unsigned char *)cmd;
- s = (const unsigned char *)str;
- for (; *s; ++s) {
- if (*s == '"') {
- *d++ = '\\';
- in_quote++;
- }
- else if (*s == '\\' || (*s == ' ' && (in_quote % 2))) {
- *d++ = '\\';
- }
- *d++ = *s;
- }
- *d = '\0';
- return cmd;
- }
- int external_spawn(command_t *cmd, const char *file, const char **argv)
- {
- if (!cmd->options.silent) {
- const char **argument = argv;
- printf("Executing: ");
- while (*argument) {
- printf("%s ", *argument);
- argument++;
- }
- puts("");
- }
- if (cmd->options.dry_run) {
- return 0;
- }
- #ifdef __EMX__
- return spawnvp(P_WAIT, file, argv);
- #else
- {
- pid_t pid;
- pid = fork();
- if (pid == 0) {
- return execvp(argv[0], (char**)argv);
- }
- else {
- int statuscode;
- waitpid(pid, &statuscode, 0);
- if (WIFEXITED(statuscode)) {
- return WEXITSTATUS(statuscode);
- }
- return 0;
- }
- }
- #endif
- }
- int run_command(command_t *cmd_data, count_chars *cc)
- {
- char *command;
- const char *spawn_args[4];
- count_chars tmpcc;
- init_count_chars(&tmpcc);
- if (cmd_data->program) {
- push_count_chars(&tmpcc, cmd_data->program);
- }
- append_count_chars(&tmpcc, cmd_data->program_opts);
- append_count_chars(&tmpcc, cc);
- command = shell_esc(flatten_count_chars(&tmpcc));
- spawn_args[0] = SHELL_CMD;
- spawn_args[1] = "-c";
- spawn_args[2] = command;
- spawn_args[3] = NULL;
- return external_spawn(cmd_data, spawn_args[0], (const char**)spawn_args);
- }
- /*
- * print configuration
- * shlibpath_var is used in configure.
- */
- void print_config()
- {
- #ifdef LD_RUN_PATH
- printf("runpath_var=%s\n", LD_RUN_PATH);
- #endif
- #ifdef LD_LIBRARY_PATH
- printf("shlibpath_var=%s\n", LD_LIBRARY_PATH);
- #endif
- #ifdef SHELL_CMD
- printf("SHELL=\"%s\"\n", SHELL_CMD);
- #endif
- }
- /*
- * Add a directory to the runtime library search path.
- */
- void add_runtimedirlib(char *arg, command_t *cmd_data)
- {
- #ifdef RPATH
- add_rpath(cmd_data->shared_opts.dependencies, arg);
- #else
- #endif
- }
- int parse_long_opt(char *arg, command_t *cmd_data)
- {
- char *equal_pos = strchr(arg, '=');
- char var[50];
- char value[500];
- if (equal_pos) {
- strncpy(var, arg, equal_pos - arg);
- var[equal_pos - arg] = 0;
- strcpy(value, equal_pos + 1);
- } else {
- strcpy(var, arg);
- }
- if (strcmp(var, "silent") == 0) {
- cmd_data->options.silent = 1;
- } else if (strcmp(var, "mode") == 0) {
- if (strcmp(value, "compile") == 0) {
- cmd_data->mode = mCompile;
- cmd_data->output = otObject;
- }
- if (strcmp(value, "link") == 0) {
- cmd_data->mode = mLink;
- cmd_data->output = otLibrary;
- }
- if (strcmp(value, "install") == 0) {
- cmd_data->mode = mInstall;
- }
- } else if (strcmp(var, "shared") == 0) {
- if (cmd_data->mode == mLink) {
- cmd_data->output = otDynamicLibraryOnly;
- }
- cmd_data->options.shared = 1;
- } else if (strcmp(var, "export-all") == 0) {
- cmd_data->options.export_all = 1;
- } else if (strcmp(var, "dry-run") == 0) {
- printf("Dry-run mode on!\n");
- cmd_data->options.dry_run = 1;
- } else if (strcmp(var, "version") == 0) {
- printf("Version " VERSION "\n");
- } else if (strcmp(var, "help") == 0) {
- printf("Sorry. No help available.\n");
- } else if (strcmp(var, "config") == 0) {
- print_config();
- } else if (strcmp(var, "tag") == 0) {
- if (strcmp(value, "CC") == 0) {
- /* Do nothing. */
- }
- if (strcmp(value, "CXX") == 0) {
- /* Do nothing. */
- }
- } else {
- return 0;
- }
- return 1;
- }
- /* Return 1 if we eat it. */
- int parse_short_opt(char *arg, command_t *cmd_data)
- {
- if (strcmp(arg, "export-dynamic") == 0) {
- cmd_data->options.export_dynamic = 1;
- return 1;
- }
- if (strcmp(arg, "module") == 0) {
- cmd_data->output = otModule;
- return 1;
- }
- if (strcmp(arg, "Zexe") == 0) {
- return 1;
- }
- if (strcmp(arg, "avoid-version") == 0) {
- return 1;
- }
- if (strcmp(arg, "prefer-pic") == 0) {
- cmd_data->options.pic_mode = pic_PREFER;
- return 1;
- }
- if (strcmp(arg, "prefer-non-pic") == 0) {
- cmd_data->options.pic_mode = pic_AVOID;
- return 1;
- }
- if (strcmp(arg, "static") == 0) {
- /* Don't respect it for now. */
- return 1;
- }
- if (cmd_data->mode == mLink) {
- if (strcmp(arg, "no-install") == 0) {
- cmd_data->options.no_install = 1;
- return 1;
- }
- if (arg[0] == 'L' || arg[0] == 'l') {
- /* Hack... */
- arg--;
- push_count_chars(cmd_data->shared_opts.dependencies, arg);
- return 1;
- } else if (arg[0] == 'R' && arg[1]) {
- /* -Rdir Add dir to runtime library search path. */
- add_runtimedirlib(&arg[1], cmd_data);
- return 1;
- }
- }
- return 0;
- }
- char *truncate_dll_name(char *path)
- {
- /* Cut DLL name down to 8 characters after removing any mod_ prefix */
- char *tmppath = strdup(path);
- char *newname = strrchr(tmppath, '/') + 1;
- char *ext = strrchr(tmppath, '.');
- int len;
- if (ext == NULL)
- return tmppath;
- len = ext - newname;
- if (strncmp(newname, "mod_", 4) == 0) {
- strcpy(newname, newname + 4);
- len -= 4;
- }
- if (len > 8) {
- strcpy(newname + 8, strchr(newname, '.'));
- }
- return tmppath;
- }
- long safe_strtol(const char *nptr, const char **endptr, int base)
- {
- long rv;
- errno = 0;
- rv = strtol(nptr, (char**)endptr, 10);
- if (errno == ERANGE) {
- return 0;
- }
- return rv;
- }
- /* version_info is in the form of MAJOR:MINOR:PATCH */
- const char *darwin_dynamic_link_function(const char *version_info)
- {
- char *newarg;
- long major, minor, patch;
- major = 0;
- minor = 0;
- patch = 0;
- if (version_info) {
- major = safe_strtol(version_info, &version_info, 10);
- if (version_info) {
- if (version_info[0] == ':') {
- version_info++;
- }
- minor = safe_strtol(version_info, &version_info, 10);
- if (version_info) {
- if (version_info[0] == ':') {
- version_info++;
- }
- patch = safe_strtol(version_info, &version_info, 10);
- }
- }
- }
- /* Avoid -dylib_compatibility_version must be greater than zero errors. */
- if (major == 0) {
- major = 1;
- }
- newarg = (char*)malloc(100);
- snprintf(newarg, 99,
- "-compatibility_version %ld -current_version %ld.%ld",
- major, major, minor);
- return newarg;
- }
- /* genlib values
- * 0 - static
- * 1 - dynamic
- * 2 - module
- */
- char *gen_library_name(const char *name, int genlib)
- {
- char *newarg, *newext;
- newarg = (char *)malloc(strlen(name) + 10);
- strcpy(newarg, ".libs/");
- if (genlib == 2 && strncmp(name, "lib", 3) == 0) {
- name += 3;
- }
- strcat(newarg, name);
- newext = strrchr(newarg, '.') + 1;
- switch (genlib) {
- case 0:
- strcpy(newext, STATIC_LIB_EXT);
- break;
- case 1:
- strcpy(newext, DYNAMIC_LIB_EXT);
- break;
- case 2:
- strcpy(newext, MODULE_LIB_EXT);
- break;
- }
- return newarg;
- }
- /* genlib values
- * 0 - static
- * 1 - dynamic
- * 2 - module
- */
- char *gen_install_name(const char *name, int genlib)
- {
- struct stat sb;
- char *newname;
- int rv;
- newname = gen_library_name(name, genlib);
- /* Check if it exists. If not, return NULL. */
- rv = stat(newname, &sb);
- if (rv) {
- return NULL;
- }
- return newname;
- }
- char *check_object_exists(command_t *cmd, const char *arg, int arglen)
- {
- char *newarg, *ext;
- int pass, rv;
- newarg = (char *)malloc(arglen + 10);
- memcpy(newarg, arg, arglen);
- newarg[arglen] = 0;
- ext = newarg + arglen;
- pass = 0;
- do {
- struct stat sb;
- switch (pass) {
- case 0:
- strcpy(ext, OBJECT_EXT);
- break;
- /*
- case 1:
- strcpy(ext, NO_PIC_EXT);
- break;
- */
- default:
- break;
- }
- if (!cmd->options.silent) {
- printf("Checking (obj): %s\n", newarg);
- }
- rv = stat(newarg, &sb);
- }
- while (rv != 0 && ++pass < 1);
- if (rv == 0) {
- if (pass == 1) {
- cmd->options.pic_mode = pic_AVOID;
- }
- return newarg;
- }
- return NULL;
- }
- /* libdircheck values:
- * 0 - no .libs suffix
- * 1 - .libs suffix
- */
- char *check_library_exists(command_t *cmd, const char *arg, int pathlen,
- int libdircheck, enum lib_type *libtype)
- {
- char *newarg, *ext;
- int pass, rv, newpathlen;
- newarg = (char *)malloc(strlen(arg) + 10);
- strcpy(newarg, arg);
- newarg[pathlen] = 0;
- newpathlen = pathlen;
- if (libdircheck) {
- strcat(newarg, ".libs/");
- newpathlen += sizeof(".libs/") - 1;
- }
- strcpy(newarg+newpathlen, arg+pathlen);
- ext = strrchr(newarg, '.') + 1;
- pass = 0;
- do {
- struct stat sb;
- switch (pass) {
- case 0:
- if (cmd->options.pic_mode != pic_AVOID || cmd->options.shared) {
- strcpy(ext, DYNAMIC_LIB_EXT);
- *libtype = type_DYNAMIC_LIB;
- break;
- }
- pass = 1;
- case 1:
- strcpy(ext, STATIC_LIB_EXT);
- *libtype = type_STATIC_LIB;
- break;
- case 2:
- strcpy(ext, MODULE_LIB_EXT);
- *libtype = type_MODULE_LIB;
- break;
- case 3:
- strcpy(ext, OBJECT_EXT);
- *libtype = type_OBJECT;
- break;
- default:
- *libtype = type_UNKNOWN;
- break;
- }
- if (!cmd->options.silent) {
- printf("Checking (lib): %s\n", newarg);
- }
- rv = stat(newarg, &sb);
- }
- while (rv != 0 && ++pass < 4);
- if (rv == 0) {
- return newarg;
- }
- return NULL;
- }
- char * load_install_path(const char *arg)
- {
- FILE *f;
- char *path;
- path = malloc(PATH_MAX);
- f = fopen(arg,"r");
- if (f == NULL) {
- return NULL;
- }
- fgets(path, PATH_MAX, f);
- fclose(f);
- if (path[strlen(path)-1] == '\n') {
- path[strlen(path)-1] = '\0';
- }
- /* Check that we have an absolute path.
- * Otherwise the file could be a GNU libtool file.
- */
- if (path[0] != '/') {
- return NULL;
- }
- return path;
- }
- char * load_noinstall_path(const char *arg, int pathlen)
- {
- char *newarg, *expanded_path;
- int newpathlen;
- newarg = (char *)malloc(strlen(arg) + 10);
- strcpy(newarg, arg);
- newarg[pathlen] = 0;
- newpathlen = pathlen;
- strcat(newarg, ".libs");
- newpathlen += sizeof(".libs") - 1;
- newarg[newpathlen] = 0;
- #ifdef HAS_REALPATH
- expanded_path = malloc(PATH_MAX);
- expanded_path = realpath(newarg, expanded_path);
- /* Uh, oh. There was an error. Fall back on our first guess. */
- if (!expanded_path) {
- expanded_path = newarg;
- }
- #else
- /* We might get ../ or something goofy. Oh, well. */
- expanded_path = newarg;
- #endif
- return expanded_path;
- }
- /* Read the final install location and add it to runtime library search path. */
- #ifdef RPATH
- void add_rpath(count_chars *cc, const char *path)
- {
- int size = 0;
- char *tmp;
- #ifdef LINKER_FLAG_PREFIX
- size = strlen(LINKER_FLAG_PREFIX);
- #endif
- size = size + strlen(path) + strlen(RPATH) + 2;
- tmp = malloc(size);
- if (tmp == NULL) {
- return;
- }
- #ifdef LINKER_FLAG_PREFIX
- strcpy(tmp, LINKER_FLAG_PREFIX);
- strcat(tmp, RPATH);
- #else
- strcpy(tmp, RPATH);
- #endif
- #ifndef LINKER_FLAG_NO_EQUALS
- strcat(tmp, "=");
- #endif
- strcat(tmp, path);
- push_count_chars(cc, tmp);
- }
- void add_rpath_file(count_chars *cc, const char *arg)
- {
- const char *path;
- path = load_install_path(arg);
- if (path) {
- add_rpath(cc, path);
- }
- }
- void add_rpath_noinstall(count_chars *cc, const char *arg, int pathlen)
- {
- const char *path;
- path = load_noinstall_path(arg, pathlen);
- if (path) {
- add_rpath(cc, path);
- }
- }
- #endif
- #ifdef DYNAMIC_LINK_NO_INSTALL
- void add_dylink_noinstall(count_chars *cc, const char *arg, int pathlen,
- int extlen)
- {
- const char *install_path, *current_path, *name;
- char *exp_argument;
- int i_p_len, c_p_len, name_len, dyext_len, cur_len;
- install_path = load_install_path(arg);
- current_path = load_noinstall_path(arg, pathlen);
- if (!install_path || !current_path) {
- return;
- }
- push_count_chars(cc, DYNAMIC_LINK_NO_INSTALL);
- i_p_len = strlen(install_path);
- c_p_len = strlen(current_path);
- name = arg+pathlen;
- name_len = extlen-pathlen;
- dyext_len = sizeof(DYNAMIC_LIB_EXT) - 1;
- /* No, we need to replace the extension. */
- exp_argument = (char *)malloc(i_p_len + c_p_len + (name_len*2) +
- (dyext_len*2) + 2);
- cur_len = 0;
- strcpy(exp_argument, install_path);
- cur_len += i_p_len;
- exp_argument[cur_len++] = '/';
- strncpy(exp_argument+cur_len, name, extlen-pathlen);
- cur_len += name_len;
- strcpy(exp_argument+cur_len, DYNAMIC_LIB_EXT);
- cur_len += dyext_len;
- exp_argument[cur_len++] = ':';
- strcpy(exp_argument+cur_len, current_path);
- cur_len += c_p_len;
- exp_argument[cur_len++] = '/';
- strncpy(exp_argument+cur_len, name, extlen-pathlen);
- cur_len += name_len;
- strcpy(exp_argument+cur_len, DYNAMIC_LIB_EXT);
- cur_len += dyext_len;
- push_count_chars(cc, exp_argument);
- }
- #endif
- /* use -L -llibname to allow to use installed libraries */
- void add_minus_l(count_chars *cc, const char *arg)
- {
- char *newarg;
- char *name = strrchr(arg, '/');
- char *file = strrchr(arg, '.');
- char *lib = strstr(name, "lib");
- if (name !=NULL && file != NULL && lib == name+1) {
- *name = '\0';
- *file = '\0';
- file = name;
- file = file+4;
- push_count_chars(cc, "-L");
- push_count_chars(cc, arg);
- /* we need one argument like -lapr-1 */
- newarg = malloc(strlen(file) + 3);
- strcpy(newarg, "-l");
- strcat(newarg, file);
- push_count_chars(cc, newarg);
- } else {
- push_count_chars(cc, arg);
- }
- }
- void add_linker_flag_prefix(count_chars *cc, const char *arg)
- {
- #ifndef LINKER_FLAG_PREFIX
- push_count_chars(cc, arg);
- #else
- char *newarg;
- newarg = (char*)malloc(strlen(arg) + sizeof(LINKER_FLAG_PREFIX) + 1);
- strcpy(newarg, LINKER_FLAG_PREFIX);
- strcat(newarg, arg);
- push_count_chars(cc, newarg);
- #endif
- }
- int parse_input_file_name(char *arg, command_t *cmd_data)
- {
- char *ext = strrchr(arg, '.');
- char *name = strrchr(arg, '/');
- int pathlen;
- enum lib_type libtype;
- char *newarg;
- if (!ext) {
- return 0;
- }
- ext++;
- if (name == NULL) {
- name = strrchr(arg, '\\');
- if (name == NULL) {
- name = arg;
- } else {
- name++;
- }
- } else {
- name++;
- }
- pathlen = name - arg;
- if (strcmp(ext, "lo") == 0) {
- newarg = check_object_exists(cmd_data, arg, ext - arg);
- if (!newarg) {
- printf("Can not find suitable object file for %s\n", arg);
- exit(1);
- }
- if (cmd_data->mode != mLink) {
- push_count_chars(cmd_data->arglist, newarg);
- }
- else {
- push_count_chars(cmd_data->obj_files, newarg);
- }
- return 1;
- }
- if (strcmp(ext, "la") == 0) {
- switch (cmd_data->mode) {
- case mLink:
- /* Try the .libs dir first! */
- newarg = check_library_exists(cmd_data, arg, pathlen, 1, &libtype);
- if (!newarg) {
- /* Try the normal dir next. */
- newarg = check_library_exists(cmd_data, arg, pathlen, 0, &libtype);
- if (!newarg) {
- printf("Can not find suitable library for %s\n", arg);
- exit(1);
- }
- }
- /* It is not ok to just add the file: a library may added with:
- 1 - -L path library_name. (For *.so in Linux).
- 2 - library_name.
- */
- #ifdef ADD_MINUS_L
- if (libtype == type_DYNAMIC_LIB) {
- add_minus_l(cmd_data->shared_opts.dependencies, newarg);
- } else {
- push_count_chars(cmd_data->shared_opts.dependencies, newarg);
- }
- #else
- push_count_chars(cmd_data->shared_opts.dependencies, newarg);
- #endif
- if (libtype == type_DYNAMIC_LIB) {
- if (cmd_data->options.no_install) {
- #ifdef RPATH
- add_rpath_noinstall(cmd_data->shared_opts.dependencies,
- arg, pathlen);
- #endif
- #ifdef DYNAMIC_LINK_NO_INSTALL
- /*
- * This doesn't work as Darwin's linker has no way to
- * override at link-time the search paths for a
- * non-installed library.
- */
- /*
- add_dylink_noinstall(cmd_data->shared_opts.dependencies,
- arg, pathlen, ext - arg);
- */
- #endif
- }
- else {
- #ifdef RPATH
- add_rpath_file(cmd_data->shared_opts.dependencies, arg);
- #endif
- }
- }
- break;
- case mInstall:
- /* If we've already recorded a library to install, we're most
- * likely getting the .la file that we want to install as.
- * The problem is that we need to add it as the directory,
- * not the .la file itself. Otherwise, we'll do odd things.
- */
- if (cmd_data->output == otLibrary) {
- arg[pathlen] = '\0';
- push_count_chars(cmd_data->arglist, arg);
- }
- else {
- cmd_data->output = otLibrary;
- cmd_data->output_name = arg;
- cmd_data->static_name.install = gen_install_name(arg, 0);
- cmd_data->shared_name.install = gen_install_name(arg, 1);
- cmd_data->module_name.install = gen_install_name(arg, 2);
- }
- break;
- default:
- break;
- }
- return 1;
- }
- if (strcmp(ext, "c") == 0) {
- /* If we don't already have an idea what our output name will be. */
- if (cmd_data->basename == NULL) {
- cmd_data->basename = (char *)malloc(strlen(arg) + 4);
- strcpy(cmd_data->basename, arg);
- strcpy(strrchr(cmd_data->basename, '.') + 1, "lo");
- cmd_data->fake_output_name = strrchr(cmd_data->basename, '/');
- if (cmd_data->fake_output_name) {
- cmd_data->fake_output_name++;
- }
- else {
- cmd_data->fake_output_name = cmd_data->basename;
- }
- }
- }
- return 0;
- }
- int parse_output_file_name(char *arg, command_t *cmd_data)
- {
- char *name = strrchr(arg, '/');
- char *ext = strrchr(arg, '.');
- char *newarg = NULL;
- int pathlen;
- cmd_data->fake_output_name = arg;
- if (name) {
- name++;
- }
- else {
- name = strrchr(arg, '\\');
- if (name == NULL) {
- name = arg;
- }
- else {
- name++;
- }
- }
- if (!ext) {
- cmd_data->basename = arg;
- cmd_data->output = otProgram;
- #if defined(_OSD_POSIX)
- cmd_data->options.pic_mode = pic_AVOID;
- #endif
- newarg = (char *)malloc(strlen(arg) + 5);
- strcpy(newarg, arg);
- #ifdef EXE_EXT
- strcat(newarg, EXE_EXT);
- #endif
- cmd_data->output_name = newarg;
- return 1;
- }
- ext++;
- pathlen = name - arg;
- if (strcmp(ext, "la") == 0) {
- assert(cmd_data->mode == mLink);
- cmd_data->basename = arg;
- cmd_data->static_name.normal = gen_library_name(arg, 0);
- cmd_data->shared_name.normal = gen_library_name(arg, 1);
- cmd_data->module_name.normal = gen_library_name(arg, 2);
- cmd_data->static_name.install = gen_install_name(arg, 0);
- cmd_data->shared_name.install = gen_install_name(arg, 1);
- cmd_data->module_name.install = gen_install_name(arg, 2);
- #ifdef TRUNCATE_DLL_NAME
- if (shared) {
- arg = truncate_dll_name(arg);
- }
- #endif
- cmd_data->output_name = arg;
- return 1;
- }
- if (strcmp(ext, "lo") == 0) {
- cmd_data->basename = arg;
- cmd_data->output = otObject;
- newarg = (char *)malloc(strlen(arg) + 2);
- strcpy(newarg, arg);
- ext = strrchr(newarg, '.') + 1;
- strcpy(ext, OBJECT_EXT);
- cmd_data->output_name = newarg;
- return 1;
- }
- return 0;
- }
- /* returns just a file's name without path or extension */
- char *nameof(char *fullpath)
- {
- char buffer[1024];
- char *ext;
- char *name = strrchr(fullpath, '/');
- if (name == NULL) {
- name = strrchr(fullpath, '\\');
- }
- if (name == NULL) {
- name = fullpath;
- } else {
- name++;
- }
- strcpy(buffer, name);
- ext = strrchr(buffer, '.');
- if (ext) {
- *ext = 0;
- return strdup(buffer);
- }
- return name;
- }
- void parse_args(int argc, char *argv[], command_t *cmd_data)
- {
- int a;
- char *arg;
- int argused;
- for (a = 1; a < argc; a++) {
- arg = argv[a];
- argused = 1;
- if (arg[0] == '-') {
- if (arg[1] == '-') {
- argused = parse_long_opt(arg + 2, cmd_data);
- }
- else {
- argused = parse_short_opt(arg + 1, cmd_data);
- }
- /* We haven't done anything with it yet, try some of the
- * more complicated short opts... */
- if (argused == 0 && a + 1 < argc) {
- if (arg[1] == 'o' && !arg[2]) {
- arg = argv[++a];
- argused = parse_output_file_name(arg, cmd_data);
- } else if (strcmp(arg+1, "MT") == 0) {
- if (!cmd_data->options.silent) {
- printf("Adding: %s", arg);
- }
- push_count_chars(cmd_data->arglist, arg);
- arg = argv[++a];
- if (!cmd_data->options.silent) {
- printf(" %s\n", arg);
- }
- push_count_chars(cmd_data->arglist, arg);
- argused = 1;
- } else if (strcmp(arg+1, "rpath") == 0) {
- /* Aha, we should try to link both! */
- cmd_data->install_path = argv[++a];
- argused = 1;
- } else if (strcmp(arg+1, "version-info") == 0) {
- /* Store for later deciphering */
- cmd_data->version_info = argv[++a];
- argused = 1;
- } else if (strcmp(arg+1, "export-symbols-regex") == 0) {
- /* Skip the argument. */
- ++a;
- argused = 1;
- } else if (arg[1] == 'R' && !arg[2]) {
- /* -R dir Add dir to runtime library search path. */
- add_runtimedirlib(argv[++a], cmd_data);
- argused = 1;
- }
- }
- } else {
- argused = parse_input_file_name(arg, cmd_data);
- }
- if (!argused) {
- if (!cmd_data->options.silent) {
- printf("Adding: %s\n", arg);
- }
- push_count_chars(cmd_data->arglist, arg);
- }
- }
- }
- int explode_static_lib(const char *lib, command_t *cmd_data)
- {
- char tmpdir[1024];
- char savewd[1024];
- char cmd[1024];
- const char *name;
- DIR *dir;
- struct dirent *entry;
- /* Bah! */
- if (cmd_data->options.dry_run) {
- return 0;
- }
- strcpy(tmpdir, lib);
- strcat(tmpdir, ".exploded");
- mkdir(tmpdir, 0);
- push_count_chars(cmd_data->tmp_dirs, strdup(tmpdir));
- getcwd(savewd, sizeof(savewd));
- if (chdir(tmpdir) != 0)
- return 1;
- strcpy(cmd, LIBRARIAN " x ");
- name = strrchr(lib, '/');
- if (name) {
- name++;
- } else {
- name = lib;
- }
- strcat(cmd, "../");
- strcat(cmd, name);
- system(cmd);
- chdir(savewd);
- dir = opendir(tmpdir);
- while ((entry = readdir(dir)) != NULL) {
- if (entry->d_name[0] != '.') {
- strcpy(cmd, tmpdir);
- strcat(cmd, "/");
- strcat(cmd, entry->d_name);
- push_count_chars(cmd_data->arglist, strdup(cmd));
- }
- }
- closedir(dir);
- return 0;
- }
- #ifdef GEN_EXPORTS
- void generate_def_file(command_t *cmd_data)
- {
- char def_file[1024];
- char implib_file[1024];
- char *ext;
- FILE *hDef;
- char *export_args[1024];
- int num_export_args = 0;
- char *cmd;
- int cmd_size = 0;
- int a;
- if (cmd_data->output_name) {
- strcpy(def_file, cmd_data->output_name);
- strcat(def_file, ".def");
- hDef = fopen(def_file, "w");
- if (hDef != NULL) {
- fprintf(hDef, "LIBRARY '%s' INITINSTANCE\n", nameof(cmd_data->output_name));
- fprintf(hDef, "DATA NONSHARED\n");
- fprintf(hDef, "EXPORTS\n");
- fclose(hDef);
- for (a = 0; a < cmd_data->num_obj_files; a++) {
- cmd_size += strlen(cmd_data->obj_files[a]) + 1;
- }
- cmd_size += strlen(GEN_EXPORTS) + strlen(def_file) + 3;
- cmd = (char *)malloc(cmd_size);
- strcpy(cmd, GEN_EXPORTS);
- for (a=0; a < cmd_data->num_obj_files; a++) {
- strcat(cmd, " ");
- strcat(cmd, cmd_data->obj_files[a] );
- }
- strcat(cmd, ">>");
- strcat(cmd, def_file);
- puts(cmd);
- export_args[num_export_args++] = SHELL_CMD;
- export_args[num_export_args++] = "-c";
- export_args[num_export_args++] = cmd;
- export_args[num_export_args++] = NULL;
- external_spawn(cmd_data, export_args[0], (const char**)export_args);
- cmd_data->arglist[cmd_data->num_args++] = strdup(def_file);
- /* Now make an import library for the dll */
- num_export_args = 0;
- export_args[num_export_args++] = DEF2IMPLIB_CMD;
- export_args[num_export_args++] = "-o";
- strcpy(implib_file, ".libs/");
- strcat(implib_file, cmd_data->basename);
- ext = strrchr(implib_file, '.');
- if (ext)
- *ext = 0;
- strcat(implib_file, ".");
- strcat(implib_file, STATIC_LIB_EXT);
- export_args[num_export_args++] = implib_file;
- export_args[num_export_args++] = def_file;
- export_args[num_export_args++] = NULL;
- external_spawn(cmd_data, export_args[0], (const char**)export_args);
- }
- }
- }
- #endif
- const char* expand_path(const char *relpath)
- {
- char foo[PATH_MAX], *newpath;
- getcwd(foo, PATH_MAX-1);
- newpath = (char*)malloc(strlen(foo)+strlen(relpath)+2);
- strcat(newpath, foo);
- strcat(newpath, "/");
- strcat(newpath, relpath);
- return newpath;
- }
- void link_fixup(command_t *c)
- {
- /* If we were passed an -rpath directive, we need to build
- * shared objects too. Otherwise, we should only create static
- * libraries.
- */
- if (!c->install_path && (c->output == otDynamicLibraryOnly ||
- c->output == otModule || c->output == otLibrary)) {
- c->output = otStaticLibraryOnly;
- }
- if (c->output == otDynamicLibraryOnly ||
- c->output == otModule ||
- c->output == otLibrary) {
- push_count_chars(c->shared_opts.normal, "-o");
- if (c->output == otModule) {
- push_count_chars(c->shared_opts.normal, c->module_name.normal);
- }
- else {
- char *tmp;
- push_count_chars(c->shared_opts.normal, c->shared_name.normal);
- #ifdef DYNAMIC_INSTALL_NAME
- push_count_chars(c->shared_opts.normal, DYNAMIC_INSTALL_NAME);
- tmp = (char*)malloc(PATH_MAX);
- strcat(tmp, c->install_path);
- strcat(tmp, strrchr(c->shared_name.normal, '/'));
- push_count_chars(c->shared_opts.normal, tmp);
- #endif
- }
- append_count_chars(c->shared_opts.normal, c->obj_files);
- append_count_chars(c->shared_opts.normal, c->shared_opts.dependencies);
- if (c->options.export_all) {
- #ifdef GEN_EXPORTS
- generate_def_file(c);
- #endif
- }
- }
- if (c->output == otLibrary || c->output == otStaticLibraryOnly) {
- push_count_chars(c->static_opts.normal, "-o");
- push_count_chars(c->static_opts.normal, c->output_name);
- }
- if (c->output == otProgram) {
- if (c->output_name) {
- push_count_chars(c->arglist, "-o");
- push_count_chars(c->arglist, c->output_name);
- append_count_chars(c->arglist, c->obj_files);
- append_count_chars(c->arglist, c->shared_opts.dependencies);
- #ifdef DYNAMIC_LINK_OPTS
- if (c->options.pic_mode != pic_AVOID) {
- push_count_chars(c->arglist, DYNAMIC_LINK_OPTS);
- }
- #endif
- }
- }
- }
- void post_parse_fixup(command_t *cmd_data)
- {
- switch (cmd_data->mode)
- {
- case mCompile:
- #ifdef PIC_FLAG
- if (cmd_data->options.pic_mode != pic_AVOID) {
- push_count_chars(cmd_data->arglist, PIC_FLAG);
- }
- #endif
- if (cmd_data->output_name) {
- push_count_chars(cmd_data->arglist, "-o");
- push_count_chars(cmd_data->arglist, cmd_data->output_name);
- }
- break;
- case mLink:
- link_fixup(cmd_data);
- break;
- case mInstall:
- if (cmd_data->output == otLibrary) {
- link_fixup(cmd_data);
- }
- default:
- break;
- }
- #if USE_OMF
- if (cmd_data->output == otObject ||
- cmd_data->output == otProgram ||
- cmd_data->output == otLibrary ||
- cmd_data->output == otDynamicLibraryOnly) {
- push_count_chars(cmd_data->arglist, "-Zomf");
- }
- #endif
- if (cmd_data->options.shared &&
- (cmd_data->output == otObject ||
- cmd_data->output == otLibrary ||
- cmd_data->output == otDynamicLibraryOnly)) {
- #ifdef SHARE_SW
- push_count_chars(cmd_data->arglist, SHARE_SW);
- #endif
- }
- }
- int run_mode(command_t *cmd_data)
- {
- int rv;
- count_chars *cctemp;
- cctemp = (count_chars*)malloc(sizeof(count_chars));
- init_count_chars(cctemp);
- switch (cmd_data->mode)
- {
- case mCompile:
- rv = run_command(cmd_data, cmd_data->arglist);
- if (rv) {
- return rv;
- }
- break;
- case mInstall:
- /* Well, we'll assume it's a file going to a directory... */
- /* For brain-dead install-sh based scripts, we have to repeat
- * the command N-times. install-sh should die.
- */
- if (!cmd_data->output_name) {
- rv = run_command(cmd_data, cmd_data->arglist);
- if (rv) {
- return rv;
- }
- }
- if (cmd_data->output_name) {
- append_count_chars(cctemp, cmd_data->arglist);
- insert_count_chars(cctemp,
- cmd_data->output_name,
- cctemp->num - 1);
- rv = run_command(cmd_data, cctemp);
- if (rv) {
- return rv;
- }
- clear_count_chars(cctemp);
- }
- if (cmd_data->static_name.install) {
- append_count_chars(cctemp, cmd_data->arglist);
- insert_count_chars(cctemp,
- cmd_data->static_name.install,
- cctemp->num - 1);
- rv = run_command(cmd_data, cctemp);
- if (rv) {
- return rv;
- }
- clear_count_chars(cctemp);
- }
- if (cmd_data->shared_name.install) {
- append_count_chars(cctemp, cmd_data->arglist);
- insert_count_chars(cctemp,
- cmd_data->shared_name.install,
- cctemp->num - 1);
- rv = run_command(cmd_data, cctemp);
- if (rv) {
- return rv;
- }
- clear_count_chars(cctemp);
- }
- if (cmd_data->module_name.install) {
- append_count_chars(cctemp, cmd_data->arglist);
- insert_count_chars(cctemp,
- cmd_data->module_name.install,
- cctemp->num - 1);
- rv = run_command(cmd_data, cctemp);
- if (rv) {
- return rv;
- }
- clear_count_chars(cctemp);
- }
- break;
- case mLink:
- if (!cmd_data->options.dry_run) {
- /* Check first to see if the dir already exists! */
- mode_t old_umask;
- old_umask = umask(0);
- umask(old_umask);
- mkdir(".libs", ~old_umask);
- }
- if (cmd_data->output == otStaticLibraryOnly ||
- cmd_data->output == otLibrary) {
- #ifdef RANLIB
- const char *lib_args[3];
- #endif
- /* Removes compiler! */
- cmd_data->program = LIBRARIAN;
- push_count_chars(cmd_data->program_opts, LIBRARIAN_OPTS);
- push_count_chars(cmd_data->program_opts,
- cmd_data->static_name.normal);
- rv = run_command(cmd_data, cmd_data->obj_files);
- if (rv) {
- return rv;
- }
- #ifdef RANLIB
- lib_args[0] = RANLIB;
- lib_args[1] = cmd_data->static_name.normal;
- lib_args[2] = NULL;
- external_spawn(cmd_data, RANLIB, lib_args);
- #endif
- }
- if (cmd_data->output == otDynamicLibraryOnly ||
- cmd_data->output == otModule ||
- cmd_data->output == otLibrary) {
- cmd_data->program = NULL;
- clear_count_chars(cmd_data->program_opts);
- append_count_chars(cmd_data->program_opts, cmd_data->arglist);
- if (cmd_data->output != otModule) {
- #ifdef SHARED_OPTS
- push_count_chars(cmd_data->program_opts, SHARED_OPTS);
- #endif
- #ifdef dynamic_link_version_func
- push_count_chars(cmd_data->program_opts,
- dynamic_link_version_func(cmd_data->version_info));
- #endif
- }
- if (cmd_data->output == otModule) {
- #ifdef MODULE_OPTS
- push_count_chars(cmd_data->program_opts, MODULE_OPTS);
- #endif
- }
- #ifdef DYNAMIC_LINK_OPTS
- if (cmd_data->options.pic_mode != pic_AVOID) {
- push_count_chars(cmd_data->program_opts,
- DYNAMIC_LINK_OPTS);
- }
- #endif
- rv = run_command(cmd_data, cmd_data->shared_opts.normal);
- if (rv) {
- return rv;
- }
- }
- if (cmd_data->output == otProgram) {
- rv = run_command(cmd_data, cmd_data->arglist);
- if (rv) {
- return rv;
- }
- }
- break;
- default:
- break;
- }
- return 0;
- }
- void cleanup_tmp_dir(const char *dirname)
- {
- DIR *dir;
- struct dirent *entry;
- char fullname[1024];
- dir = opendir(dirname);
- if (dir == NULL)
- return;
- while ((entry = readdir(dir)) != NULL) {
- if (entry->d_name[0] != '.') {
- strcpy(fullname, dirname);
- strcat(fullname, "/");
- strcat(fullname, entry->d_name);
- remove(fullname);
- }
- }
- rmdir(dirname);
- }
- void cleanup_tmp_dirs(command_t *cmd_data)
- {
- int d;
- for (d = 0; d < cmd_data->tmp_dirs->num; d++) {
- cleanup_tmp_dir(cmd_data->tmp_dirs->vals[d]);
- }
- }
- int ensure_fake_uptodate(command_t *cmd_data)
- {
- /* FIXME: could do the stat/touch here, but nah... */
- const char *touch_args[3];
- if (cmd_data->mode == mInstall) {
- return 0;
- }
- touch_args[0] = "touch";
- touch_args[1] = cmd_data->fake_output_name;
- touch_args[2] = NULL;
- return external_spawn(cmd_data, "touch", touch_args);
- }
- /* Store the install path in the *.la file */
- int add_for_runtime(command_t *cmd_data)
- {
- if (cmd_data->mode == mInstall) {
- return 0;
- }
- if (cmd_data->output == otDynamicLibraryOnly ||
- cmd_data->output == otLibrary) {
- FILE *f=fopen(cmd_data->fake_output_name,"w");
- if (f == NULL) {
- return -1;
- }
- fprintf(f,"%s\n", cmd_data->install_path);
- fclose(f);
- return(0);
- } else {
- return(ensure_fake_uptodate(cmd_data));
- }
- }
- int main(int argc, char *argv[])
- {
- int rc;
- command_t cmd_data;
- memset(&cmd_data, 0, sizeof(cmd_data));
- cmd_data.options.pic_mode = pic_UNKNOWN;
- cmd_data.program_opts = (count_chars*)malloc(sizeof(count_chars));
- init_count_chars(cmd_data.program_opts);
- cmd_data.arglist = (count_chars*)malloc(sizeof(count_chars));
- init_count_chars(cmd_data.arglist);
- cmd_data.tmp_dirs = (count_chars*)malloc(sizeof(count_chars));
- init_count_chars(cmd_data.tmp_dirs);
- cmd_data.obj_files = (count_chars*)malloc(sizeof(count_chars));
- init_count_chars(cmd_data.obj_files);
- cmd_data.dep_rpaths = (count_chars*)malloc(sizeof(count_chars));
- init_count_chars(cmd_data.dep_rpaths);
- cmd_data.rpaths = (count_chars*)malloc(sizeof(count_chars));
- init_count_chars(cmd_data.rpaths);
- cmd_data.static_opts.normal = (count_chars*)malloc(sizeof(count_chars));
- init_count_chars(cmd_data.static_opts.normal);
- cmd_data.shared_opts.normal = (count_chars*)malloc(sizeof(count_chars));
- init_count_chars(cmd_data.shared_opts.normal);
- cmd_data.shared_opts.dependencies = (count_chars*)malloc(sizeof(count_chars));
- init_count_chars(cmd_data.shared_opts.dependencies);
- cmd_data.mode = mUnknown;
- cmd_data.output = otGeneral;
- parse_args(argc, argv, &cmd_data);
- post_parse_fixup(&cmd_data);
- if (cmd_data.mode == mUnknown) {
- exit(0);
- }
- rc = run_mode(&cmd_data);
- if (!rc) {
- add_for_runtime(&cmd_data);
- }
- cleanup_tmp_dirs(&cmd_data);
- return rc;
- }
|