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.
22 #include <sys/types.h>
24 #if !defined(__MINGW32__)
25 # include <sys/wait.h>
34 # define SHELL_CMD "sh"
35 # define GEN_EXPORTS "emxexp"
36 # define DEF2IMPLIB_CMD "emximp"
37 # define SHARE_SW "-Zdll -Zmtd"
39 # define TRUNCATE_DLL_NAME
40 # define DYNAMIC_LIB_EXT "dll"
41 # define EXE_EX ".exe"
42 /* OMF is the native format under OS/2 */
45 # define STATIC_LIB_EXT "lib"
46 # define OBJECT_EXT "obj"
47 # define LIBRARIAN "emxomfar"
48 # define LIBRARIAN_OPTS "cr"
50 /* but the alternative, a.out, can fork() which is sometimes necessary */
51 # define STATIC_LIB_EXT "a"
52 # define OBJECT_EXT "o"
53 # define LIBRARIAN "ar"
54 # define LIBRARIAN_OPTS "cr"
58 #if defined(__APPLE__)
59 # define SHELL_CMD "/bin/sh"
60 # define DYNAMIC_LIB_EXT "dylib"
61 # define MODULE_LIB_EXT "bundle"
62 # define STATIC_LIB_EXT "a"
63 # define OBJECT_EXT "o"
64 # define LIBRARIAN "ar"
65 # define LIBRARIAN_OPTS "cr"
66 /* man libtool(1) documents ranlib option of -c. */
67 # define RANLIB "ranlib"
68 # define PIC_FLAG "-fPIC -fno-common"
69 # define SHARED_OPTS "-dynamiclib"
70 # define MODULE_OPTS "-bundle -dynamic"
71 # define DYNAMIC_LINK_OPTS "-flat_namespace"
72 # define DYNAMIC_LINK_UNDEFINED "-undefined suppress"
73 # define dynamic_link_version_func darwin_dynamic_link_function
74 # define DYNAMIC_INSTALL_NAME "-install_name"
75 # define DYNAMIC_LINK_NO_INSTALL "-dylib_file"
77 /*-install_name /Users/jerenk/apache-2.0-cvs/lib/libapr.0.dylib -compatibility_version 1 -current_version 1.0 */
78 # define LD_LIBRARY_PATH "DYLD_LIBRARY_PATH"
79 # define LD_LIBRARY_PATH_LOCAL "DYLD_FALLBACK_LIBRARY_PATH"
82 #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
83 # define SHELL_CMD "/bin/sh"
84 # define DYNAMIC_LIB_EXT "so"
85 # define MODULE_LIB_EXT "so"
86 # define STATIC_LIB_EXT "a"
87 # define OBJECT_EXT "o"
88 # define LIBRARIAN "ar"
89 # define LIBRARIAN_OPTS "cr"
90 # define RANLIB "ranlib"
91 # define PIC_FLAG "-fPIC"
92 # define RPATH "-rpath"
93 # define SHARED_OPTS "-shared"
94 # define MODULE_OPTS "-shared"
95 # define LINKER_FLAG_PREFIX "-Wl,"
96 # define DYNAMIC_LINK_OPTS LINKER_FLAG_PREFIX "-export-dynamic"
98 # define LD_RUN_PATH "LD_RUN_PATH"
99 # define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
100 # define LD_LIBRARY_PATH_LOCAL LD_LIBRARY_PATH
104 # define SHELL_CMD "/bin/sh"
105 # define DYNAMIC_LIB_EXT "so"
106 # define MODULE_LIB_EXT "so"
107 # define STATIC_LIB_EXT "a"
108 # define OBJECT_EXT "o"
109 # define LIBRARIAN "ar"
110 # define LIBRARIAN_OPTS "cr"
111 # define RANLIB "ranlib"
112 # define PIC_FLAG "-fPIC"
114 # define SHARED_OPTS "-G"
115 # define MODULE_OPTS "-G"
116 # define DYNAMIC_LINK_OPTS ""
117 # define LINKER_FLAG_NO_EQUALS
119 # define HAS_REALPATH
120 # define LD_RUN_PATH "LD_RUN_PATH"
121 # define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
122 # define LD_LIBRARY_PATH_LOCAL LD_LIBRARY_PATH
125 #if defined(_OSD_POSIX)
126 # define SHELL_CMD "/usr/bin/sh"
127 # define DYNAMIC_LIB_EXT "so"
128 # define MODULE_LIB_EXT "so"
129 # define STATIC_LIB_EXT "a"
130 # define OBJECT_EXT "o"
131 # define LIBRARIAN "ar"
132 # define LIBRARIAN_OPTS "cr"
133 # define SHARED_OPTS "-G"
134 # define MODULE_OPTS "-G"
135 # define LINKER_FLAG_PREFIX "-Wl,"
136 # define NEED_SNPRINTF
139 #if defined(sinix) && defined(mips) && defined(__SNI_TARG_UNIX)
140 # define SHELL_CMD "/usr/bin/sh"
141 # define DYNAMIC_LIB_EXT "so"
142 # define MODULE_LIB_EXT "so"
143 # define STATIC_LIB_EXT "a"
144 # define OBJECT_EXT "o"
145 # define LIBRARIAN "ar"
146 # define LIBRARIAN_OPTS "cr"
147 # define RPATH "-Brpath"
148 # define SHARED_OPTS "-G"
149 # define MODULE_OPTS "-G"
150 # define LINKER_FLAG_PREFIX "-Wl,"
151 # define DYNAMIC_LINK_OPTS LINKER_FLAG_PREFIX "-Blargedynsym"
153 # define NEED_SNPRINTF
154 # define LD_RUN_PATH "LD_RUN_PATH"
155 # define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
156 # define LD_LIBRARY_PATH_LOCAL LD_LIBRARY_PATH
159 #if defined(__MINGW32__)
160 # define SHELL_CMD "sh"
161 # define DYNAMIC_LIB_EXT "dll"
162 # define MODULE_LIB_EXT "dll"
163 # define STATIC_LIB_EXT "a"
164 # define OBJECT_EXT "o"
165 # define LIBRARIAN "ar"
166 # define LIBRARIAN_OPTS "cr"
167 # define RANLIB "ranlib"
168 # define LINKER_FLAG_PREFIX "-Wl,"
169 # define SHARED_OPTS "-shared"
170 # define MODULE_OPTS "-shared"
171 # define MKDIR_NO_UMASK
172 # define EXE_EXT ".exe"
188 #define LINK_CXX "g++"
192 #define LIBDIR "/usr/local/lib"
195 #define OBJDIR ".libs"
198 #error Unsupported platform: Please add defines for SHELL_CMD etc. for your platform.
210 #define PATH_MAX 1024
214 /* We want to say we are libtool 1.4 for shlibtool compatibility. */
215 #define VERSION "1.4"
217 #define DEBUG(fmt, ...) if(cmd->options.debug) printf(fmt, ## __VA_ARGS__)
218 #define NOTICE(fmt, ...) if(!cmd->options.silent) printf(fmt, ## __VA_ARGS__)
219 #define ERROR(fmt, ...) fprintf(stderr, fmt, ## __VA_ARGS__)
235 OUT_DYNAMIC_LIB_ONLY,
271 count_chars *install;
272 count_chars *dependencies;
278 enum shared_mode shared;
281 enum pic_mode pic_mode;
288 enum output_type output;
291 char const *output_name;
292 char const *fake_output_name;
293 char const *basename;
295 char const *install_path;
296 char const *compiler;
298 count_chars *program_opts;
300 count_chars *arglist;
301 count_chars *tmp_dirs;
302 count_chars *obj_files;
303 count_chars *dep_rpaths;
306 library_name static_name;
307 library_name shared_name;
308 library_name module_name;
310 library_opts static_opts;
311 library_opts shared_opts;
313 char const *version_info;
314 char const *undefined_flag;
318 static void add_rpath(count_chars *cc, char const *path);
321 static void usage(int code)
323 printf("Usage: jlibtool [OPTIONS...] COMMANDS...\n");
324 printf("jlibtool is a replacement for GNU libtool with similar functionality.\n\n");
326 printf(" --config show all configuration variables\n");
327 printf(" --debug enable verbose shell tracing\n");
328 printf(" --dry-run display commands without modifying any files\n");
329 printf(" --help display this help message and exit\n");
330 printf(" --mode=MODE use operational mode MODE (you *must* set mode)\n");
332 printf(" --silent don't print informational messages\n");
333 printf(" --tag=TAG Ignored for libtool compatibility\n");
334 printf(" --version print version information\n");
337 printf(" --shared Build shared libraries when using --mode=link\n");
338 printf(" --export-all Try to export 'def' file on some platforms\n");
340 printf("\nMODE must be one of the following:\n\n");
341 printf(" compile compile a source file into a jlibtool object\n");
342 printf(" execute automatically set library path, then run a program\n");
343 printf(" install install libraries or executables\n");
344 printf(" link create a library or an executable\n");
346 printf("\nMODE-ARGS can be the following:\n\n");
347 printf(" -export-dynamic accepted and ignored\n");
348 printf(" -module create a module when linking\n");
349 printf(" -shared create a shared library when linking\n");
350 printf(" -prefer-pic prefer position-independent-code when compiling\n");
351 printf(" -prefer-non-pic prefer non position-independent-code when compiling\n");
352 printf(" -static create a static library when linking\n");
353 printf(" -no-install link libraries locally\n");
354 printf(" -rpath arg Set install path for shared libraries\n");
355 printf(" -l arg pass '-l arg' to the link stage\n");
356 printf(" -L arg pass '-L arg' to the link stage\n");
357 printf(" -R dir add 'dir' to runtime library search path.\n");
358 printf(" -Zexe accepted and ignored\n");
359 printf(" -avoid-version accepted and ignored\n");
364 #if defined(NEED_SNPRINTF)
365 /* Write at most n characters to the buffer in str, return the
366 * number of chars written or -1 if the buffer would have been
369 * This is portable to any POSIX-compliant system has /dev/null
371 static FILE *f = NULL;
372 static int vsnprintf(char *str, size_t n, char const *fmt, va_list ap)
377 f = fopen("/dev/null","w");
384 setvbuf(f, str, _IOFBF, n);
386 res = vfprintf(f, fmt, ap);
388 if ((res > 0) && (res < n)) {
389 res = vsprintf( str, fmt, ap );
394 static int snprintf(char *str, size_t n, char const *fmt, ...)
400 res = vsnprintf(str, n, fmt, ap);
406 static void *lt_malloc(size_t size)
412 ERROR("Failed allocating %zu bytes, OOM", size);
419 static void lt_const_free(const void *ptr)
423 memcpy(&tmp, &ptr, sizeof(tmp));
427 static void init_count_chars(count_chars *cc)
429 cc->vals = (char const**) lt_malloc(PATH_MAX*sizeof(char*));
433 static count_chars *alloc_countchars(void)
436 out = lt_malloc(sizeof(count_chars));
440 init_count_chars(out);
445 static void clear_count_chars(count_chars *cc)
448 for (i = 0; i < cc->num; i++) {
455 static void push_count_chars(count_chars *cc, char const *newval)
457 cc->vals[cc->num++] = newval;
460 static char const *pop_count_chars(count_chars *cc)
465 return cc->vals[--cc->num];
468 static void insert_count_chars(count_chars *cc, char const *newval, int position)
472 for (i = cc->num; i > position; i--) {
473 cc->vals[i] = cc->vals[i-1];
476 cc->vals[position] = newval;
480 static void append_count_chars(count_chars *cc, count_chars *cctoadd)
483 for (i = 0; i < cctoadd->num; i++) {
484 if (cctoadd->vals[i]) {
485 push_count_chars(cc, cctoadd->vals[i]);
490 static char const *flatten_count_chars(count_chars *cc, char delim)
496 for (i = 0; i < cc->num; i++) {
498 size += strlen(cc->vals[i]) + 1;
505 newval = (char*)lt_malloc(size + 1);
508 for (i = 0; i < cc->num; i++) {
510 strcat(newval, cc->vals[i]);
512 size_t len = strlen(newval);
514 newval[len + 1] = '\0';
522 static char *shell_esc(char const *str)
529 cmd = (char *)lt_malloc(2 * strlen(str) + 3);
530 d = (unsigned char *)cmd;
531 s = (const unsigned char *)str;
542 else if (*s == '\\' || (*s == ' ' && (in_quote % 2))) {
556 static int external_spawn(command_t *cmd, char const *file, char const **argv)
558 file = file; /* -Wunused */
560 if (!cmd->options.silent) {
561 char const **argument = argv;
562 NOTICE("Executing: ");
564 NOTICE("%s ", *argument);
570 if (cmd->options.dry_run) {
573 #if defined(__EMX__) || defined(__MINGW32__)
574 return spawnvp(P_WAIT, argv[0], argv);
580 return execvp(argv[0], (char**)argv);
584 waitpid(pid, &status, 0);
587 * Exited via exit(status)
589 if (WIFEXITED(status)) {
590 return WEXITSTATUS(status);
594 if (WIFSIGNALED(status)) {
595 return WTERMSIG(status);
600 * Some other failure.
608 static int run_command(command_t *cmd, count_chars *cc)
614 char const *spawn_args[4];
617 init_count_chars(&tmpcc);
620 push_count_chars(&tmpcc, cmd->program);
623 append_count_chars(&tmpcc, cmd->program_opts);
625 append_count_chars(&tmpcc, cc);
627 raw = flatten_count_chars(&tmpcc, ' ');
628 command = shell_esc(raw);
630 memcpy(&tmp, &raw, sizeof(tmp));
633 spawn_args[0] = SHELL_CMD;
634 spawn_args[1] = "-c";
635 spawn_args[2] = command;
636 spawn_args[3] = NULL;
637 ret = external_spawn(cmd, spawn_args[0], spawn_args);
645 * print configuration
646 * shlibpath_var is used in configure.
648 #define printc(_x,_y) if (!value || !strcmp(value, _x)) printf(_x "=\"%s\"\n", _y)
650 static void print_config(char const *value)
653 printc("runpath_var", LD_RUN_PATH);
655 #ifdef LD_LIBRARY_PATH
656 printc("shlibpath_var", LD_LIBRARY_PATH);
658 #ifdef LD_LIBRARY_PATH_LOCAL
659 printc("shlocallibpath_var", LD_LIBRARY_PATH_LOCAL);
662 printc("SHELL", SHELL_CMD);
665 printc("objext", OBJECT_EXT);
668 printc("objdir", OBJDIR);
670 #ifdef DYNAMIC_LIB_EXT
671 /* add a '.' prefix because libtool does that. */
672 printc("shrext_cmds", "echo ." DYNAMIC_LIB_EXT);
673 /* add a '.' prefix because libtool does that. */
674 printc("shrext", "." DYNAMIC_LIB_EXT);
677 printc("exeext", EXE_EXT);
679 #ifdef STATIC_LIB_EXT
680 printc("libext", STATIC_LIB_EXT);
683 printc("AR", LIBRARIAN);
685 #ifdef LIBRARIAN_OPTS
686 printc("AR_FLAGS", LIBRARIAN_OPTS);
688 #ifdef LINKER_FLAG_PREFIX
689 printc("wl", LINKER_FLAG_PREFIX);
692 printc("ranlib", RANLIB);
697 * Add a directory to the runtime library search path.
699 static void add_runtime_dir_lib(char const *arg, command_t *cmd)
702 add_rpath(cmd->shared_opts.dependencies, arg);
704 (void) arg; /* -Wunused */
709 static int parse_long_opt(char const *arg, command_t *cmd)
711 char *equal_pos = strchr(arg, '=');
716 strncpy(var, arg, equal_pos - arg);
717 var[equal_pos - arg] = 0;
718 if (strlen(equal_pos + 1) >= sizeof(var)) {
721 strcpy(value, equal_pos + 1);
723 strncpy(var, arg, sizeof(var) - 1);
724 var[sizeof(var) - 1] = '\0';
729 if (strcmp(var, "silent") == 0) {
730 cmd->options.silent = 1;
731 } else if (strcmp(var, "quiet") == 0) {
732 cmd->options.silent = 1;
733 } else if (strcmp(var, "debug") == 0) {
734 cmd->options.debug = 1;
735 } else if (strcmp(var, "mode") == 0) {
736 if (cmd->mode != MODE_UNKNOWN) {
737 ERROR("Cannot set --mode twice\n");
741 if (strcmp(value, "compile") == 0) {
742 cmd->mode = MODE_COMPILE;
743 cmd->output = OUT_OBJECT;
745 } else if (strcmp(value, "link") == 0) {
746 cmd->mode = MODE_LINK;
747 cmd->output = OUT_LIB;
749 } else if (strcmp(value, "install") == 0) {
750 cmd->mode = MODE_INSTALL;
752 } else if (strcmp(value, "execute") == 0) {
753 cmd->mode = MODE_EXECUTE;
756 ERROR("Unknown mode \"%s\"\n", value);
760 } else if (strcmp(var, "shared") == 0) {
761 if ((cmd->mode == MODE_LINK) && (cmd->output == OUT_GENERAL)) {
762 cmd->output = OUT_DYNAMIC_LIB_ONLY;
764 cmd->options.shared = SHARE_SHARED;
766 } else if (strcmp(var, "export-all") == 0) {
767 cmd->options.export_all = 1;
769 } else if (strcmp(var, "dry-run") == 0) {
770 NOTICE("Dry-run mode on!\n");
771 cmd->options.dry_run = 1;
773 } else if (strcmp(var, "version") == 0) {
774 NOTICE("Version " VERSION "\n");
776 } else if (strcmp(var, "help") == 0) {
779 } else if (strcmp(var, "config") == 0) {
790 /* Return 1 if we eat it. */
791 static int parse_short_opt(char const *arg, command_t *cmd)
793 if (strcmp(arg, "export-dynamic") == 0) {
794 cmd->options.export_dynamic = 1;
798 if (strcmp(arg, "module") == 0) {
799 cmd->output = OUT_MODULE;
803 if (strcmp(arg, "shared") == 0) {
804 if (cmd->mode == MODE_LINK) {
805 cmd->output = OUT_DYNAMIC_LIB_ONLY;
807 cmd->options.shared = SHARE_SHARED;
811 if (strcmp(arg, "Zexe") == 0) {
815 if (strcmp(arg, "avoid-version") == 0) {
819 if (strcmp(arg, "prefer-pic") == 0) {
820 cmd->options.pic_mode = PIC_PREFER;
824 if (strcmp(arg, "prefer-non-pic") == 0) {
825 cmd->options.pic_mode = PIC_AVOID;
829 if (strcmp(arg, "static") == 0) {
830 if ((cmd->mode == MODE_LINK) && (cmd->output == OUT_LIB)) {
831 cmd->output = OUT_STATIC_LIB_ONLY;
833 cmd->options.shared = SHARE_STATIC;
837 if (cmd->mode == MODE_LINK) {
838 if (strcmp(arg, "no-install") == 0) {
839 cmd->options.no_install = 1;
842 if (arg[0] == 'L' || arg[0] == 'l') {
845 push_count_chars(cmd->shared_opts.dependencies, arg);
847 } else if (arg[0] == 'R' && arg[1]) {
848 /* -Rdir Add dir to runtime library search path. */
849 add_runtime_dir_lib(&arg[1], cmd);
856 #ifdef TRUNCATE_DLL_NAME
857 static char *truncate_dll_name(char *path)
859 /* Cut DLL name down to 8 characters after removing any mod_ prefix */
860 char *tmppath = strdup(path);
861 char *newname = strrchr(tmppath, '/') + 1;
862 char *ext = strrchr(newname, '.');
871 if (strncmp(newname, "mod_", 4) == 0) {
872 strcpy(newname, newname + 4);
877 strcpy(newname + 8, strchr(newname, '.'));
884 static long safe_strtol(char const *nptr, char const **endptr, int base)
890 rv = strtol(nptr, (char**)endptr, 10);
892 if (errno == ERANGE) {
899 static void safe_mkdir(command_t *cmd, char const *path)
904 old_umask = umask(0);
907 #ifdef MKDIR_NO_UMASK
908 status = mkdir(path);
910 status = mkdir(path, ~old_umask);
912 if ((status < 0) && (errno != EEXIST)) {
913 NOTICE("Warning: mkdir of %s failed\n", path);
917 /** Returns a file's name without the path
919 * @param path to break apart.
920 * @return pointer in path.
922 static char const *file_name(char const *path)
926 name = strrchr(path, '/');
928 name = strrchr(path, '\\'); /* eww windows? */
941 /** Returns a file's name without path or extension
943 * @param path to check
944 * @return pointer in path.
946 static char const *file_name_stripped(char const *path)
951 name = file_name(path);
952 ext = strrchr(name, '.');
957 trimmed = lt_malloc(ext - name + 1);
958 strncpy(trimmed, name, ext - name);
959 trimmed[ext-name] = 0;
968 /* version_info is in the form of MAJOR:MINOR:PATCH */
969 static char const *darwin_dynamic_link_function(char const *version_info)
972 long major, minor, patch;
979 major = safe_strtol(version_info, &version_info, 10);
982 if (version_info[0] == ':') {
986 minor = safe_strtol(version_info, &version_info, 10);
989 if (version_info[0] == ':') {
993 patch = safe_strtol(version_info, &version_info, 10);
999 /* Avoid -dylib_compatibility_version must be greater than zero errors. */
1003 newarg = (char*)lt_malloc(100);
1004 snprintf(newarg, 99,
1005 "-compatibility_version %ld -current_version %ld.%ld",
1006 major, major, minor);
1013 * Add a '.libs/' to the buffer. The caller ensures that
1014 * The buffer is large enough to handle 6 extra characters.
1016 static void add_dotlibs(char *buffer)
1018 char *name = strrchr(buffer, '/');
1022 strcpy(buffer, ".libs/");
1029 memmove(name + 6, name, strlen(name));
1030 memcpy(name, ".libs/", 6);
1033 static char *gen_library_name(char const *name, enum lib_type genlib)
1035 char *newarg, *newext;
1037 newarg = (char *)calloc(strlen(name) + 11, 1);
1039 if (genlib == TYPE_MODULE_LIB && strncmp(name, "lib", 3) == 0) {
1043 if (genlib == TYPE_MODULE_LIB) {
1044 strcpy(newarg, file_name(name));
1047 strcpy(newarg, name);
1050 newext = strrchr(newarg, '.');
1052 ERROR("Library path does not have an extension");
1060 case TYPE_STATIC_LIB:
1061 strcpy(newext, STATIC_LIB_EXT);
1063 case TYPE_DYNAMIC_LIB:
1064 strcpy(newext, DYNAMIC_LIB_EXT);
1066 case TYPE_MODULE_LIB:
1067 strcpy(newext, MODULE_LIB_EXT);
1074 add_dotlibs(newarg);
1079 static char *gen_install_name(char const *name, enum lib_type genlib)
1085 newname = gen_library_name(name, genlib);
1086 if (!newname) return NULL;
1088 /* Check if it exists. If not, return NULL. */
1089 rv = stat(newname, &sb);
1099 static char const *check_object_exists(command_t *cmd, char const *arg, int arglen)
1104 newarg = (char *)lt_malloc(arglen + 10);
1105 memcpy(newarg, arg, arglen);
1107 ext = newarg + arglen;
1109 strcpy(ext, OBJECT_EXT);
1111 DEBUG("Checking (obj): %s\n", newarg);
1112 if (stat(newarg, &sb) == 0) {
1121 /* libdircheck values:
1122 * 0 - no .libs suffix
1125 static char *check_library_exists(command_t *cmd, char const *arg, int pathlen,
1126 int libdircheck, enum lib_type *libtype)
1129 int pass, rv, newpathlen;
1131 newarg = (char *)lt_malloc(strlen(arg) + 10);
1132 strcpy(newarg, arg);
1133 newarg[pathlen] = '\0';
1135 newpathlen = pathlen;
1137 add_dotlibs(newarg);
1138 newpathlen += sizeof(".libs/") - 1;
1141 strcpy(newarg + newpathlen, arg + pathlen);
1142 ext = strrchr(newarg, '.');
1144 ERROR("Error: Library path does not have an extension");
1158 if (cmd->options.pic_mode != PIC_AVOID &&
1159 cmd->options.shared != SHARE_STATIC) {
1160 strcpy(ext, DYNAMIC_LIB_EXT);
1161 *libtype = TYPE_DYNAMIC_LIB;
1167 strcpy(ext, STATIC_LIB_EXT);
1168 *libtype = TYPE_STATIC_LIB;
1171 strcpy(ext, MODULE_LIB_EXT);
1172 *libtype = TYPE_MODULE_LIB;
1175 strcpy(ext, OBJECT_EXT);
1176 *libtype = TYPE_OBJECT;
1179 *libtype = TYPE_UKNOWN;
1183 DEBUG("Checking (lib): %s\n", newarg);
1184 rv = stat(newarg, &sb);
1186 while (rv != 0 && ++pass < 4);
1197 static char * load_install_path(char const *arg)
1207 path = lt_malloc(PATH_MAX);
1209 fgets(path, PATH_MAX, f);
1212 if (path[strlen(path)-1] == '\n') {
1213 path[strlen(path)-1] = '\0';
1216 /* Check that we have an absolute path.
1217 * Otherwise the file could be a GNU libtool file.
1219 if (path[0] != '/') {
1227 static char *load_noinstall_path(char const *arg, int pathlen)
1229 char *newarg, *expanded_path;
1232 newarg = (char *)lt_malloc(strlen(arg) + 10);
1233 strcpy(newarg, arg);
1234 newarg[pathlen] = 0;
1236 newpathlen = pathlen;
1237 strcat(newarg, ".libs");
1238 newpathlen += sizeof(".libs") - 1;
1239 newarg[newpathlen] = 0;
1242 expanded_path = lt_malloc(PATH_MAX);
1243 expanded_path = realpath(newarg, expanded_path);
1244 /* Uh, oh. There was an error. Fall back on our first guess. */
1245 if (!expanded_path) {
1246 expanded_path = newarg;
1249 /* We might get ../ or something goofy. Oh, well. */
1250 expanded_path = newarg;
1253 return expanded_path;
1256 static void add_dynamic_link_opts(command_t *cmd, count_chars *args)
1258 #ifdef DYNAMIC_LINK_OPTS
1259 if (cmd->options.pic_mode != PIC_AVOID) {
1260 DEBUG("Adding linker opt: %s\n", DYNAMIC_LINK_OPTS);
1262 push_count_chars(args, DYNAMIC_LINK_OPTS);
1263 if (cmd->undefined_flag) {
1264 push_count_chars(args, "-undefined");
1265 #if defined(__APPLE__)
1266 /* -undefined dynamic_lookup is used by the bundled Python in
1267 * 10.4, but if we don't set MACOSX_DEPLOYMENT_TARGET to 10.3+,
1268 * we'll get a linker error if we pass this flag.
1270 if (strcasecmp(cmd->undefined_flag, "dynamic_lookup") == 0) {
1271 insert_count_chars(cmd->program_opts, "MACOSX_DEPLOYMENT_TARGET=10.3", 0);
1274 push_count_chars(args, cmd->undefined_flag);
1277 #ifdef DYNAMIC_LINK_UNDEFINED
1278 DEBUG("Adding linker opt: %s\n", DYNAMIC_LINK_UNDEFINED);
1280 push_count_chars(args, DYNAMIC_LINK_UNDEFINED);
1287 /* Read the final install location and add it to runtime library search path. */
1289 static void add_rpath(count_chars *cc, char const *path)
1294 #ifdef LINKER_FLAG_PREFIX
1295 size = strlen(LINKER_FLAG_PREFIX);
1297 size = size + strlen(path) + strlen(RPATH) + 2;
1298 tmp = lt_malloc(size);
1300 #ifdef LINKER_FLAG_PREFIX
1301 strcpy(tmp, LINKER_FLAG_PREFIX);
1306 #ifndef LINKER_FLAG_NO_EQUALS
1311 push_count_chars(cc, tmp);
1314 static void add_rpath_file(count_chars *cc, char const *arg)
1318 path = load_install_path(arg);
1320 add_rpath(cc, path);
1321 lt_const_free(path);
1325 static void add_rpath_noinstall(count_chars *cc, char const *arg, int pathlen)
1329 path = load_noinstall_path(arg, pathlen);
1331 add_rpath(cc, path);
1332 lt_const_free(path);
1337 #ifdef DYNAMIC_LINK_NO_INSTALL
1338 static void add_dylink_noinstall(count_chars *cc, char const *arg, int pathlen,
1341 char const *install_path, *current_path, *name;
1343 int i_p_len, c_p_len, name_len, dyext_len, cur_len;
1345 install_path = load_install_path(arg);
1346 current_path = load_noinstall_path(arg, pathlen);
1348 if (!install_path || !current_path) {
1352 push_count_chars(cc, DYNAMIC_LINK_NO_INSTALL);
1354 i_p_len = strlen(install_path);
1355 c_p_len = strlen(current_path);
1358 name_len = extlen-pathlen;
1359 dyext_len = sizeof(DYNAMIC_LIB_EXT) - 1;
1361 /* No, we need to replace the extension. */
1362 exp_argument = (char *)lt_malloc(i_p_len + c_p_len + (name_len*2) +
1366 strcpy(exp_argument, install_path);
1368 exp_argument[cur_len++] = '/';
1369 strncpy(exp_argument+cur_len, name, extlen-pathlen);
1370 cur_len += name_len;
1371 strcpy(exp_argument+cur_len, DYNAMIC_LIB_EXT);
1372 cur_len += dyext_len;
1373 exp_argument[cur_len++] = ':';
1374 strcpy(exp_argument+cur_len, current_path);
1376 exp_argument[cur_len++] = '/';
1377 strncpy(exp_argument+cur_len, name, extlen-pathlen);
1378 cur_len += name_len;
1379 strcpy(exp_argument+cur_len, DYNAMIC_LIB_EXT);
1380 cur_len += dyext_len;
1382 push_count_chars(cc, exp_argument);
1387 /* use -L -llibname to allow to use installed libraries */
1388 static void add_minus_l(count_chars *cc, char const *arg)
1391 char *name = strrchr(arg, '/');
1392 char *file = strrchr(arg, '.');
1394 if ((name != NULL) && (file != NULL) &&
1395 (strstr(name, "lib") == (name + 1))) {
1400 push_count_chars(cc, "-L");
1401 push_count_chars(cc, arg);
1402 /* we need one argument like -lapr-1 */
1403 newarg = lt_malloc(strlen(file) + 3);
1404 strcpy(newarg, "-l");
1405 strcat(newarg, file);
1406 push_count_chars(cc, newarg);
1408 push_count_chars(cc, arg);
1414 static void add_linker_flag_prefix(count_chars *cc, char const *arg)
1416 #ifndef LINKER_FLAG_PREFIX
1417 push_count_chars(cc, arg);
1420 newarg = (char*)lt_malloc(strlen(arg) + sizeof(LINKER_FLAG_PREFIX) + 1);
1421 strcpy(newarg, LINKER_FLAG_PREFIX);
1422 strcat(newarg, arg);
1423 push_count_chars(cc, newarg);
1428 static int explode_static_lib(command_t *cmd, char const *lib)
1430 count_chars tmpdir_cc, libname_cc;
1431 char const *tmpdir, *libname;
1432 char savewd[PATH_MAX];
1435 struct dirent *entry;
1436 char const *lib_args[4];
1439 if (cmd->options.dry_run) {
1443 name = file_name(lib);
1445 init_count_chars(&tmpdir_cc);
1446 push_count_chars(&tmpdir_cc, ".libs/");
1447 push_count_chars(&tmpdir_cc, name);
1448 push_count_chars(&tmpdir_cc, ".exploded/");
1449 tmpdir = flatten_count_chars(&tmpdir_cc, 0);
1451 NOTICE("Making: %s\n", tmpdir);
1453 safe_mkdir(cmd, tmpdir);
1455 push_count_chars(cmd->tmp_dirs, tmpdir);
1457 getcwd(savewd, sizeof(savewd));
1459 if (chdir(tmpdir) != 0) {
1460 NOTICE("Warning: could not explode %s\n", lib);
1465 if (lib[0] == '/') {
1469 init_count_chars(&libname_cc);
1470 push_count_chars(&libname_cc, "../../");
1471 push_count_chars(&libname_cc, lib);
1472 libname = flatten_count_chars(&libname_cc, 0);
1475 lib_args[0] = LIBRARIAN;
1477 lib_args[2] = libname;
1480 external_spawn(cmd, LIBRARIAN, lib_args);
1483 dir = opendir(tmpdir);
1485 while ((entry = readdir(dir)) != NULL) {
1486 #if defined(__APPLE__) && defined(RANLIB)
1487 /* Apple inserts __.SYMDEF which isn't needed.
1488 * Leopard (10.5+) can also add '__.SYMDEF SORTED' which isn't
1489 * much fun either. Just skip them.
1491 if (strstr(entry->d_name, "__.SYMDEF") != NULL) {
1495 if (entry->d_name[0] != '.') {
1496 push_count_chars(&tmpdir_cc, entry->d_name);
1497 name = flatten_count_chars(&tmpdir_cc, 0);
1499 DEBUG("Adding object: %s\n", name);
1500 push_count_chars(cmd->obj_files, name);
1501 pop_count_chars(&tmpdir_cc);
1509 static int parse_input_file_name(char const *arg, command_t *cmd)
1511 char const *ext = strrchr(arg, '.');
1514 enum lib_type libtype;
1517 /* Can't guess the extension */
1523 name = file_name(arg);
1524 pathlen = name - arg;
1527 * Were linking and have an archived object or object file
1528 * push it onto the list of object files which'll get used
1529 * to create the input files list for the linker.
1531 * We assume that these are outside of the project were building,
1532 * as there's no reason to create .a files as part of the build
1535 if (!strcmp(ext, STATIC_LIB_EXT) && (cmd->mode == MODE_LINK)) {
1538 if (!stat(arg, &sb)) {
1539 DEBUG("Adding object: %s\n", arg);
1541 push_count_chars(cmd->obj_files, arg);
1548 * More object files, if were linking they get set as input
1551 if (!strcmp(ext, "lo") || !strcmp(ext, OBJECT_EXT)) {
1552 newarg = check_object_exists(cmd, arg, ext - arg);
1554 ERROR("Can not find suitable object file for %s\n", arg);
1558 if (cmd->mode == MODE_LINK) {
1559 DEBUG("Adding object: %s\n", newarg);
1561 push_count_chars(cmd->obj_files, newarg);
1563 push_count_chars(cmd->arglist, newarg);
1569 if (!strcmp(ext, "la")) {
1570 switch (cmd->mode) {
1572 /* Try the .libs dir first! */
1573 newarg = check_library_exists(cmd, arg, pathlen, 1, &libtype);
1575 /* Try the normal dir next. */
1576 newarg = check_library_exists(cmd, arg, pathlen, 0, &libtype);
1578 ERROR("Can not find suitable library for %s\n", arg);
1583 /* It is not ok to just add the file: a library may added with:
1584 1 - -L path library_name. (For *.so in Linux).
1588 if (libtype == TYPE_DYNAMIC_LIB) {
1589 add_minus_l(cmd->shared_opts.dependencies, newarg);
1590 } else if (cmd->output == OUT_LIB &&
1591 libtype == TYPE_STATIC_LIB) {
1592 explode_static_lib(cmd, newarg);
1594 push_count_chars(cmd->shared_opts.dependencies, newarg);
1597 if (cmd->output == OUT_LIB && libtype == TYPE_STATIC_LIB) {
1598 explode_static_lib(cmd, newarg);
1601 push_count_chars(cmd->shared_opts.dependencies, newarg);
1604 if (libtype == TYPE_DYNAMIC_LIB) {
1605 if (cmd->options.no_install) {
1607 add_rpath_noinstall(cmd->shared_opts.dependencies,
1613 add_rpath_file(cmd->shared_opts.dependencies, arg);
1620 * If we've already recorded a library to
1621 * install, we're most likely getting the .la
1622 * file that we want to install as.
1624 * The problem is that we need to add it as the
1625 * directory, not the .la file itself.
1626 * Otherwise, we'll do odd things.
1628 if (cmd->output == OUT_LIB) {
1632 tmp[pathlen] = '\0';
1633 push_count_chars(cmd->arglist, tmp);
1636 cmd->output = OUT_LIB;
1637 cmd->output_name = arg;
1638 cmd->static_name.install = gen_install_name(arg, 0);
1639 cmd->shared_name.install = gen_install_name(arg, 1);
1640 cmd->module_name.install = gen_install_name(arg, 2);
1642 if (!cmd->static_name.install &&
1643 !cmd->shared_name.install &&
1644 !cmd->module_name.install) {
1645 ERROR("Files to install do not exist\n");
1658 if (!strcmp(ext, "c")) {
1659 /* If we don't already have an idea what our output name will be. */
1660 if (!cmd->basename) {
1661 char *tmp = lt_malloc(strlen(arg) + 4);
1663 strcpy(strrchr(tmp, '.') + 1, "lo");
1665 cmd->basename = tmp;
1667 cmd->fake_output_name = strrchr(cmd->basename, '/');
1668 if (cmd->fake_output_name) {
1669 cmd->fake_output_name++;
1671 cmd->fake_output_name = cmd->basename;
1679 static int parse_output_file_name(char const *arg, command_t *cmd)
1683 char *newarg = NULL;
1686 cmd->fake_output_name = arg;
1688 name = file_name(arg);
1689 ext = strrchr(name, '.');
1692 if (!ext || strcmp(ext, EXE_EXT) == 0) {
1696 cmd->basename = arg;
1697 cmd->output = OUT_PROGRAM;
1698 #if defined(_OSD_POSIX)
1699 cmd->options.pic_mode = PIC_AVOID;
1701 newarg = (char *)lt_malloc(strlen(arg) + 5);
1702 strcpy(newarg, arg);
1705 strcat(newarg, EXE_EXT);
1708 cmd->output_name = newarg;
1713 pathlen = name - arg;
1715 if (strcmp(ext, "la") == 0) {
1716 assert(cmd->mode == MODE_LINK);
1718 cmd->basename = arg;
1719 cmd->static_name.normal = gen_library_name(arg, TYPE_STATIC_LIB);
1720 cmd->shared_name.normal = gen_library_name(arg, TYPE_DYNAMIC_LIB);
1721 cmd->module_name.normal = gen_library_name(arg, TYPE_MODULE_LIB);
1722 cmd->static_name.install = gen_install_name(arg, TYPE_STATIC_LIB);
1723 cmd->shared_name.install = gen_install_name(arg, TYPE_DYNAMIC_LIB);
1724 cmd->module_name.install = gen_install_name(arg, TYPE_MODULE_LIB);
1726 if (!cmd->options.dry_run) {
1729 newname = lt_malloc(strlen(cmd->static_name.normal) + 1);
1731 strcpy(newname, cmd->static_name.normal);
1732 newext = strrchr(newname, '/');
1734 /* Check first to see if the dir already exists! */
1735 safe_mkdir(cmd, ".libs");
1738 safe_mkdir(cmd, newname);
1743 #ifdef TRUNCATE_DLL_NAME
1745 arg = truncate_dll_name(arg);
1749 cmd->output_name = arg;
1753 if (strcmp(ext, STATIC_LIB_EXT) == 0) {
1754 assert(cmd->mode == MODE_LINK);
1756 cmd->basename = arg;
1757 cmd->options.shared = SHARE_STATIC;
1758 cmd->output = OUT_STATIC_LIB_ONLY;
1759 cmd->static_name.normal = gen_library_name(arg, TYPE_STATIC_LIB);
1760 cmd->static_name.install = gen_install_name(arg, TYPE_STATIC_LIB);
1762 if (!cmd->options.dry_run) {
1765 newname = lt_malloc(strlen(cmd->static_name.normal) + 1);
1767 strcpy(newname, cmd->static_name.normal);
1768 newext = strrchr(newname, '/');
1770 /* Check first to see if the dir already exists! */
1771 safe_mkdir(cmd, ".libs");
1774 safe_mkdir(cmd, newname);
1779 cmd->output_name = arg;
1783 if (strcmp(ext, DYNAMIC_LIB_EXT) == 0) {
1784 assert(cmd->mode == MODE_LINK);
1786 cmd->basename = arg;
1787 cmd->options.shared = SHARE_SHARED;
1788 cmd->output = OUT_DYNAMIC_LIB_ONLY;
1789 cmd->shared_name.normal = gen_library_name(arg, TYPE_DYNAMIC_LIB);
1790 cmd->module_name.normal = gen_library_name(arg, TYPE_MODULE_LIB);
1791 cmd->shared_name.install = gen_install_name(arg, TYPE_DYNAMIC_LIB);
1792 cmd->module_name.install = gen_install_name(arg, TYPE_MODULE_LIB);
1794 if (!cmd->options.dry_run) {
1797 newname = lt_malloc(strlen(cmd->shared_name.normal) + 1);
1799 strcpy(newname, cmd->shared_name.normal);
1800 newext = strrchr(newname, '/');
1802 /* Check first to see if the dir already exists! */
1803 safe_mkdir(cmd, ".libs");
1806 safe_mkdir(cmd, newname);
1811 cmd->output_name = arg;
1815 if (strcmp(ext, "lo") == 0) {
1817 cmd->basename = arg;
1818 cmd->output = OUT_OBJECT;
1819 newarg = (char *)lt_malloc(strlen(arg) + 2);
1820 strcpy(newarg, arg);
1821 newext = strrchr(newarg, '.') + 1;
1822 strcpy(newext, OBJECT_EXT);
1823 cmd->output_name = newarg;
1827 if (strcmp(ext, DYNAMIC_LIB_EXT) == 0) {
1828 ERROR("Please build libraries with .la target, not ."
1829 DYNAMIC_LIB_EXT "\n");
1834 if (strcmp(ext, STATIC_LIB_EXT) == 0) {
1835 ERROR("Please build libraries with .la target, not ."
1836 STATIC_LIB_EXT "\n");
1844 static char const *automode(char const *arg, command_t *cmd)
1846 if (cmd->mode != MODE_UNKNOWN) return arg;
1848 if (!strcmp(arg, "CC") ||
1849 !strcmp(arg, "CXX")) {
1850 DEBUG("Now in compile mode, guessed from: %s\n", arg);
1852 cmd->mode = MODE_COMPILE;
1854 } else if (!strcmp(arg, "LINK") ||
1855 !strcmp(arg, "LINK.c") ||
1856 !strcmp(arg, "LINK.cxx")) {
1857 DEBUG("Now in linker mode, guessed from: %s\n", arg);
1859 cmd->mode = MODE_LINK;
1867 static void generate_def_file(command_t *cmd)
1869 char def_file[1024];
1870 char implib_file[1024];
1873 char *export_args[1024];
1874 int num_export_args = 0;
1879 if (cmd->output_name) {
1880 strcpy(def_file, cmd->output_name);
1881 strcat(def_file, ".def");
1882 hDef = fopen(def_file, "w");
1885 fprintf(hDef, "LIBRARY '%s' INITINSTANCE\n", file_name_stripped(cmd->output_name));
1886 fprintf(hDef, "DATA NONSHARED\n");
1887 fprintf(hDef, "EXPORTS\n");
1890 for (a = 0; a < cmd->num_obj_files; a++) {
1891 cmd_size += strlen(cmd->obj_files[a]) + 1;
1894 cmd_size += strlen(GEN_EXPORTS) + strlen(def_file) + 3;
1895 cmd = (char *)lt_malloc(cmd_size);
1896 strcpy(cmd, GEN_EXPORTS);
1898 for (a=0; a < cmd->num_obj_files; a++) {
1900 strcat(cmd, cmd->obj_files[a] );
1904 strcat(cmd, def_file);
1906 export_args[num_export_args++] = SHELL_CMD;
1907 export_args[num_export_args++] = "-c";
1908 export_args[num_export_args++] = cmd;
1909 export_args[num_export_args++] = NULL;
1910 external_spawn(cmd, export_args[0], (char const**)export_args);
1911 cmd->arglist[cmd->num_args++] = strdup(def_file);
1913 /* Now make an import library for the dll */
1914 num_export_args = 0;
1915 export_args[num_export_args++] = DEF2IMPLIB_CMD;
1916 export_args[num_export_args++] = "-o";
1918 strcpy(implib_file, ".libs/");
1919 strcat(implib_file, cmd->basename);
1920 ext = strrchr(implib_file, '.');
1926 strcat(implib_file, ".");
1927 strcat(implib_file, STATIC_LIB_EXT);
1929 export_args[num_export_args++] = implib_file;
1930 export_args[num_export_args++] = def_file;
1931 export_args[num_export_args++] = NULL;
1932 external_spawn(cmd, export_args[0], (char const**)export_args);
1940 static char const* expand_path(char const *relpath)
1942 char foo[PATH_MAX], *newpath;
1944 getcwd(foo, PATH_MAX-1);
1945 newpath = (char*)lt_malloc(strlen(foo)+strlen(relpath)+2);
1946 strcpy(newpath, foo);
1947 strcat(newpath, "/");
1948 strcat(newpath, relpath);
1953 static void link_fixup(command_t *cmd)
1955 /* If we were passed an -rpath directive, we need to build
1956 * shared objects too. Otherwise, we should only create static
1959 if (!cmd->install_path && (cmd->output == OUT_DYNAMIC_LIB_ONLY ||
1960 cmd->output == OUT_MODULE || cmd->output == OUT_LIB)) {
1961 if (cmd->options.shared == SHARE_SHARED) {
1962 cmd->install_path = LIBDIR;
1966 if (cmd->output == OUT_DYNAMIC_LIB_ONLY ||
1967 cmd->output == OUT_MODULE ||
1968 cmd->output == OUT_LIB) {
1970 push_count_chars(cmd->shared_opts.normal, "-o");
1971 if (cmd->output == OUT_MODULE) {
1972 push_count_chars(cmd->shared_opts.normal, cmd->module_name.normal);
1974 push_count_chars(cmd->shared_opts.normal, cmd->shared_name.normal);
1975 #ifdef DYNAMIC_INSTALL_NAME
1976 push_count_chars(cmd->shared_opts.normal, DYNAMIC_INSTALL_NAME);
1978 if (!cmd->install_path) {
1979 ERROR("Installation mode requires -rpath\n");
1984 char *tmp = lt_malloc(PATH_MAX);
1985 strcpy(tmp, cmd->install_path);
1987 if (cmd->shared_name.install) {
1988 strcat(tmp, strrchr(cmd->shared_name.install, '/'));
1990 strcat(tmp, strrchr(cmd->shared_name.normal, '/'));
1993 push_count_chars(cmd->shared_opts.normal, tmp);
1998 append_count_chars(cmd->shared_opts.normal, cmd->obj_files);
1999 append_count_chars(cmd->shared_opts.normal, cmd->shared_opts.dependencies);
2001 if (cmd->options.export_all) {
2003 generate_def_file(cmd);
2008 if (cmd->output == OUT_LIB || cmd->output == OUT_STATIC_LIB_ONLY) {
2009 push_count_chars(cmd->static_opts.normal, "-o");
2010 push_count_chars(cmd->static_opts.normal, cmd->output_name);
2013 if (cmd->output == OUT_PROGRAM) {
2014 if (cmd->output_name) {
2015 push_count_chars(cmd->arglist, "-o");
2016 push_count_chars(cmd->arglist, cmd->output_name);
2017 append_count_chars(cmd->arglist, cmd->obj_files);
2018 append_count_chars(cmd->arglist, cmd->shared_opts.dependencies);
2019 add_dynamic_link_opts(cmd, cmd->arglist);
2024 static void post_parse_fixup(command_t *cmd)
2026 switch (cmd->mode) {
2029 if (cmd->options.pic_mode != PIC_AVOID) {
2030 push_count_chars(cmd->arglist, PIC_FLAG);
2033 if (cmd->output_name) {
2034 push_count_chars(cmd->arglist, "-o");
2035 push_count_chars(cmd->arglist, cmd->output_name);
2042 if (cmd->output == OUT_LIB) {
2050 if (cmd->output == OUT_OBJECT ||
2051 cmd->output == OUT_PROGRAM ||
2052 cmd->output == OUT_LIB ||
2053 cmd->output == OUT_DYNAMIC_LIB_ONLY) {
2054 push_count_chars(cmd->arglist, "-Zomf");
2058 if (cmd->options.shared &&
2059 (cmd->output == OUT_OBJECT ||
2060 cmd->output == OUT_LIB ||
2061 cmd->output == OUT_DYNAMIC_LIB_ONLY)) {
2063 push_count_chars(cmd->arglist, SHARE_SW);
2068 static int run_mode(command_t *cmd)
2071 count_chars *cctemp;
2073 cctemp = (count_chars*)lt_malloc(sizeof(count_chars));
2074 init_count_chars(cctemp);
2076 switch (cmd->mode) {
2078 rv = run_command(cmd, cmd->arglist);
2079 if (rv) goto finish;
2082 /* Well, we'll assume it's a file going to a directory... */
2083 /* For brain-dead install-sh based scripts, we have to repeat
2084 * the command N-times. install-sh should die.
2086 if (!cmd->output_name) {
2087 rv = run_command(cmd, cmd->arglist);
2088 if (rv) goto finish;
2090 if (cmd->output_name) {
2091 append_count_chars(cctemp, cmd->arglist);
2092 insert_count_chars(cctemp,
2095 rv = run_command(cmd, cctemp);
2096 if (rv) goto finish;
2097 clear_count_chars(cctemp);
2099 if (cmd->static_name.install) {
2100 append_count_chars(cctemp, cmd->arglist);
2101 insert_count_chars(cctemp,
2102 cmd->static_name.install,
2104 rv = run_command(cmd, cctemp);
2105 if (rv) goto finish;
2106 #if defined(__APPLE__) && defined(RANLIB)
2107 /* From the Apple libtool(1) manpage on Tiger/10.4:
2109 * With the way libraries used to be created, errors were possible
2110 * if the library was modified with ar(1) and the table of
2111 * contents was not updated by rerunning ranlib(1). Thus the
2112 * link editor, ld, warns when the modification date of a library
2113 * is more recent than the creation date of its table of
2114 * contents. Unfortunately, this means that you get the warning
2115 * even if you only copy the library.
2118 * This means that when we install the static archive, we need to
2119 * rerun ranlib afterwards.
2121 char const *lib_args[3], *static_lib_name;
2127 len1 = strlen(cmd->arglist->vals[cmd->arglist->num - 1]);
2129 static_lib_name = file_name(cmd->static_name.install);
2130 len2 = strlen(static_lib_name);
2132 tmp = lt_malloc(len1 + len2 + 2);
2134 snprintf(tmp, len1 + len2 + 2, "%s/%s",
2135 cmd->arglist->vals[cmd->arglist->num - 1],
2138 lib_args[0] = RANLIB;
2142 external_spawn(cmd, RANLIB, lib_args);
2147 clear_count_chars(cctemp);
2149 if (cmd->shared_name.install) {
2150 append_count_chars(cctemp, cmd->arglist);
2151 insert_count_chars(cctemp, cmd->shared_name.install,
2153 rv = run_command(cmd, cctemp);
2154 if (rv) goto finish;
2155 clear_count_chars(cctemp);
2157 if (cmd->module_name.install) {
2158 append_count_chars(cctemp, cmd->arglist);
2159 insert_count_chars(cctemp, cmd->module_name.install,
2161 rv = run_command(cmd, cctemp);
2162 if (rv) goto finish;
2163 clear_count_chars(cctemp);
2167 if (cmd->output == OUT_STATIC_LIB_ONLY ||
2168 cmd->output == OUT_LIB) {
2170 char const *lib_args[3];
2172 /* Removes compiler! */
2173 cmd->program = LIBRARIAN;
2174 push_count_chars(cmd->program_opts, LIBRARIAN_OPTS);
2175 push_count_chars(cmd->program_opts, cmd->static_name.normal);
2177 rv = run_command(cmd, cmd->obj_files);
2178 if (rv) goto finish;
2181 lib_args[0] = RANLIB;
2182 lib_args[1] = cmd->static_name.normal;
2184 external_spawn(cmd, RANLIB, lib_args);
2188 if (cmd->output == OUT_DYNAMIC_LIB_ONLY ||
2189 cmd->output == OUT_MODULE ||
2190 cmd->output == OUT_LIB) {
2191 cmd->program = NULL;
2192 clear_count_chars(cmd->program_opts);
2194 append_count_chars(cmd->program_opts, cmd->arglist);
2195 if (cmd->output == OUT_MODULE) {
2197 push_count_chars(cmd->program_opts, MODULE_OPTS);
2201 push_count_chars(cmd->program_opts, SHARED_OPTS);
2203 #ifdef dynamic_link_version_func
2204 push_count_chars(cmd->program_opts,
2205 dynamic_link_version_func(cmd->version_info));
2208 add_dynamic_link_opts(cmd, cmd->program_opts);
2210 rv = run_command(cmd, cmd->shared_opts.normal);
2211 if (rv) goto finish;
2213 if (cmd->output == OUT_PROGRAM) {
2214 rv = run_command(cmd, cmd->arglist);
2215 if (rv) goto finish;
2220 char *l, libpath[PATH_MAX];
2222 if (strlen(cmd->arglist->vals[0]) >= PATH_MAX) {
2223 ERROR("Libpath too long no buffer space");
2229 strcpy(libpath, cmd->arglist->vals[0]);
2230 add_dotlibs(libpath);
2231 l = strrchr(libpath, '/');
2232 if (!l) l = strrchr(libpath, '\\');
2240 l = "./build/lib/.libs";
2241 setenv(LD_LIBRARY_PATH_LOCAL, l, 1);
2242 rv = run_command(cmd, cmd->arglist);
2243 if (rv) goto finish;
2257 static void cleanup_tmp_dir(char const *dirname)
2260 struct dirent *entry;
2261 char fullname[1024];
2263 dir = opendir(dirname);
2268 if ((strlen(dirname) + 1 + sizeof(entry->d_name)) >= sizeof(fullname)) {
2269 ERROR("Dirname too long, out of buffer space");
2271 (void) closedir(dir);
2275 while ((entry = readdir(dir)) != NULL) {
2276 if (entry->d_name[0] != '.') {
2277 strcpy(fullname, dirname);
2278 strcat(fullname, "/");
2279 strcat(fullname, entry->d_name);
2280 (void) remove(fullname);
2286 (void) closedir(dir);
2289 static void cleanup_tmp_dirs(command_t *cmd)
2293 for (d = 0; d < cmd->tmp_dirs->num; d++) {
2294 cleanup_tmp_dir(cmd->tmp_dirs->vals[d]);
2298 static int ensure_fake_uptodate(command_t *cmd)
2300 /* FIXME: could do the stat/touch here, but nah... */
2301 char const *touch_args[3];
2303 if (cmd->mode == MODE_INSTALL) {
2306 if (!cmd->fake_output_name) {
2310 touch_args[0] = "touch";
2311 touch_args[1] = cmd->fake_output_name;
2312 touch_args[2] = NULL;
2313 return external_spawn(cmd, "touch", touch_args);
2316 /* Store the install path in the *.la file */
2317 static int add_for_runtime(command_t *cmd)
2319 if (cmd->mode == MODE_INSTALL) {
2322 if (cmd->output == OUT_DYNAMIC_LIB_ONLY ||
2323 cmd->output == OUT_LIB) {
2324 FILE *f=fopen(cmd->fake_output_name,"w");
2328 fprintf(f,"%s\n", cmd->install_path);
2332 return(ensure_fake_uptodate(cmd));
2336 static void parse_args(int argc, char *argv[], command_t *cmd)
2339 char const *arg, *base;
2343 * We now take a major step past libtool.
2345 * IF there's no "--mode=...", AND we recognise
2346 * the binary as a "special" name, THEN replace it
2347 * with the correct one, and set the correct mode.
2349 * For example if were called 'CC' then we know we should
2350 * probably be compiling stuff.
2352 base = file_name(argv[0]);
2353 arg = automode(base, cmd);
2355 push_count_chars(cmd->arglist, arg);
2357 assert(cmd->mode != MODE_UNKNOWN);
2361 * We first pass over the command-line arguments looking for
2362 * "--mode", etc. If so, then use the libtool compatibility
2363 * method for building the software. Otherwise, auto-detect it
2364 * via "-o" and the extensions.
2367 if (cmd->mode == MODE_UNKNOWN) for (a = 1; a < argc; a++) {
2370 if (strncmp(arg, "--mode=", 7) == 0) {
2376 * Stop if we get another magic method
2379 ((strncmp(arg, "LINK", 4) == 0) ||
2380 (strcmp(arg, "CC") == 0) ||
2381 (strcmp(arg, "CXX") == 0))) {
2386 if (strncmp(arg, "-o", 2) == 0) {
2392 * There were no magic args or an explicit --mode= but we did
2393 * find an output file, so guess what mode were meant to be in
2394 * from its extension.
2397 arg = strrchr(base, '.');
2399 cmd->mode = MODE_LINK;
2400 push_count_chars(cmd->arglist, LINK_C);
2403 else if (strcmp(arg, EXE_EXT) == 0) {
2404 cmd->mode = MODE_LINK;
2405 push_count_chars(cmd->arglist, LINK_C);
2408 else if (strcmp(arg + 1, DYNAMIC_LIB_EXT) == 0) {
2409 cmd->mode = MODE_LINK;
2410 push_count_chars(cmd->arglist, LINK_C);
2412 else if (strcmp(arg + 1, STATIC_LIB_EXT) == 0) {
2413 cmd->mode = MODE_LINK;
2414 push_count_chars(cmd->arglist, LINK_C);
2416 else if (strcmp(arg + 1, "la") == 0) {
2417 cmd->mode = MODE_LINK;
2418 push_count_chars(cmd->arglist, LINK_C);
2420 else if ((strcmp(arg + 1, "lo") == 0) ||
2421 (strcmp(arg + 1, "o") == 0)) {
2422 cmd->mode = MODE_COMPILE;
2423 push_count_chars(cmd->arglist, CC);
2427 for (a = 1; a < argc; a++) {
2431 if (cmd->mode == MODE_EXECUTE) {
2432 push_count_chars(cmd->arglist, arg);
2436 if (arg[0] == '-') {
2438 * Double dashed (long) single dash (short)
2440 arg_used = (arg[1] == '-') ?
2441 parse_long_opt(arg + 2, cmd) :
2442 parse_short_opt(arg + 1, cmd);
2444 if (arg_used) continue;
2447 * Ignore all options after the '--execute'
2449 if (cmd->mode == MODE_EXECUTE) continue;
2452 * We haven't done anything with it yet, but
2453 * there are still some arg/value pairs.
2455 * Try some of the more complicated short opts...
2459 * We found an output file!
2461 if ((arg[1] == 'o') && (arg[2] == '\0')) {
2463 arg_used = parse_output_file_name(arg,
2466 * -MT literal dependency
2468 } else if (!strcmp(arg + 1, "MT")) {
2469 DEBUG("Adding: %s\n", arg);
2471 push_count_chars(cmd->arglist, arg);
2474 NOTICE(" %s\n", arg);
2476 push_count_chars(cmd->arglist, arg);
2479 * Runtime library search path
2481 } else if (!strcmp(arg + 1, "rpath")) {
2482 /* Aha, we should try to link both! */
2483 cmd->install_path = argv[++a];
2486 } else if (!strcmp(arg + 1, "release")) {
2487 /* Store for later deciphering */
2488 cmd->version_info = argv[++a];
2491 } else if (!strcmp(arg + 1, "version-info")) {
2492 /* Store for later deciphering */
2493 cmd->version_info = argv[++a];
2496 } else if (!strcmp(arg + 1,
2497 "export-symbols-regex")) {
2498 /* Skip the argument. */
2502 } else if (!strcmp(arg + 1, "undefined")) {
2503 cmd->undefined_flag = argv[++a];
2506 * Add dir to runtime library search path.
2508 } else if ((arg[1] == 'R') && !arg[2]) {
2510 add_runtime_dir_lib(argv[++a], cmd);
2515 * Ok.. the argument doesn't begin with a dash
2516 * maybe it's an input file.
2518 * Check its extension to see if it's a known input
2519 * file and verify it exists.
2522 arg_used = parse_input_file_name(arg, cmd);
2526 * If we still don't have a run mode, look for a magic
2527 * program name CC, LINK, or whatever. Then replace that
2528 * with the name of the real program we want to run.
2531 if ((cmd->arglist->num == 0) &&
2532 (cmd->mode == MODE_UNKNOWN)) {
2533 arg = automode(arg, cmd);
2536 DEBUG("Adding: %s\n", arg);
2538 push_count_chars(cmd->arglist, arg);
2544 int main(int argc, char *argv[])
2549 memset(&cmd, 0, sizeof(cmd));
2551 cmd.options.pic_mode = PIC_UNKNOWN;
2552 cmd.mode = MODE_UNKNOWN;
2553 cmd.output = OUT_GENERAL;
2556 * Initialise the various argument lists
2558 cmd.program_opts = alloc_countchars();
2559 cmd.arglist = alloc_countchars();
2560 cmd.tmp_dirs = alloc_countchars();
2561 cmd.obj_files = alloc_countchars();
2562 cmd.dep_rpaths = alloc_countchars();
2563 cmd.rpaths = alloc_countchars();
2564 cmd.static_opts.normal = alloc_countchars();
2565 cmd.shared_opts.normal = alloc_countchars();
2566 cmd.shared_opts.dependencies = alloc_countchars();
2569 * Fill up the various argument lists
2571 parse_args(argc, argv, &cmd);
2572 post_parse_fixup(&cmd);
2575 * We couldn't figure out which mode to operate in
2577 if (cmd.mode == MODE_UNKNOWN) {
2581 rc = run_mode(&cmd);
2583 add_for_runtime(&cmd);
2586 cleanup_tmp_dirs(&cmd);