1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include <sys/types.h>
23 #if !defined(__MINGW32__)
24 # include <sys/wait.h>
33 # define SHELL_CMD "sh"
34 # define GEN_EXPORTS "emxexp"
35 # define DEF2IMPLIB_CMD "emximp"
36 # define SHARE_SW "-Zdll -Zmtd"
38 # define TRUNCATE_DLL_NAME
39 # define DYNAMIC_LIB_EXT "dll"
40 # define EXE_EX ".exe"
41 /* OMF is the native format under OS/2 */
44 # define STATIC_LIB_EXT "lib"
45 # define OBJECT_EXT "obj"
46 # define LIBRARIAN "emxomfar"
47 # define LIBRARIAN_OPTS "cr"
49 /* but the alternative, a.out, can fork() which is sometimes necessary */
50 # define STATIC_LIB_EXT "a"
51 # define OBJECT_EXT "o"
52 # define LIBRARIAN "ar"
53 # define LIBRARIAN_OPTS "cr"
57 #if defined(__APPLE__)
58 # define SHELL_CMD "/bin/sh"
59 # define DYNAMIC_LIB_EXT "dylib"
60 # define MODULE_LIB_EXT "bundle"
61 # define STATIC_LIB_EXT "a"
62 # define OBJECT_EXT "o"
63 # define LIBRARIAN "ar"
64 # define LIBRARIAN_OPTS "cr"
65 /* man libtool(1) documents ranlib option of -c. */
66 # define RANLIB "ranlib"
67 # define PIC_FLAG "-fPIC -fno-common"
68 # define SHARED_OPTS "-dynamiclib"
69 # define MODULE_OPTS "-bundle -dynamic"
70 # define DYNAMIC_LINK_OPTS "-flat_namespace"
71 # define DYNAMIC_LINK_UNDEFINED "-undefined suppress"
72 # define dynamic_link_version_func darwin_dynamic_link_function
73 # define DYNAMIC_INSTALL_NAME "-install_name"
74 # define DYNAMIC_LINK_NO_INSTALL "-dylib_file"
76 /*-install_name /Users/jerenk/apache-2.0-cvs/lib/libapr.0.dylib -compatibility_version 1 -current_version 1.0 */
77 # define LD_LIBRARY_PATH "DYLD_LIBRARY_PATH"
78 # define LD_LIBRARY_PATH_LOCAL "DYLD_FALLBACK_LIBRARY_PATH"
81 #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
82 # define SHELL_CMD "/bin/sh"
83 # define DYNAMIC_LIB_EXT "so"
84 # define MODULE_LIB_EXT "so"
85 # define STATIC_LIB_EXT "a"
86 # define OBJECT_EXT "o"
87 # define LIBRARIAN "ar"
88 # define LIBRARIAN_OPTS "cr"
89 # define RANLIB "ranlib"
90 # define PIC_FLAG "-fPIC"
91 # define RPATH "-rpath"
92 # define SHARED_OPTS "-shared"
93 # define MODULE_OPTS "-shared"
94 # define DYNAMIC_LINK_OPTS "-export-dynamic"
95 # define LINKER_FLAG_PREFIX "-Wl,"
97 # define LD_RUN_PATH "LD_RUN_PATH"
98 # define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
99 # define LD_LIBRARY_PATH_LOCAL LD_LIBRARY_PATH
103 # define SHELL_CMD "/bin/sh"
104 # define DYNAMIC_LIB_EXT "so"
105 # define MODULE_LIB_EXT "so"
106 # define STATIC_LIB_EXT "a"
107 # define OBJECT_EXT "o"
108 # define LIBRARIAN "ar"
109 # define LIBRARIAN_OPTS "cr"
110 # define RANLIB "ranlib"
111 # define PIC_FLAG "-KPIC"
113 # define SHARED_OPTS "-G"
114 # define MODULE_OPTS "-G"
115 # define DYNAMIC_LINK_OPTS ""
116 # define LINKER_FLAG_NO_EQUALS
118 # define HAS_REALPATH
119 # define LD_RUN_PATH "LD_RUN_PATH"
120 # define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
121 # define LD_LIBRARY_PATH_LOCAL LD_LIBRARY_PATH
124 #if defined(_OSD_POSIX)
125 # define SHELL_CMD "/usr/bin/sh"
126 # define DYNAMIC_LIB_EXT "so"
127 # define MODULE_LIB_EXT "so"
128 # define STATIC_LIB_EXT "a"
129 # define OBJECT_EXT "o"
130 # define LIBRARIAN "ar"
131 # define LIBRARIAN_OPTS "cr"
132 # define SHARED_OPTS "-G"
133 # define MODULE_OPTS "-G"
134 # define LINKER_FLAG_PREFIX "-Wl,"
135 # define NEED_SNPRINTF
138 #if defined(sinix) && defined(mips) && defined(__SNI_TARG_UNIX)
139 # define SHELL_CMD "/usr/bin/sh"
140 # define DYNAMIC_LIB_EXT "so"
141 # define MODULE_LIB_EXT "so"
142 # define STATIC_LIB_EXT "a"
143 # define OBJECT_EXT "o"
144 # define LIBRARIAN "ar"
145 # define LIBRARIAN_OPTS "cr"
146 # define RPATH "-Brpath"
147 # define SHARED_OPTS "-G"
148 # define MODULE_OPTS "-G"
149 # define DYNAMIC_LINK_OPTS "-Wl,-Blargedynsym"
150 # define LINKER_FLAG_PREFIX "-Wl,"
151 # define NEED_SNPRINTF
152 # define LD_RUN_PATH "LD_RUN_PATH"
153 # define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
154 # define LD_LIBRARY_PATH_LOCAL LD_LIBRARY_PATH
157 #if defined(__MINGW32__)
158 # define SHELL_CMD "sh"
159 # define DYNAMIC_LIB_EXT "dll"
160 # define MODULE_LIB_EXT "dll"
161 # define STATIC_LIB_EXT "a"
162 # define OBJECT_EXT "o"
163 # define LIBRARIAN "ar"
164 # define LIBRARIAN_OPTS "cr"
165 # define RANLIB "ranlib"
166 # define LINKER_FLAG_PREFIX "-Wl,"
167 # define SHARED_OPTS "-shared"
168 # define MODULE_OPTS "-shared"
169 # define MKDIR_NO_UMASK
170 # define EXE_EXT ".exe"
186 #define LINK_CXX "g++"
190 #define LIBDIR "/usr/local/lib"
193 #define OBJDIR ".libs"
196 #error Unsupported platform: Please add defines for SHELL_CMD etc. for your platform.
208 #define PATH_MAX 1024
212 /* We want to say we are libtool 1.4 for shlibtool compatibility. */
213 #define VERSION "1.4"
215 #define DEBUG(fmt, ...) if(cmd->options.debug) printf(fmt, ## __VA_ARGS__)
216 #define NOTICE(fmt, ...) if(!cmd->options.silent) printf(fmt, ## __VA_ARGS__)
217 #define ERROR(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
233 OUT_DYNAMIC_LIB_ONLY,
269 count_chars *install;
270 count_chars *dependencies;
276 enum shared_mode shared;
279 enum pic_mode pic_mode;
286 enum output_type output;
289 const char *output_name;
290 const char *fake_output_name;
291 const char *basename;
293 const char *install_path;
294 const char *compiler;
296 count_chars *program_opts;
298 count_chars *arglist;
299 count_chars *tmp_dirs;
300 count_chars *obj_files;
301 count_chars *dep_rpaths;
304 library_name static_name;
305 library_name shared_name;
306 library_name module_name;
308 library_opts static_opts;
309 library_opts shared_opts;
311 const char *version_info;
312 const char *undefined_flag;
316 static void add_rpath(count_chars *cc, const char *path);
319 static void usage(int code)
321 printf("Usage: jlibtool [OPTIONS...] COMMANDS...\n");
322 printf("jlibtool is a replacement for GNU libtool with similar functionality.\n\n");
324 printf(" --config show all configuration variables\n");
325 printf(" --debug enable verbose shell tracing\n");
326 printf(" --dry-run display commands without modifying any files\n");
327 printf(" --help display this help message and exit\n");
328 printf(" --mode=MODE use operational mode MODE (you *must* set mode)\n");
330 printf(" --silent don't print informational messages\n");
331 printf(" --tag=TAG Ignored for libtool compatibility\n");
332 printf(" --version print version information\n");
335 printf(" --shared Build shared libraries when using --mode=link\n");
336 printf(" --export-all Try to export 'def' file on some platforms\n");
338 printf("\nMODE must be one of the following:\n\n");
339 printf(" compile compile a source file into a jlibtool object\n");
340 printf(" execute automatically set library path, then run a program\n");
341 printf(" install install libraries or executables\n");
342 printf(" link create a library or an executable\n");
344 printf("\nMODE-ARGS can be the following:\n\n");
345 printf(" -export-dynamic accepted and ignored\n");
346 printf(" -module create a module when linking\n");
347 printf(" -shared create a shared library when linking\n");
348 printf(" -prefer-pic prefer position-independent-code when compiling\n");
349 printf(" -prefer-non-pic prefer non position-independent-code when compiling\n");
350 printf(" -static create a static library when linking\n");
351 printf(" -no-install link libraries locally\n");
352 printf(" -rpath arg Set install path for shared libraries\n");
353 printf(" -l arg pass '-l arg' to the link stage\n");
354 printf(" -L arg pass '-L arg' to the link stage\n");
355 printf(" -R dir add 'dir' to runtime library search path.\n");
356 printf(" -Zexe accepted and ignored\n");
357 printf(" -avoid-version accepted and ignored\n");
362 #if defined(NEED_SNPRINTF)
363 /* Write at most n characters to the buffer in str, return the
364 * number of chars written or -1 if the buffer would have been
367 * This is portable to any POSIX-compliant system has /dev/null
369 static FILE *f = NULL;
370 static int vsnprintf(char *str, size_t n, const char *fmt, va_list ap)
375 f = fopen("/dev/null","w");
382 setvbuf(f, str, _IOFBF, n);
384 res = vfprintf(f, fmt, ap);
386 if ((res > 0) && (res < n)) {
387 res = vsprintf( str, fmt, ap );
392 static int snprintf(char *str, size_t n, const char *fmt, ...)
398 res = vsnprintf( str, n, fmt, ap );
404 static void *lt_malloc(size_t size)
410 ERROR("Failed allocating %zu bytes, OOM", size);
417 static void lt_const_free(const void *ptr)
421 memcpy(&tmp, &ptr, sizeof(tmp));
425 static void init_count_chars(count_chars *cc)
427 cc->vals = (const char**) lt_malloc(PATH_MAX*sizeof(char*));
431 static count_chars *alloc_countchars()
434 out = lt_malloc(sizeof(count_chars));
438 init_count_chars(out);
443 static void clear_count_chars(count_chars *cc)
446 for (i = 0; i < cc->num; i++) {
453 static void push_count_chars(count_chars *cc, const char *newval)
455 cc->vals[cc->num++] = newval;
458 static void pop_count_chars(count_chars *cc)
463 static void insert_count_chars(count_chars *cc, const char *newval, int position)
467 for (i = cc->num; i > position; i--) {
468 cc->vals[i] = cc->vals[i-1];
471 cc->vals[position] = newval;
475 static void append_count_chars(count_chars *cc, count_chars *cctoadd)
478 for (i = 0; i < cctoadd->num; i++) {
479 if (cctoadd->vals[i]) {
480 push_count_chars(cc, cctoadd->vals[i]);
485 static const char *flatten_count_chars(count_chars *cc, int space)
491 for (i = 0; i < cc->num; i++) {
493 size += strlen(cc->vals[i]) + 1;
500 newval = (char*)lt_malloc(size + 1);
503 for (i = 0; i < cc->num; i++) {
505 strcat(newval, cc->vals[i]);
515 static char *shell_esc(const char *str)
520 const unsigned char *s;
522 cmd = (char *)lt_malloc(2 * strlen(str) + 3);
523 d = (unsigned char *)cmd;
524 s = (const unsigned char *)str;
535 else if (*s == '\\' || (*s == ' ' && (in_quote % 2))) {
549 static int external_spawn(command_t *cmd, const char *file, const char **argv)
551 file = file; /* -Wunused */
553 if (!cmd->options.silent) {
554 const char **argument = argv;
555 NOTICE("Executing: ");
557 NOTICE("%s ", *argument);
563 if (cmd->options.dry_run) {
566 #if defined(__EMX__) || defined(__MINGW32__)
567 return spawnvp(P_WAIT, argv[0], argv);
573 return execvp(argv[0], (char**)argv);
577 waitpid(pid, &statuscode, 0);
578 if (WIFEXITED(statuscode)) {
579 return WEXITSTATUS(statuscode);
587 static int run_command(command_t *cmd, count_chars *cc)
593 const char *spawn_args[4];
596 init_count_chars(&tmpcc);
599 push_count_chars(&tmpcc, cmd->program);
602 append_count_chars(&tmpcc, cmd->program_opts);
604 append_count_chars(&tmpcc, cc);
606 raw = flatten_count_chars(&tmpcc, 1);
607 command = shell_esc(raw);
609 memcpy(&tmp, &raw, sizeof(tmp));
612 spawn_args[0] = SHELL_CMD;
613 spawn_args[1] = "-c";
614 spawn_args[2] = command;
615 spawn_args[3] = NULL;
616 ret = external_spawn(cmd, spawn_args[0], spawn_args);
624 * print configuration
625 * shlibpath_var is used in configure.
627 #define printc(_x,_y) if (!value || !strcmp(value, _x)) printf(_x "=\"%s\"\n", _y)
629 static void print_config(const char *value)
632 printc("runpath_var", LD_RUN_PATH);
634 #ifdef LD_LIBRARY_PATH
635 printc("shlibpath_var", LD_LIBRARY_PATH);
637 #ifdef LD_LIBRARY_PATH_LOCAL
638 printc("shlocallibpath_var", LD_LIBRARY_PATH_LOCAL);
641 printc("SHELL", SHELL_CMD);
644 printc("objext", OBJECT_EXT);
647 printc("objdir", OBJDIR);
649 #ifdef DYNAMIC_LIB_EXT
650 /* add a '.' prefix because libtool does that. */
651 printc("shrext_cmds", "echo ." DYNAMIC_LIB_EXT);
652 /* add a '.' prefix because libtool does that. */
653 printc("shrext", "." DYNAMIC_LIB_EXT);
656 printc("exeext", EXE_EXT);
658 #ifdef STATIC_LIB_EXT
659 printc("libext", STATIC_LIB_EXT);
662 printc("AR", LIBRARIAN);
664 #ifdef LIBRARIAN_OPTS
665 printc("AR_FLAGS", LIBRARIAN_OPTS);
667 #ifdef LINKER_FLAG_PREFIX
668 printc("wl", LINKER_FLAG_PREFIX);
671 printc("ranlib", RANLIB);
676 * Add a directory to the runtime library search path.
678 static void add_runtime_dir_lib(const char *arg, command_t *cmd)
681 add_rpath(cmd->shared_opts.dependencies, arg);
683 arg = arg; /* -Wunused */
688 static int parse_long_opt(const char *arg, command_t *cmd)
690 char *equal_pos = strchr(arg, '=');
695 strncpy(var, arg, equal_pos - arg);
696 var[equal_pos - arg] = 0;
697 if (strlen(equal_pos + 1) >= sizeof(var)) return 0;
698 strcpy(value, equal_pos + 1);
700 strncpy(var, arg, sizeof(var) - 1);
701 var[sizeof(var) - 1] = '\0';
706 if (strcmp(var, "silent") == 0) {
707 cmd->options.silent = 1;
708 } else if (strcmp(var, "quiet") == 0) {
709 cmd->options.silent = 1;
710 } else if (strcmp(var, "debug") == 0) {
711 cmd->options.debug = 1;
712 } else if (strcmp(var, "mode") == 0) {
713 if (cmd->mode != MODE_UNKNOWN) {
714 ERROR("Cannot set --mode twice\n");
718 if (strcmp(value, "compile") == 0) {
719 cmd->mode = MODE_COMPILE;
720 cmd->output = OUT_OBJECT;
722 } else if (strcmp(value, "link") == 0) {
723 cmd->mode = MODE_LINK;
724 cmd->output = OUT_LIB;
726 } else if (strcmp(value, "install") == 0) {
727 cmd->mode = MODE_INSTALL;
729 } else if (strcmp(value, "execute") == 0) {
730 cmd->mode = MODE_EXECUTE;
733 ERROR("Unknown mode \"%s\"\n", value);
737 } else if (strcmp(var, "shared") == 0) {
738 if ((cmd->mode == MODE_LINK) && (cmd->output == OUT_GENERAL)) {
739 cmd->output = OUT_DYNAMIC_LIB_ONLY;
741 cmd->options.shared = SHARE_SHARED;
743 } else if (strcmp(var, "export-all") == 0) {
744 cmd->options.export_all = 1;
746 } else if (strcmp(var, "dry-run") == 0) {
747 NOTICE("Dry-run mode on!\n");
748 cmd->options.dry_run = 1;
750 } else if (strcmp(var, "version") == 0) {
751 NOTICE("Version " VERSION "\n");
753 } else if (strcmp(var, "help") == 0) {
756 } else if (strcmp(var, "config") == 0) {
767 /* Return 1 if we eat it. */
768 static int parse_short_opt(const char *arg, command_t *cmd)
770 if (strcmp(arg, "export-dynamic") == 0) {
771 cmd->options.export_dynamic = 1;
775 if (strcmp(arg, "module") == 0) {
776 cmd->output = OUT_MODULE;
780 if (strcmp(arg, "shared") == 0) {
781 if (cmd->mode == MODE_LINK) {
782 cmd->output = OUT_DYNAMIC_LIB_ONLY;
784 cmd->options.shared = SHARE_SHARED;
788 if (strcmp(arg, "Zexe") == 0) {
792 if (strcmp(arg, "avoid-version") == 0) {
796 if (strcmp(arg, "prefer-pic") == 0) {
797 cmd->options.pic_mode = PIC_PREFER;
801 if (strcmp(arg, "prefer-non-pic") == 0) {
802 cmd->options.pic_mode = PIC_AVOID;
806 if (strcmp(arg, "static") == 0) {
807 if ((cmd->mode == MODE_LINK) && (cmd->output == OUT_LIB)) {
808 cmd->output = OUT_STATIC_LIB_ONLY;
810 cmd->options.shared = SHARE_STATIC;
814 if (cmd->mode == MODE_LINK) {
815 if (strcmp(arg, "no-install") == 0) {
816 cmd->options.no_install = 1;
819 if (arg[0] == 'L' || arg[0] == 'l') {
822 push_count_chars(cmd->shared_opts.dependencies, arg);
824 } else if (arg[0] == 'R' && arg[1]) {
825 /* -Rdir Add dir to runtime library search path. */
826 add_runtime_dir_lib(&arg[1], cmd);
833 #ifdef TRUNCATE_DLL_NAME
834 static char *truncate_dll_name(char *path)
836 /* Cut DLL name down to 8 characters after removing any mod_ prefix */
837 char *tmppath = strdup(path);
838 char *newname = strrchr(tmppath, '/') + 1;
839 char *ext = strrchr(newname, '.');
848 if (strncmp(newname, "mod_", 4) == 0) {
849 strcpy(newname, newname + 4);
854 strcpy(newname + 8, strchr(newname, '.'));
861 static long safe_strtol(const char *nptr, const char **endptr, int base)
867 rv = strtol(nptr, (char**)endptr, 10);
869 if (errno == ERANGE) {
876 static void safe_mkdir(command_t *cmd, const char *path)
881 old_umask = umask(0);
884 #ifdef MKDIR_NO_UMASK
885 status = mkdir(path);
887 status = mkdir(path, ~old_umask);
889 if ((status < 0) && (errno != EEXIST)) {
890 NOTICE("Warning: mkdir of %s failed\n", path);
894 /** Returns a file's name without the path
896 * @param path to break apart.
897 * @return pointer in path.
899 static const char *file_name(const char *path)
903 name = strrchr(path, '/');
905 name = strrchr(path, '\\'); /* eww windows? */
918 /** Returns a file's name without path or extension
920 * @param path to check
921 * @return pointer in path.
923 static const char *file_name_stripped(const char *path)
928 name = file_name(path);
929 ext = strrchr(name, '.');
934 trimmed = lt_malloc(ext - name + 1);
935 strncpy(trimmed, name, ext - name);
936 trimmed[ext-name] = 0;
945 /* version_info is in the form of MAJOR:MINOR:PATCH */
946 static const char *darwin_dynamic_link_function(const char *version_info)
949 long major, minor, patch;
956 major = safe_strtol(version_info, &version_info, 10);
959 if (version_info[0] == ':') {
963 minor = safe_strtol(version_info, &version_info, 10);
966 if (version_info[0] == ':') {
970 patch = safe_strtol(version_info, &version_info, 10);
976 /* Avoid -dylib_compatibility_version must be greater than zero errors. */
980 newarg = (char*)lt_malloc(100);
982 "-compatibility_version %ld -current_version %ld.%ld",
983 major, major, minor);
990 * Add a '.libs/' to the buffer. The caller ensures that
991 * The buffer is large enough to handle 6 extra characters.
993 static void add_dotlibs(char *buffer)
995 char *name = strrchr(buffer, '/');
999 strcpy(buffer, ".libs/");
1006 memmove(name + 6, name, strlen(name));
1007 memcpy(name, ".libs/", 6);
1010 static char *gen_library_name(const char *name, enum lib_type genlib)
1012 char *newarg, *newext;
1014 newarg = (char *)calloc(strlen(name) + 11, 1);
1016 if (genlib == TYPE_MODULE_LIB && strncmp(name, "lib", 3) == 0) {
1020 if (genlib == TYPE_MODULE_LIB) {
1021 strcpy(newarg, file_name(name));
1024 strcpy(newarg, name);
1027 newext = strrchr(newarg, '.');
1029 ERROR("Library path does not have an extension");
1037 case TYPE_STATIC_LIB:
1038 strcpy(newext, STATIC_LIB_EXT);
1040 case TYPE_DYNAMIC_LIB:
1041 strcpy(newext, DYNAMIC_LIB_EXT);
1043 case TYPE_MODULE_LIB:
1044 strcpy(newext, MODULE_LIB_EXT);
1051 add_dotlibs(newarg);
1056 static char *gen_install_name(const char *name, enum lib_type genlib)
1062 newname = gen_library_name(name, genlib);
1063 if (!newname) return NULL;
1065 /* Check if it exists. If not, return NULL. */
1066 rv = stat(newname, &sb);
1076 static const char *check_object_exists(command_t *cmd, const char *arg, int arglen)
1081 newarg = (char *)lt_malloc(arglen + 10);
1082 memcpy(newarg, arg, arglen);
1084 ext = newarg + arglen;
1093 strcpy(ext, OBJECT_EXT);
1097 strcpy(ext, NO_PIC_EXT);
1104 DEBUG("Checking (obj): %s\n", newarg);
1105 rv = stat(newarg, &sb);
1107 while (rv != 0 && ++pass < 1);
1118 /* libdircheck values:
1119 * 0 - no .libs suffix
1122 static char *check_library_exists(command_t *cmd, const char *arg, int pathlen,
1123 int libdircheck, enum lib_type*libtype)
1126 int pass, rv, newpathlen;
1128 newarg = (char *)lt_malloc(strlen(arg) + 10);
1129 strcpy(newarg, arg);
1130 newarg[pathlen] = '\0';
1132 newpathlen = pathlen;
1134 add_dotlibs(newarg);
1135 newpathlen += sizeof(".libs/") - 1;
1138 strcpy(newarg + newpathlen, arg + pathlen);
1139 ext = strrchr(newarg, '.');
1141 ERROR("Error: Library path does not have an extension");
1155 if (cmd->options.pic_mode != PIC_AVOID &&
1156 cmd->options.shared != SHARE_STATIC) {
1157 strcpy(ext, DYNAMIC_LIB_EXT);
1158 *libtype = TYPE_DYNAMIC_LIB;
1164 strcpy(ext, STATIC_LIB_EXT);
1165 *libtype = TYPE_STATIC_LIB;
1168 strcpy(ext, MODULE_LIB_EXT);
1169 *libtype = TYPE_MODULE_LIB;
1172 strcpy(ext, OBJECT_EXT);
1173 *libtype = TYPE_OBJECT;
1176 *libtype = TYPE_UKNOWN;
1180 DEBUG("Checking (lib): %s\n", newarg);
1181 rv = stat(newarg, &sb);
1183 while (rv != 0 && ++pass < 4);
1194 static char * load_install_path(const char *arg)
1204 path = lt_malloc(PATH_MAX);
1206 fgets(path, PATH_MAX, f);
1209 if (path[strlen(path)-1] == '\n') {
1210 path[strlen(path)-1] = '\0';
1213 /* Check that we have an absolute path.
1214 * Otherwise the file could be a GNU libtool file.
1216 if (path[0] != '/') {
1224 static char * load_noinstall_path(const char *arg, int pathlen)
1226 char *newarg, *expanded_path;
1229 newarg = (char *)lt_malloc(strlen(arg) + 10);
1230 strcpy(newarg, arg);
1231 newarg[pathlen] = 0;
1233 newpathlen = pathlen;
1234 strcat(newarg, ".libs");
1235 newpathlen += sizeof(".libs") - 1;
1236 newarg[newpathlen] = 0;
1239 expanded_path = lt_malloc(PATH_MAX);
1240 expanded_path = realpath(newarg, expanded_path);
1241 /* Uh, oh. There was an error. Fall back on our first guess. */
1242 if (!expanded_path) {
1243 expanded_path = newarg;
1246 /* We might get ../ or something goofy. Oh, well. */
1247 expanded_path = newarg;
1250 return expanded_path;
1253 static void add_dynamic_link_opts(command_t *cmd, count_chars *args)
1255 #ifdef DYNAMIC_LINK_OPTS
1256 if (cmd->options.pic_mode != PIC_AVOID) {
1257 DEBUG("Adding linker opt: %s\n", DYNAMIC_LINK_OPTS);
1259 push_count_chars(args, DYNAMIC_LINK_OPTS);
1260 if (cmd->undefined_flag) {
1261 push_count_chars(args, "-undefined");
1262 #if defined(__APPLE__)
1263 /* -undefined dynamic_lookup is used by the bundled Python in
1264 * 10.4, but if we don't set MACOSX_DEPLOYMENT_TARGET to 10.3+,
1265 * we'll get a linker error if we pass this flag.
1267 if (strcasecmp(cmd->undefined_flag, "dynamic_lookup") == 0) {
1268 insert_count_chars(cmd->program_opts, "MACOSX_DEPLOYMENT_TARGET=10.3", 0);
1271 push_count_chars(args, cmd->undefined_flag);
1274 #ifdef DYNAMIC_LINK_UNDEFINED
1275 DEBUG("Adding linker opt: %s\n", DYNAMIC_LINK_UNDEFINED);
1277 push_count_chars(args, DYNAMIC_LINK_UNDEFINED);
1284 /* Read the final install location and add it to runtime library search path. */
1286 static void add_rpath(count_chars *cc, const char *path)
1291 #ifdef LINKER_FLAG_PREFIX
1292 size = strlen(LINKER_FLAG_PREFIX);
1294 size = size + strlen(path) + strlen(RPATH) + 2;
1295 tmp = lt_malloc(size);
1297 #ifdef LINKER_FLAG_PREFIX
1298 strcpy(tmp, LINKER_FLAG_PREFIX);
1303 #ifndef LINKER_FLAG_NO_EQUALS
1308 push_count_chars(cc, tmp);
1311 static void add_rpath_file(count_chars *cc, const char *arg)
1315 path = load_install_path(arg);
1317 add_rpath(cc, path);
1318 lt_const_free(path);
1322 static void add_rpath_noinstall(count_chars *cc, const char *arg, int pathlen)
1326 path = load_noinstall_path(arg, pathlen);
1328 add_rpath(cc, path);
1329 lt_const_free(path);
1334 #ifdef DYNAMIC_LINK_NO_INSTALL
1335 static void add_dylink_noinstall(count_chars *cc, const char *arg, int pathlen,
1338 const char *install_path, *current_path, *name;
1340 int i_p_len, c_p_len, name_len, dyext_len, cur_len;
1342 install_path = load_install_path(arg);
1343 current_path = load_noinstall_path(arg, pathlen);
1345 if (!install_path || !current_path) {
1349 push_count_chars(cc, DYNAMIC_LINK_NO_INSTALL);
1351 i_p_len = strlen(install_path);
1352 c_p_len = strlen(current_path);
1355 name_len = extlen-pathlen;
1356 dyext_len = sizeof(DYNAMIC_LIB_EXT) - 1;
1358 /* No, we need to replace the extension. */
1359 exp_argument = (char *)lt_malloc(i_p_len + c_p_len + (name_len*2) +
1363 strcpy(exp_argument, install_path);
1365 exp_argument[cur_len++] = '/';
1366 strncpy(exp_argument+cur_len, name, extlen-pathlen);
1367 cur_len += name_len;
1368 strcpy(exp_argument+cur_len, DYNAMIC_LIB_EXT);
1369 cur_len += dyext_len;
1370 exp_argument[cur_len++] = ':';
1371 strcpy(exp_argument+cur_len, current_path);
1373 exp_argument[cur_len++] = '/';
1374 strncpy(exp_argument+cur_len, name, extlen-pathlen);
1375 cur_len += name_len;
1376 strcpy(exp_argument+cur_len, DYNAMIC_LIB_EXT);
1377 cur_len += dyext_len;
1379 push_count_chars(cc, exp_argument);
1384 /* use -L -llibname to allow to use installed libraries */
1385 static void add_minus_l(count_chars *cc, const char *arg)
1388 char *name = strrchr(arg, '/');
1389 char *file = strrchr(arg, '.');
1391 if ((name != NULL) && (file != NULL) &&
1392 (strstr(name, "lib") == (name + 1))) {
1397 push_count_chars(cc, "-L");
1398 push_count_chars(cc, arg);
1399 /* we need one argument like -lapr-1 */
1400 newarg = lt_malloc(strlen(file) + 3);
1401 strcpy(newarg, "-l");
1402 strcat(newarg, file);
1403 push_count_chars(cc, newarg);
1405 push_count_chars(cc, arg);
1411 static void add_linker_flag_prefix(count_chars *cc, const char *arg)
1413 #ifndef LINKER_FLAG_PREFIX
1414 push_count_chars(cc, arg);
1417 newarg = (char*)lt_malloc(strlen(arg) + sizeof(LINKER_FLAG_PREFIX) + 1);
1418 strcpy(newarg, LINKER_FLAG_PREFIX);
1419 strcat(newarg, arg);
1420 push_count_chars(cc, newarg);
1425 static int explode_static_lib(command_t *cmd, const char *lib)
1427 count_chars tmpdir_cc, libname_cc;
1428 const char *tmpdir, *libname;
1429 char savewd[PATH_MAX];
1432 struct dirent *entry;
1433 const char *lib_args[4];
1436 if (cmd->options.dry_run) {
1440 name = file_name(lib);
1442 init_count_chars(&tmpdir_cc);
1443 push_count_chars(&tmpdir_cc, ".libs/");
1444 push_count_chars(&tmpdir_cc, name);
1445 push_count_chars(&tmpdir_cc, ".exploded/");
1446 tmpdir = flatten_count_chars(&tmpdir_cc, 0);
1448 NOTICE("Making: %s\n", tmpdir);
1450 safe_mkdir(cmd, tmpdir);
1452 push_count_chars(cmd->tmp_dirs, tmpdir);
1454 getcwd(savewd, sizeof(savewd));
1456 if (chdir(tmpdir) != 0) {
1457 NOTICE("Warning: could not explode %s\n", lib);
1462 if (lib[0] == '/') {
1466 init_count_chars(&libname_cc);
1467 push_count_chars(&libname_cc, "../../");
1468 push_count_chars(&libname_cc, lib);
1469 libname = flatten_count_chars(&libname_cc, 0);
1472 lib_args[0] = LIBRARIAN;
1474 lib_args[2] = libname;
1477 external_spawn(cmd, LIBRARIAN, lib_args);
1480 dir = opendir(tmpdir);
1482 while ((entry = readdir(dir)) != NULL) {
1483 #if defined(__APPLE__) && defined(RANLIB)
1484 /* Apple inserts __.SYMDEF which isn't needed.
1485 * Leopard (10.5+) can also add '__.SYMDEF SORTED' which isn't
1486 * much fun either. Just skip them.
1488 if (strstr(entry->d_name, "__.SYMDEF") != NULL) {
1492 if (entry->d_name[0] != '.') {
1493 push_count_chars(&tmpdir_cc, entry->d_name);
1494 name = flatten_count_chars(&tmpdir_cc, 0);
1496 DEBUG("Adding object: %s\n", name);
1497 push_count_chars(cmd->obj_files, name);
1498 pop_count_chars(&tmpdir_cc);
1506 static int parse_input_file_name(const char *arg, command_t *cmd)
1508 const char *ext = strrchr(arg, '.');
1511 enum lib_type libtype;
1514 /* Can't guess the extension */
1520 name = file_name(arg);
1521 pathlen = name - arg;
1524 * Were linking and have an archived object or object file
1525 * push it onto the list of object files which'll get used
1526 * to create the input files list for the linker.
1528 * We assume that these are outside of the project were building,
1529 * as there's no reason to create .a files as part of the build
1532 if (!strcmp(ext, STATIC_LIB_EXT) && (cmd->mode == MODE_LINK)) {
1535 if (!stat(arg, &sb)) {
1536 DEBUG("Adding object: %s\n", arg);
1538 push_count_chars(cmd->obj_files, arg);
1545 * More object files, if were linking they get set as input
1548 if (!strcmp(ext, "lo") || !strcmp(ext, OBJECT_EXT)) {
1549 newarg = check_object_exists(cmd, arg, ext - arg);
1551 ERROR("Can not find suitable object file for %s\n", arg);
1555 if (cmd->mode == MODE_LINK) {
1556 DEBUG("Adding object: %s\n", newarg);
1558 push_count_chars(cmd->obj_files, newarg);
1560 push_count_chars(cmd->arglist, newarg);
1566 if (!strcmp(ext, "la")) {
1567 switch (cmd->mode) {
1569 /* Try the .libs dir first! */
1570 newarg = check_library_exists(cmd, arg, pathlen, 1, &libtype);
1572 /* Try the normal dir next. */
1573 newarg = check_library_exists(cmd, arg, pathlen, 0, &libtype);
1575 ERROR("Can not find suitable library for %s\n", arg);
1580 /* It is not ok to just add the file: a library may added with:
1581 1 - -L path library_name. (For *.so in Linux).
1585 if (libtype == TYPE_DYNAMIC_LIB) {
1586 add_minus_l(cmd->shared_opts.dependencies, newarg);
1587 } else if (cmd->output == OUT_LIB &&
1588 libtype == TYPE_STATIC_LIB) {
1589 explode_static_lib(cmd, newarg);
1591 push_count_chars(cmd->shared_opts.dependencies, newarg);
1594 if (cmd->output == OUT_LIB && libtype == TYPE_STATIC_LIB) {
1595 explode_static_lib(cmd, newarg);
1598 push_count_chars(cmd->shared_opts.dependencies, newarg);
1601 if (libtype == TYPE_DYNAMIC_LIB) {
1602 if (cmd->options.no_install) {
1604 add_rpath_noinstall(cmd->shared_opts.dependencies,
1610 add_rpath_file(cmd->shared_opts.dependencies, arg);
1617 * If we've already recorded a library to
1618 * install, we're most likely getting the .la
1619 * file that we want to install as.
1621 * The problem is that we need to add it as the
1622 * directory, not the .la file itself.
1623 * Otherwise, we'll do odd things.
1625 if (cmd->output == OUT_LIB) {
1629 tmp[pathlen] = '\0';
1630 push_count_chars(cmd->arglist, tmp);
1633 cmd->output = OUT_LIB;
1634 cmd->output_name = arg;
1635 cmd->static_name.install = gen_install_name(arg, 0);
1636 cmd->shared_name.install = gen_install_name(arg, 1);
1637 cmd->module_name.install = gen_install_name(arg, 2);
1639 if (!cmd->static_name.install &&
1640 !cmd->shared_name.install &&
1641 !cmd->module_name.install) {
1642 ERROR("Files to install do not exist\n");
1655 if (!strcmp(ext, "c")) {
1656 /* If we don't already have an idea what our output name will be. */
1657 if (!cmd->basename) {
1658 char *tmp = lt_malloc(strlen(arg) + 4);
1660 strcpy(strrchr(tmp, '.') + 1, "lo");
1662 cmd->basename = tmp;
1664 cmd->fake_output_name = strrchr(cmd->basename, '/');
1665 if (cmd->fake_output_name) {
1666 cmd->fake_output_name++;
1668 cmd->fake_output_name = cmd->basename;
1676 static int parse_output_file_name(const char *arg, command_t *cmd)
1680 char *newarg = NULL;
1683 cmd->fake_output_name = arg;
1685 name = file_name(arg);
1686 ext = strrchr(name, '.');
1689 if (!ext || strcmp(ext, EXE_EXT) == 0) {
1693 cmd->basename = arg;
1694 cmd->output = OUT_PROGRAM;
1695 #if defined(_OSD_POSIX)
1696 cmd->options.pic_mode = PIC_AVOID;
1698 newarg = (char *)lt_malloc(strlen(arg) + 5);
1699 strcpy(newarg, arg);
1702 strcat(newarg, EXE_EXT);
1705 cmd->output_name = newarg;
1710 pathlen = name - arg;
1712 if (strcmp(ext, "la") == 0) {
1713 assert(cmd->mode == MODE_LINK);
1715 cmd->basename = arg;
1716 cmd->static_name.normal = gen_library_name(arg, TYPE_STATIC_LIB);
1717 cmd->shared_name.normal = gen_library_name(arg, TYPE_DYNAMIC_LIB);
1718 cmd->module_name.normal = gen_library_name(arg, TYPE_MODULE_LIB);
1719 cmd->static_name.install = gen_install_name(arg, TYPE_STATIC_LIB);
1720 cmd->shared_name.install = gen_install_name(arg, TYPE_DYNAMIC_LIB);
1721 cmd->module_name.install = gen_install_name(arg, TYPE_MODULE_LIB);
1723 if (!cmd->options.dry_run) {
1726 newname = lt_malloc(strlen(cmd->static_name.normal) + 1);
1728 strcpy(newname, cmd->static_name.normal);
1729 newext = strrchr(newname, '/');
1731 /* Check first to see if the dir already exists! */
1732 safe_mkdir(cmd, ".libs");
1735 safe_mkdir(cmd, newname);
1740 #ifdef TRUNCATE_DLL_NAME
1742 arg = truncate_dll_name(arg);
1746 cmd->output_name = arg;
1750 if (strcmp(ext, STATIC_LIB_EXT) == 0) {
1751 assert(cmd->mode == MODE_LINK);
1753 cmd->basename = arg;
1754 cmd->options.shared = SHARE_STATIC;
1755 cmd->output = OUT_STATIC_LIB_ONLY;
1756 cmd->static_name.normal = gen_library_name(arg, TYPE_STATIC_LIB);
1757 cmd->static_name.install = gen_install_name(arg, TYPE_STATIC_LIB);
1759 if (!cmd->options.dry_run) {
1762 newname = lt_malloc(strlen(cmd->static_name.normal) + 1);
1764 strcpy(newname, cmd->static_name.normal);
1765 newext = strrchr(newname, '/');
1767 /* Check first to see if the dir already exists! */
1768 safe_mkdir(cmd, ".libs");
1771 safe_mkdir(cmd, newname);
1776 cmd->output_name = arg;
1780 if (strcmp(ext, DYNAMIC_LIB_EXT) == 0) {
1781 assert(cmd->mode == MODE_LINK);
1783 cmd->basename = arg;
1784 cmd->options.shared = SHARE_SHARED;
1785 cmd->output = OUT_DYNAMIC_LIB_ONLY;
1786 cmd->shared_name.normal = gen_library_name(arg, TYPE_DYNAMIC_LIB);
1787 cmd->module_name.normal = gen_library_name(arg, TYPE_MODULE_LIB);
1788 cmd->shared_name.install = gen_install_name(arg, TYPE_DYNAMIC_LIB);
1789 cmd->module_name.install = gen_install_name(arg, TYPE_MODULE_LIB);
1791 if (!cmd->options.dry_run) {
1794 newname = lt_malloc(strlen(cmd->shared_name.normal) + 1);
1796 strcpy(newname, cmd->shared_name.normal);
1797 newext = strrchr(newname, '/');
1799 /* Check first to see if the dir already exists! */
1800 safe_mkdir(cmd, ".libs");
1803 safe_mkdir(cmd, newname);
1808 cmd->output_name = arg;
1812 if (strcmp(ext, "lo") == 0) {
1814 cmd->basename = arg;
1815 cmd->output = OUT_OBJECT;
1816 newarg = (char *)lt_malloc(strlen(arg) + 2);
1817 strcpy(newarg, arg);
1818 newext = strrchr(newarg, '.') + 1;
1819 strcpy(newext, OBJECT_EXT);
1820 cmd->output_name = newarg;
1824 if (strcmp(ext, DYNAMIC_LIB_EXT) == 0) {
1825 ERROR("Please build libraries with .la target, not ."
1826 DYNAMIC_LIB_EXT "\n");
1831 if (strcmp(ext, STATIC_LIB_EXT) == 0) {
1832 ERROR("Please build libraries with .la target, not ."
1833 STATIC_LIB_EXT "\n");
1841 static const char *automode(const char *arg, command_t *cmd)
1843 if (cmd->mode != MODE_UNKNOWN) return arg;
1845 if (!strcmp(arg, "CC") ||
1846 !strcmp(arg, "CXX")) {
1847 DEBUG("Now in compile mode, guessed from: %s\n", arg);
1849 cmd->mode = MODE_COMPILE;
1851 } else if (!strcmp(arg, "LINK") ||
1852 !strcmp(arg, "LINK.c") ||
1853 !strcmp(arg, "LINK.cxx")) {
1854 DEBUG("Now in linker mode, guessed from: %s\n", arg);
1856 cmd->mode = MODE_LINK;
1864 static void generate_def_file(command_t *cmd)
1866 char def_file[1024];
1867 char implib_file[1024];
1870 char *export_args[1024];
1871 int num_export_args = 0;
1876 if (cmd->output_name) {
1877 strcpy(def_file, cmd->output_name);
1878 strcat(def_file, ".def");
1879 hDef = fopen(def_file, "w");
1882 fprintf(hDef, "LIBRARY '%s' INITINSTANCE\n", file_name_stripped(cmd->output_name));
1883 fprintf(hDef, "DATA NONSHARED\n");
1884 fprintf(hDef, "EXPORTS\n");
1887 for (a = 0; a < cmd->num_obj_files; a++) {
1888 cmd_size += strlen(cmd->obj_files[a]) + 1;
1891 cmd_size += strlen(GEN_EXPORTS) + strlen(def_file) + 3;
1892 cmd = (char *)lt_malloc(cmd_size);
1893 strcpy(cmd, GEN_EXPORTS);
1895 for (a=0; a < cmd->num_obj_files; a++) {
1897 strcat(cmd, cmd->obj_files[a] );
1901 strcat(cmd, def_file);
1903 export_args[num_export_args++] = SHELL_CMD;
1904 export_args[num_export_args++] = "-c";
1905 export_args[num_export_args++] = cmd;
1906 export_args[num_export_args++] = NULL;
1907 external_spawn(cmd, export_args[0], (const char**)export_args);
1908 cmd->arglist[cmd->num_args++] = strdup(def_file);
1910 /* Now make an import library for the dll */
1911 num_export_args = 0;
1912 export_args[num_export_args++] = DEF2IMPLIB_CMD;
1913 export_args[num_export_args++] = "-o";
1915 strcpy(implib_file, ".libs/");
1916 strcat(implib_file, cmd->basename);
1917 ext = strrchr(implib_file, '.');
1923 strcat(implib_file, ".");
1924 strcat(implib_file, STATIC_LIB_EXT);
1926 export_args[num_export_args++] = implib_file;
1927 export_args[num_export_args++] = def_file;
1928 export_args[num_export_args++] = NULL;
1929 external_spawn(cmd, export_args[0], (const char**)export_args);
1937 static const char* expand_path(const char *relpath)
1939 char foo[PATH_MAX], *newpath;
1941 getcwd(foo, PATH_MAX-1);
1942 newpath = (char*)lt_malloc(strlen(foo)+strlen(relpath)+2);
1943 strcpy(newpath, foo);
1944 strcat(newpath, "/");
1945 strcat(newpath, relpath);
1950 static void link_fixup(command_t *cmd)
1952 /* If we were passed an -rpath directive, we need to build
1953 * shared objects too. Otherwise, we should only create static
1956 if (!cmd->install_path && (cmd->output == OUT_DYNAMIC_LIB_ONLY ||
1957 cmd->output == OUT_MODULE || cmd->output == OUT_LIB)) {
1958 if (cmd->options.shared == SHARE_SHARED) {
1959 cmd->install_path = LIBDIR;
1963 if (cmd->output == OUT_DYNAMIC_LIB_ONLY ||
1964 cmd->output == OUT_MODULE ||
1965 cmd->output == OUT_LIB) {
1967 push_count_chars(cmd->shared_opts.normal, "-o");
1968 if (cmd->output == OUT_MODULE) {
1969 push_count_chars(cmd->shared_opts.normal, cmd->module_name.normal);
1971 push_count_chars(cmd->shared_opts.normal, cmd->shared_name.normal);
1972 #ifdef DYNAMIC_INSTALL_NAME
1973 push_count_chars(cmd->shared_opts.normal, DYNAMIC_INSTALL_NAME);
1975 if (!cmd->install_path) {
1976 ERROR("Installation mode requires -rpath\n");
1981 char *tmp = lt_malloc(PATH_MAX);
1982 strcpy(tmp, cmd->install_path);
1984 if (cmd->shared_name.install) {
1985 strcat(tmp, strrchr(cmd->shared_name.install, '/'));
1987 strcat(tmp, strrchr(cmd->shared_name.normal, '/'));
1990 push_count_chars(cmd->shared_opts.normal, tmp);
1995 append_count_chars(cmd->shared_opts.normal, cmd->obj_files);
1996 append_count_chars(cmd->shared_opts.normal, cmd->shared_opts.dependencies);
1998 if (cmd->options.export_all) {
2000 generate_def_file(cmd);
2005 if (cmd->output == OUT_LIB || cmd->output == OUT_STATIC_LIB_ONLY) {
2006 push_count_chars(cmd->static_opts.normal, "-o");
2007 push_count_chars(cmd->static_opts.normal, cmd->output_name);
2010 if (cmd->output == OUT_PROGRAM) {
2011 if (cmd->output_name) {
2012 push_count_chars(cmd->arglist, "-o");
2013 push_count_chars(cmd->arglist, cmd->output_name);
2014 append_count_chars(cmd->arglist, cmd->obj_files);
2015 append_count_chars(cmd->arglist, cmd->shared_opts.dependencies);
2016 add_dynamic_link_opts(cmd, cmd->arglist);
2021 static void post_parse_fixup(command_t *cmd)
2027 if (cmd->options.pic_mode != PIC_AVOID) {
2028 push_count_chars(cmd->arglist, PIC_FLAG);
2031 if (cmd->output_name) {
2032 push_count_chars(cmd->arglist, "-o");
2033 push_count_chars(cmd->arglist, cmd->output_name);
2040 if (cmd->output == OUT_LIB) {
2048 if (cmd->output == OUT_OBJECT ||
2049 cmd->output == OUT_PROGRAM ||
2050 cmd->output == OUT_LIB ||
2051 cmd->output == OUT_DYNAMIC_LIB_ONLY) {
2052 push_count_chars(cmd->arglist, "-Zomf");
2056 if (cmd->options.shared &&
2057 (cmd->output == OUT_OBJECT ||
2058 cmd->output == OUT_LIB ||
2059 cmd->output == OUT_DYNAMIC_LIB_ONLY)) {
2061 push_count_chars(cmd->arglist, SHARE_SW);
2066 static int run_mode(command_t *cmd)
2069 count_chars *cctemp;
2071 cctemp = (count_chars*)lt_malloc(sizeof(count_chars));
2072 init_count_chars(cctemp);
2077 rv = run_command(cmd, cmd->arglist);
2078 if (rv) goto finish;
2081 /* Well, we'll assume it's a file going to a directory... */
2082 /* For brain-dead install-sh based scripts, we have to repeat
2083 * the command N-times. install-sh should die.
2085 if (!cmd->output_name) {
2086 rv = run_command(cmd, cmd->arglist);
2087 if (rv) goto finish;
2089 if (cmd->output_name) {
2090 append_count_chars(cctemp, cmd->arglist);
2091 insert_count_chars(cctemp,
2094 rv = run_command(cmd, cctemp);
2095 if (rv) goto finish;
2096 clear_count_chars(cctemp);
2098 if (cmd->static_name.install) {
2099 append_count_chars(cctemp, cmd->arglist);
2100 insert_count_chars(cctemp,
2101 cmd->static_name.install,
2103 rv = run_command(cmd, cctemp);
2104 if (rv) goto finish;
2105 #if defined(__APPLE__) && defined(RANLIB)
2106 /* From the Apple libtool(1) manpage on Tiger/10.4:
2108 * With the way libraries used to be created, errors were possible
2109 * if the library was modified with ar(1) and the table of
2110 * contents was not updated by rerunning ranlib(1). Thus the
2111 * link editor, ld, warns when the modification date of a library
2112 * is more recent than the creation date of its table of
2113 * contents. Unfortunately, this means that you get the warning
2114 * even if you only copy the library.
2117 * This means that when we install the static archive, we need to
2118 * rerun ranlib afterwards.
2120 const char *lib_args[3], *static_lib_name;
2126 len1 = strlen(cmd->arglist->vals[cmd->arglist->num - 1]);
2128 static_lib_name = file_name(cmd->static_name.install);
2129 len2 = strlen(static_lib_name);
2131 tmp = lt_malloc(len1 + len2 + 2);
2133 snprintf(tmp, len1 + len2 + 2, "%s/%s",
2134 cmd->arglist->vals[cmd->arglist->num - 1],
2137 lib_args[0] = RANLIB;
2141 external_spawn(cmd, RANLIB, lib_args);
2146 clear_count_chars(cctemp);
2148 if (cmd->shared_name.install) {
2149 append_count_chars(cctemp, cmd->arglist);
2150 insert_count_chars(cctemp, cmd->shared_name.install,
2152 rv = run_command(cmd, cctemp);
2153 if (rv) goto finish;
2154 clear_count_chars(cctemp);
2156 if (cmd->module_name.install) {
2157 append_count_chars(cctemp, cmd->arglist);
2158 insert_count_chars(cctemp, cmd->module_name.install,
2160 rv = run_command(cmd, cctemp);
2161 if (rv) goto finish;
2162 clear_count_chars(cctemp);
2166 if (cmd->output == OUT_STATIC_LIB_ONLY ||
2167 cmd->output == OUT_LIB) {
2169 const char *lib_args[3];
2171 /* Removes compiler! */
2172 cmd->program = LIBRARIAN;
2173 push_count_chars(cmd->program_opts, LIBRARIAN_OPTS);
2174 push_count_chars(cmd->program_opts, cmd->static_name.normal);
2176 rv = run_command(cmd, cmd->obj_files);
2177 if (rv) goto finish;
2180 lib_args[0] = RANLIB;
2181 lib_args[1] = cmd->static_name.normal;
2183 external_spawn(cmd, RANLIB, lib_args);
2187 if (cmd->output == OUT_DYNAMIC_LIB_ONLY ||
2188 cmd->output == OUT_MODULE ||
2189 cmd->output == OUT_LIB) {
2190 cmd->program = NULL;
2191 clear_count_chars(cmd->program_opts);
2193 append_count_chars(cmd->program_opts, cmd->arglist);
2194 if (cmd->output == OUT_MODULE) {
2196 push_count_chars(cmd->program_opts, MODULE_OPTS);
2200 push_count_chars(cmd->program_opts, SHARED_OPTS);
2202 #ifdef dynamic_link_version_func
2203 push_count_chars(cmd->program_opts,
2204 dynamic_link_version_func(cmd->version_info));
2207 add_dynamic_link_opts(cmd, cmd->program_opts);
2209 rv = run_command(cmd, cmd->shared_opts.normal);
2210 if (rv) goto finish;
2212 if (cmd->output == OUT_PROGRAM) {
2213 rv = run_command(cmd, cmd->arglist);
2214 if (rv) goto finish;
2219 char *l, libpath[PATH_MAX];
2221 if (strlen(cmd->arglist->vals[0]) >= PATH_MAX) {
2222 ERROR("Libpath too long no buffer space");
2228 strcpy(libpath, cmd->arglist->vals[0]);
2229 add_dotlibs(libpath);
2230 l = strrchr(libpath, '/');
2231 if (!l) l = strrchr(libpath, '\\');
2239 l = "./build/lib/.libs";
2240 setenv(LD_LIBRARY_PATH_LOCAL, l, 1);
2241 rv = run_command(cmd, cmd->arglist);
2242 if (rv) goto finish;
2256 static void cleanup_tmp_dir(const char *dirname)
2259 struct dirent *entry;
2260 char fullname[1024];
2262 dir = opendir(dirname);
2267 if ((strlen(dirname) + 1 + sizeof(entry->d_name)) >= sizeof(fullname)) {
2268 ERROR("Dirname too long, out of buffer space");
2270 (void) closedir(dir);
2274 while ((entry = readdir(dir)) != NULL) {
2275 if (entry->d_name[0] != '.') {
2276 strcpy(fullname, dirname);
2277 strcat(fullname, "/");
2278 strcat(fullname, entry->d_name);
2279 (void) remove(fullname);
2285 (void) closedir(dir);
2288 static void cleanup_tmp_dirs(command_t *cmd)
2292 for (d = 0; d < cmd->tmp_dirs->num; d++) {
2293 cleanup_tmp_dir(cmd->tmp_dirs->vals[d]);
2297 static int ensure_fake_uptodate(command_t *cmd)
2299 /* FIXME: could do the stat/touch here, but nah... */
2300 const char *touch_args[3];
2302 if (cmd->mode == MODE_INSTALL) {
2305 if (!cmd->fake_output_name) {
2309 touch_args[0] = "touch";
2310 touch_args[1] = cmd->fake_output_name;
2311 touch_args[2] = NULL;
2312 return external_spawn(cmd, "touch", touch_args);
2315 /* Store the install path in the *.la file */
2316 static int add_for_runtime(command_t *cmd)
2318 if (cmd->mode == MODE_INSTALL) {
2321 if (cmd->output == OUT_DYNAMIC_LIB_ONLY ||
2322 cmd->output == OUT_LIB) {
2323 FILE *f=fopen(cmd->fake_output_name,"w");
2327 fprintf(f,"%s\n", cmd->install_path);
2331 return(ensure_fake_uptodate(cmd));
2335 static void parse_args(int argc, char *argv[], command_t *cmd)
2338 const char *arg, *base;
2342 * We now take a major step past libtool.
2344 * IF there's no "--mode=...", AND we recognise
2345 * the binary as a "special" name, THEN replace it
2346 * with the correct one, and set the correct mode.
2348 * For example if were called 'CC' then we know we should
2349 * probably be compiling stuff.
2351 base = file_name(argv[0]);
2352 arg = automode(base, cmd);
2354 push_count_chars(cmd->arglist, arg);
2356 assert(cmd->mode != MODE_UNKNOWN);
2360 * We first pass over the command-line arguments looking for
2361 * "--mode", etc. If so, then use the libtool compatibility
2362 * method for building the software. Otherwise, auto-detect it
2363 * via "-o" and the extensions.
2366 if (cmd->mode == MODE_UNKNOWN) for (a = 1; a < argc; a++) {
2369 if (strncmp(arg, "--mode=", 7) == 0) {
2375 * Stop if we get another magic method
2378 ((strncmp(arg, "LINK", 4) == 0) ||
2379 (strcmp(arg, "CC") == 0) ||
2380 (strcmp(arg, "CXX") == 0))) {
2385 if (strncmp(arg, "-o", 2) == 0) {
2391 * There were no magic args or an explicit --mode= but we did
2392 * find an output file, so guess what mode were meant to be in
2393 * from its extension.
2396 arg = strrchr(base, '.');
2398 cmd->mode = MODE_LINK;
2399 push_count_chars(cmd->arglist, LINK_C);
2402 else if (strcmp(arg, EXE_EXT) == 0) {
2403 cmd->mode = MODE_LINK;
2404 push_count_chars(cmd->arglist, LINK_C);
2407 else if (strcmp(arg + 1, DYNAMIC_LIB_EXT) == 0) {
2408 cmd->mode = MODE_LINK;
2409 push_count_chars(cmd->arglist, LINK_C);
2411 else if (strcmp(arg + 1, STATIC_LIB_EXT) == 0) {
2412 cmd->mode = MODE_LINK;
2413 push_count_chars(cmd->arglist, LINK_C);
2415 else if (strcmp(arg + 1, "la") == 0) {
2416 cmd->mode = MODE_LINK;
2417 push_count_chars(cmd->arglist, LINK_C);
2419 else if ((strcmp(arg + 1, "lo") == 0) ||
2420 (strcmp(arg + 1, "o") == 0)) {
2421 cmd->mode = MODE_COMPILE;
2422 push_count_chars(cmd->arglist, CC);
2426 for (a = 1; a < argc; a++) {
2430 if (arg[0] == '-') {
2432 * Double dashed (long) single dash (short)
2434 arg_used = (arg[1] == '-') ?
2435 parse_long_opt(arg + 2, cmd) :
2436 parse_short_opt(arg + 1, cmd);
2438 if (arg_used) continue;
2441 * We haven't done anything with it yet, but
2442 * there are still some arg/value pairs.
2444 * Try some of the more complicated short opts...
2448 * We found an output file!
2450 if ((arg[1] == 'o') && (arg[2] == '\0')) {
2452 arg_used = parse_output_file_name(arg,
2455 * -MT literal dependency
2457 } else if (!strcmp(arg + 1, "MT")) {
2458 DEBUG("Adding: %s\n", arg);
2460 push_count_chars(cmd->arglist, arg);
2463 NOTICE(" %s\n", arg);
2465 push_count_chars(cmd->arglist, arg);
2468 * Runtime library search path
2470 } else if (!strcmp(arg + 1, "rpath")) {
2471 /* Aha, we should try to link both! */
2472 cmd->install_path = argv[++a];
2475 } else if (!strcmp(arg + 1, "release")) {
2476 /* Store for later deciphering */
2477 cmd->version_info = argv[++a];
2480 } else if (!strcmp(arg + 1, "version-info")) {
2481 /* Store for later deciphering */
2482 cmd->version_info = argv[++a];
2485 } else if (!strcmp(arg + 1,
2486 "export-symbols-regex")) {
2487 /* Skip the argument. */
2491 } else if (!strcmp(arg + 1, "undefined")) {
2492 cmd->undefined_flag = argv[++a];
2495 * Add dir to runtime library search path.
2497 } else if ((arg[1] == 'R') && !arg[2]) {
2499 add_runtime_dir_lib(argv[++a], cmd);
2504 * Ok.. the argument doesn't begin with a dash
2505 * maybe it's an input file.
2507 * Check its extension to see if it's a known input
2508 * file and verify it exists.
2511 arg_used = parse_input_file_name(arg, cmd);
2515 * If we still don't have a run mode, look for a magic
2516 * program name CC, LINK, or whatever. Then replace that
2517 * with the name of the real program we want to run.
2520 if ((cmd->arglist->num == 0) &&
2521 (cmd->mode == MODE_UNKNOWN)) {
2522 arg = automode(arg, cmd);
2525 DEBUG("Adding: %s\n", arg);
2527 push_count_chars(cmd->arglist, arg);
2533 int main(int argc, char *argv[])
2538 memset(&cmd, 0, sizeof(cmd));
2540 cmd.options.pic_mode = PIC_UNKNOWN;
2541 cmd.mode = MODE_UNKNOWN;
2542 cmd.output = OUT_GENERAL;
2545 * Initialise the various argument lists
2547 cmd.program_opts = alloc_countchars();
2548 cmd.arglist = alloc_countchars();
2549 cmd.tmp_dirs = alloc_countchars();
2550 cmd.obj_files = alloc_countchars();
2551 cmd.dep_rpaths = alloc_countchars();
2552 cmd.rpaths = alloc_countchars();
2553 cmd.static_opts.normal = alloc_countchars();
2554 cmd.shared_opts.normal = alloc_countchars();
2555 cmd.shared_opts.dependencies = alloc_countchars();
2558 * Fill up the various argument lists
2560 parse_args(argc, argv, &cmd);
2561 post_parse_fixup(&cmd);
2564 * We couldn't figure out which mode to operate in
2566 if (cmd.mode == MODE_UNKNOWN) {
2570 rc = run_mode(&cmd);
2572 add_for_runtime(&cmd);
2575 cleanup_tmp_dirs(&cmd);