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>
22 #if !defined(__MINGW32__)
31 # define SHELL_CMD "sh"
32 # define GEN_EXPORTS "emxexp"
33 # define DEF2IMPLIB_CMD "emximp"
34 # define SHARE_SW "-Zdll -Zmtd"
36 # define TRUNCATE_DLL_NAME
37 # define DYNAMIC_LIB_EXT "dll"
38 # define EXE_EXT ".exe"
41 /* OMF is the native format under OS/2 */
42 # define STATIC_LIB_EXT "lib"
43 # define OBJECT_EXT "obj"
44 # define LIBRARIAN "emxomfar"
45 # define LIBRARIAN_OPTS "cr"
47 /* but the alternative, a.out, can fork() which is sometimes necessary */
48 # define STATIC_LIB_EXT "a"
49 # define OBJECT_EXT "o"
50 # define LIBRARIAN "ar"
51 # define LIBRARIAN_OPTS "cr"
55 #if defined(__APPLE__)
56 # define SHELL_CMD "/bin/sh"
57 # define DYNAMIC_LIB_EXT "dylib"
58 # define MODULE_LIB_EXT "bundle"
59 # define STATIC_LIB_EXT "a"
60 # define OBJECT_EXT "o"
61 # define LIBRARIAN "ar"
62 # define LIBRARIAN_OPTS "cr"
63 /* man libtool(1) documents ranlib option of -c. */
64 # define RANLIB "ranlib"
65 # define PIC_FLAG "-fPIC -fno-common"
66 # define SHARED_OPTS "-dynamiclib"
67 # define MODULE_OPTS "-bundle -dynamic"
68 # define DYNAMIC_LINK_OPTS "-flat_namespace"
69 # define DYNAMIC_LINK_UNDEFINED "-undefined suppress"
70 # define dynamic_link_version_func darwin_dynamic_link_function
71 # define DYNAMIC_INSTALL_NAME "-install_name"
72 # define DYNAMIC_LINK_NO_INSTALL "-dylib_file"
74 /*-install_name /Users/jerenk/apache-2.0-cvs/lib/libapr.0.dylib -compatibility_version 1 -current_version 1.0 */
75 # define LD_LIBRARY_PATH "DYLD_LIBRARY_PATH"
76 # define LD_LIBRARY_PATH_LOCAL "DYLD_FALLBACK_LIBRARY_PATH"
79 #if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
80 # define SHELL_CMD "/bin/sh"
81 # define DYNAMIC_LIB_EXT "so"
82 # define MODULE_LIB_EXT "so"
83 # define STATIC_LIB_EXT "a"
84 # define OBJECT_EXT "o"
85 # define LIBRARIAN "ar"
86 # define LIBRARIAN_OPTS "cr"
87 # define RANLIB "ranlib"
88 # define PIC_FLAG "-fPIC"
89 # define RPATH "-rpath"
90 # define SHARED_OPTS "-shared"
91 # define MODULE_OPTS "-shared"
92 # define DYNAMIC_LINK_OPTS "-export-dynamic"
93 # define LINKER_FLAG_PREFIX "-Wl,"
95 # define LD_RUN_PATH "LD_RUN_PATH"
96 # define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
97 # define LD_LIBRARY_PATH_LOCAL LD_LIBRARY_PATH
101 # define SHELL_CMD "/bin/sh"
102 # define DYNAMIC_LIB_EXT "so"
103 # define MODULE_LIB_EXT "so"
104 # define STATIC_LIB_EXT "a"
105 # define OBJECT_EXT "o"
106 # define LIBRARIAN "ar"
107 # define LIBRARIAN_OPTS "cr"
108 # define RANLIB "ranlib"
109 # define PIC_FLAG "-KPIC"
111 # define SHARED_OPTS "-G"
112 # define MODULE_OPTS "-G"
113 # define DYNAMIC_LINK_OPTS ""
114 # define LINKER_FLAG_NO_EQUALS
116 # define HAS_REALPATH
117 # define LD_RUN_PATH "LD_RUN_PATH"
118 # define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
119 # define LD_LIBRARY_PATH_LOCAL LD_LIBRARY_PATH
122 #if defined(_OSD_POSIX)
123 # define SHELL_CMD "/usr/bin/sh"
124 # define DYNAMIC_LIB_EXT "so"
125 # define MODULE_LIB_EXT "so"
126 # define STATIC_LIB_EXT "a"
127 # define OBJECT_EXT "o"
128 # define LIBRARIAN "ar"
129 # define LIBRARIAN_OPTS "cr"
130 # define SHARED_OPTS "-G"
131 # define MODULE_OPTS "-G"
132 # define LINKER_FLAG_PREFIX "-Wl,"
133 # define NEED_SNPRINTF
136 #if defined(sinix) && defined(mips) && defined(__SNI_TARG_UNIX)
137 # define SHELL_CMD "/usr/bin/sh"
138 # define DYNAMIC_LIB_EXT "so"
139 # define MODULE_LIB_EXT "so"
140 # define STATIC_LIB_EXT "a"
141 # define OBJECT_EXT "o"
142 # define LIBRARIAN "ar"
143 # define LIBRARIAN_OPTS "cr"
144 # define RPATH "-Brpath"
145 # define SHARED_OPTS "-G"
146 # define MODULE_OPTS "-G"
147 # define DYNAMIC_LINK_OPTS "-Wl,-Blargedynsym"
148 # define LINKER_FLAG_PREFIX "-Wl,"
149 # define NEED_SNPRINTF
150 # define LD_RUN_PATH "LD_RUN_PATH"
151 # define LD_LIBRARY_PATH "LD_LIBRARY_PATH"
152 # define LD_LIBRARY_PATH_LOCAL LD_LIBRARY_PATH
155 #if defined(__MINGW32__)
156 # define SHELL_CMD "sh"
157 # define DYNAMIC_LIB_EXT "dll"
158 # define MODULE_LIB_EXT "dll"
159 # define STATIC_LIB_EXT "a"
160 # define OBJECT_EXT "o"
161 # define LIBRARIAN "ar"
162 # define LIBRARIAN_OPTS "cr"
163 # define RANLIB "ranlib"
164 # define LINKER_FLAG_PREFIX "-Wl,"
165 # define SHARED_OPTS "-shared"
166 # define MODULE_OPTS "-shared"
167 # define MKDIR_NO_UMASK
168 # define EXE_EXT ".exe"
171 #define OBJDIR ".libs"
174 #error Unsupported platform: Please add defines for SHELL_CMD etc. for your platform.
186 #define PATH_MAX 1024
190 /* We want to say we are libtool 1.4 for shlibtool compatibility. */
191 #define VERSION "1.4"
207 otDynamicLibraryOnly,
243 count_chars *install;
244 count_chars *dependencies;
250 enum shared_mode_e shared;
253 enum pic_mode_e pic_mode;
259 enum tool_mode_t mode;
260 enum output_t output;
264 char *fake_output_name;
267 const char *install_path;
268 const char *compiler;
270 count_chars *program_opts;
272 count_chars *arglist;
273 count_chars *tmp_dirs;
274 count_chars *obj_files;
275 count_chars *dep_rpaths;
278 library_name static_name;
279 library_name shared_name;
280 library_name module_name;
282 library_opts static_opts;
283 library_opts shared_opts;
285 const char *version_info;
286 const char *undefined_flag;
290 static void add_rpath(count_chars *cc, const char *path);
293 static void usage(int code)
295 printf("Usage: jlibtool [OPTIONS...] COMMANDS...\n");
296 printf("jlibtool is a replacement for GNU libtool with similar functionality.\n\n");
298 printf(" --config show all configuration variables\n");
299 printf(" --debug enable verbose shell tracing\n");
300 printf(" --dry-run display commands without modifying any files\n");
301 printf(" --help display this help message and exit\n");
302 printf(" --mode=MODE use operational mode MODE (you *must* set mode)\n");
304 printf(" --silent don't print informational messages\n");
305 printf(" --tag=TAG Ignored for libtool compatibility\n");
306 printf(" --version print version information\n");
309 printf(" --shared Build shared libraries when using --mode=link\n");
310 printf(" --export-all Try to export 'def' file on some platforms\n");
312 printf("\nMODE must be one of the following:\n\n");
313 printf(" compile compile a source file into a jlibtool object\n");
314 printf(" execute automatically set library path, then run a program\n");
315 printf(" install install libraries or executables\n");
316 printf(" link create a library or an executable\n");
318 printf("\nMODE-ARGS can be the following:\n\n");
319 printf(" -export-dynamic accepted and ignored\n");
320 printf(" -module create a module when linking\n");
321 printf(" -shared create a shared library when linking\n");
322 printf(" -prefer-pic prefer position-independent-code when compiling\n");
323 printf(" -prefer-non-pic prefer non position-independent-code when compiling\n");
324 printf(" -static create a static library when linking\n");
325 printf(" -no-install link libraries locally\n");
326 printf(" -l arg pass '-l arg' to the link stage\n");
327 printf(" -L arg pass '-L arg' to the link stage\n");
328 printf(" -R dir add 'dir' to runtime library search path.\n");
329 printf(" -Zexe accepted and ignored\n");
330 printf(" -avoid-version accepted and ignored\n");
335 #if defined(NEED_SNPRINTF)
336 /* Write at most n characters to the buffer in str, return the
337 * number of chars written or -1 if the buffer would have been
340 * This is portable to any POSIX-compliant system has /dev/null
343 static int vsnprintf( char *str, size_t n, const char *fmt, va_list ap )
348 f = fopen("/dev/null","w");
352 setvbuf( f, str, _IOFBF, n );
354 res = vfprintf( f, fmt, ap );
356 if ( res > 0 && res < n ) {
357 res = vsprintf( str, fmt, ap );
361 static int snprintf( char *str, size_t n, const char *fmt, ... )
367 res = vsnprintf( str, n, fmt, ap );
373 static void init_count_chars(count_chars *cc)
375 cc->vals = (const char**)malloc(PATH_MAX*sizeof(char*));
379 static void clear_count_chars(count_chars *cc)
382 for (i = 0; i < cc->num; i++) {
389 static void push_count_chars(count_chars *cc, const char *newval)
391 cc->vals[cc->num++] = newval;
394 static void pop_count_chars(count_chars *cc)
399 static void insert_count_chars(count_chars *cc, const char *newval, int position)
403 for (i = cc->num; i > position; i--) {
404 cc->vals[i] = cc->vals[i-1];
407 cc->vals[position] = newval;
411 static void append_count_chars(count_chars *cc, count_chars *cctoadd)
414 for (i = 0; i < cctoadd->num; i++) {
415 if (cctoadd->vals[i]) {
416 push_count_chars(cc, cctoadd->vals[i]);
421 static const char *flatten_count_chars(count_chars *cc, int space)
427 for (i = 0; i < cc->num; i++) {
429 size += strlen(cc->vals[i]) + 1;
436 newval = (char*)malloc(size + 1);
439 for (i = 0; i < cc->num; i++) {
441 strcat(newval, cc->vals[i]);
451 static char *shell_esc(const char *str)
456 const unsigned char *s;
458 cmd = (char *)malloc(2 * strlen(str) + 3);
459 d = (unsigned char *)cmd;
460 s = (const unsigned char *)str;
471 else if (*s == '\\' || (*s == ' ' && (in_quote % 2))) {
485 static int external_spawn(command_t *cmd, const char *file, const char **argv)
487 if (!cmd->options.silent) {
488 const char **argument = argv;
489 // printf("Executing: ");
491 printf("%s ", *argument);
497 if (cmd->options.dry_run) {
500 #if defined(__EMX__) || defined(__MINGW32__)
501 return spawnvp(P_WAIT, argv[0], argv);
507 return execvp(argv[0], (char**)argv);
511 waitpid(pid, &statuscode, 0);
512 if (WIFEXITED(statuscode)) {
513 return WEXITSTATUS(statuscode);
521 static int run_command(command_t *cmd_data, count_chars *cc)
524 const char *spawn_args[4];
527 init_count_chars(&tmpcc);
529 if (cmd_data->program) {
530 push_count_chars(&tmpcc, cmd_data->program);
533 append_count_chars(&tmpcc, cmd_data->program_opts);
535 append_count_chars(&tmpcc, cc);
537 command = shell_esc(flatten_count_chars(&tmpcc, 1));
539 spawn_args[0] = SHELL_CMD;
540 spawn_args[1] = "-c";
541 spawn_args[2] = command;
542 spawn_args[3] = NULL;
544 return external_spawn(cmd_data, spawn_args[0], (const char**)spawn_args);
548 * print configuration
549 * shlibpath_var is used in configure.
551 #define printc(_x,_y) if (!value || !strcmp(value, _x)) printf(_x "=\"%s\"\n", _y)
553 static void print_config(const char *value)
556 printc("runpath_var", LD_RUN_PATH);
558 #ifdef LD_LIBRARY_PATH
559 printc("shlibpath_var", LD_LIBRARY_PATH);
561 #ifdef LD_LIBRARY_PATH_LOCAL
562 printc("shlocallibpath_var", LD_LIBRARY_PATH_LOCAL);
565 printc("SHELL", SHELL_CMD);
568 printc("objext", OBJECT_EXT);
571 printc("objdir", OBJDIR);
573 #ifdef DYNAMIC_LIB_EXT
574 /* add a '.' prefix because libtool does that. */
575 printc("shrext_cmds", "echo ." DYNAMIC_LIB_EXT);
576 /* add a '.' prefix because libtool does that. */
577 printc("shrext", "." DYNAMIC_LIB_EXT);
580 printc("exeext", EXE_EXT);
582 #ifdef STATIC_LIB_EXT
583 printc("libext", STATIC_LIB_EXT);
586 printc("AR", LIBRARIAN);
588 #ifdef LIBRARIAN_OPTS
589 printc("AR_FLAGS", LIBRARIAN_OPTS);
591 #ifdef LINKER_FLAG_PREFIX
592 printc("wl", LINKER_FLAG_PREFIX);
595 printc("ranlib", RANLIB);
599 * Add a directory to the runtime library search path.
601 static void add_runtimedirlib(char *arg, command_t *cmd_data)
604 add_rpath(cmd_data->shared_opts.dependencies, arg);
609 static int parse_long_opt(char *arg, command_t *cmd_data)
611 char *equal_pos = strchr(arg, '=');
616 strncpy(var, arg, equal_pos - arg);
617 var[equal_pos - arg] = 0;
618 strcpy(value, equal_pos + 1);
624 if (strcmp(var, "silent") == 0) {
625 cmd_data->options.silent = 1;
626 } else if (strcmp(var, "debug") == 0) {
627 cmd_data->options.debug = 1;
628 } else if (strcmp(var, "mode") == 0) {
629 if (strcmp(value, "compile") == 0) {
630 cmd_data->mode = mCompile;
631 cmd_data->output = otObject;
633 } else if (strcmp(value, "link") == 0) {
634 cmd_data->mode = mLink;
635 cmd_data->output = otLibrary;
637 } else if (strcmp(value, "install") == 0) {
638 cmd_data->mode = mInstall;
640 } else if (strcmp(value, "execute") == 0) {
641 cmd_data->mode = mExecute;
644 printf("Unknown mode \"%s\"\n", value);
646 } else if (strcmp(var, "shared") == 0) {
647 if ((cmd_data->mode == mLink) &&
648 (cmd_data->output == otGeneral)) {
649 cmd_data->output = otDynamicLibraryOnly;
651 cmd_data->options.shared = share_SHARED;
652 } else if (strcmp(var, "export-all") == 0) {
653 cmd_data->options.export_all = 1;
654 } else if (strcmp(var, "dry-run") == 0) {
655 printf("Dry-run mode on!\n");
656 cmd_data->options.dry_run = 1;
657 } else if (strcmp(var, "version") == 0) {
658 printf("Version " VERSION "\n");
659 } else if (strcmp(var, "help") == 0) {
661 } else if (strcmp(var, "config") == 0) {
664 } else if (strcmp(var, "tag") == 0) {
665 if (strcmp(value, "CC") == 0) {
668 if (strcmp(value, "CXX") == 0) {
678 /* Return 1 if we eat it. */
679 static int parse_short_opt(char *arg, command_t *cmd_data)
681 if (strcmp(arg, "export-dynamic") == 0) {
682 cmd_data->options.export_dynamic = 1;
686 if (strcmp(arg, "module") == 0) {
687 cmd_data->output = otModule;
691 if (strcmp(arg, "shared") == 0) {
692 if (cmd_data->mode == mLink) {
693 cmd_data->output = otDynamicLibraryOnly;
695 cmd_data->options.shared = share_SHARED;
699 if (strcmp(arg, "Zexe") == 0) {
703 if (strcmp(arg, "avoid-version") == 0) {
707 if (strcmp(arg, "prefer-pic") == 0) {
708 cmd_data->options.pic_mode = pic_PREFER;
712 if (strcmp(arg, "prefer-non-pic") == 0) {
713 cmd_data->options.pic_mode = pic_AVOID;
717 if (strcmp(arg, "static") == 0) {
718 cmd_data->options.shared = share_STATIC;
722 if (cmd_data->mode == mLink) {
723 if (strcmp(arg, "no-install") == 0) {
724 cmd_data->options.no_install = 1;
727 if (arg[0] == 'L' || arg[0] == 'l') {
730 push_count_chars(cmd_data->shared_opts.dependencies, arg);
732 } else if (arg[0] == 'R' && arg[1]) {
733 /* -Rdir Add dir to runtime library search path. */
734 add_runtimedirlib(&arg[1], cmd_data);
741 static char *truncate_dll_name(char *path)
743 /* Cut DLL name down to 8 characters after removing any mod_ prefix */
744 char *tmppath = strdup(path);
745 char *newname = strrchr(tmppath, '/') + 1;
746 char *ext = strrchr(newname, '.');
754 if (strncmp(newname, "mod_", 4) == 0) {
755 strcpy(newname, newname + 4);
760 strcpy(newname + 8, strchr(newname, '.'));
766 static long safe_strtol(const char *nptr, const char **endptr, int base)
772 rv = strtol(nptr, (char**)endptr, 10);
774 if (errno == ERANGE) {
781 static void safe_mkdir(const char *path)
785 old_umask = umask(0);
788 #ifdef MKDIR_NO_UMASK
791 mkdir(path, ~old_umask);
795 /* returns just a file's name without the path */
796 static const char *jlibtool_basename(const char *fullpath)
798 const char *name = strrchr(fullpath, '/');
801 name = strrchr(fullpath, '\\');
813 /* returns just a file's name without path or extension */
814 static const char *nameof(const char *fullpath)
819 name = jlibtool_basename(fullpath);
820 ext = strrchr(name, '.');
824 trimmed = malloc(ext - name + 1);
825 strncpy(trimmed, name, ext - name);
826 trimmed[ext-name] = 0;
833 /* version_info is in the form of MAJOR:MINOR:PATCH */
834 static const char *darwin_dynamic_link_function(const char *version_info)
837 long major, minor, patch;
844 major = safe_strtol(version_info, &version_info, 10);
847 if (version_info[0] == ':') {
851 minor = safe_strtol(version_info, &version_info, 10);
854 if (version_info[0] == ':') {
858 patch = safe_strtol(version_info, &version_info, 10);
864 /* Avoid -dylib_compatibility_version must be greater than zero errors. */
868 newarg = (char*)malloc(100);
870 "-compatibility_version %ld -current_version %ld.%ld",
871 major, major, minor);
878 * Add a '.libs/' to the buffer. The caller ensures that
879 * The buffer is large enough to handle 6 extra characters.
881 static void add_dotlibs(char *buffer)
883 char *name = strrchr(buffer, '/');
887 strcpy(buffer, ".libs/");
894 memmove(name + 6, name, strlen(name));
895 memcpy(name, ".libs/", 6);
903 static char *gen_library_name(const char *name, int genlib)
905 char *newarg, *newext;
907 newarg = (char *)malloc(strlen(name) + 11);
909 if (genlib == 2 && strncmp(name, "lib", 3) == 0) {
914 strcat(newarg, jlibtool_basename(name));
917 strcat(newarg, name);
920 newext = strrchr(newarg, '.') + 1;
924 strcpy(newext, STATIC_LIB_EXT);
927 strcpy(newext, DYNAMIC_LIB_EXT);
930 strcpy(newext, MODULE_LIB_EXT);
944 static char *gen_install_name(const char *name, int genlib)
950 newname = gen_library_name(name, genlib);
952 /* Check if it exists. If not, return NULL. */
953 rv = stat(newname, &sb);
962 static char *check_object_exists(command_t *cmd, const char *arg, int arglen)
967 newarg = (char *)malloc(arglen + 10);
968 memcpy(newarg, arg, arglen);
970 ext = newarg + arglen;
979 strcpy(ext, OBJECT_EXT);
983 strcpy(ext, NO_PIC_EXT);
990 if (cmd->options.debug) {
991 printf("Checking (obj): %s\n", newarg);
993 rv = stat(newarg, &sb);
995 while (rv != 0 && ++pass < 1);
999 cmd->options.pic_mode = pic_AVOID;
1007 /* libdircheck values:
1008 * 0 - no .libs suffix
1011 static char *check_library_exists(command_t *cmd, const char *arg, int pathlen,
1012 int libdircheck, enum lib_type *libtype)
1015 int pass, rv, newpathlen;
1017 newarg = (char *)malloc(strlen(arg) + 10);
1018 strcpy(newarg, arg);
1019 newarg[pathlen] = 0;
1021 newpathlen = pathlen;
1023 add_dotlibs(newarg);
1024 newpathlen += sizeof(".libs/") - 1;
1027 strcpy(newarg+newpathlen, arg+pathlen);
1028 ext = strrchr(newarg, '.') + 1;
1037 if (cmd->options.pic_mode != pic_AVOID &&
1038 cmd->options.shared != share_STATIC) {
1039 strcpy(ext, DYNAMIC_LIB_EXT);
1040 *libtype = type_DYNAMIC_LIB;
1046 strcpy(ext, STATIC_LIB_EXT);
1047 *libtype = type_STATIC_LIB;
1050 strcpy(ext, MODULE_LIB_EXT);
1051 *libtype = type_MODULE_LIB;
1054 strcpy(ext, OBJECT_EXT);
1055 *libtype = type_OBJECT;
1058 *libtype = type_UNKNOWN;
1062 if (cmd->options.debug) {
1063 printf("Checking (lib): %s\n", newarg);
1065 rv = stat(newarg, &sb);
1067 while (rv != 0 && ++pass < 4);
1076 static char * load_install_path(const char *arg)
1081 path = malloc(PATH_MAX);
1087 fgets(path, PATH_MAX, f);
1089 if (path[strlen(path)-1] == '\n') {
1090 path[strlen(path)-1] = '\0';
1092 /* Check that we have an absolute path.
1093 * Otherwise the file could be a GNU libtool file.
1095 if (path[0] != '/') {
1101 static char * load_noinstall_path(const char *arg, int pathlen)
1103 char *newarg, *expanded_path;
1106 newarg = (char *)malloc(strlen(arg) + 10);
1107 strcpy(newarg, arg);
1108 newarg[pathlen] = 0;
1110 newpathlen = pathlen;
1111 strcat(newarg, ".libs");
1112 newpathlen += sizeof(".libs") - 1;
1113 newarg[newpathlen] = 0;
1116 expanded_path = malloc(PATH_MAX);
1117 expanded_path = realpath(newarg, expanded_path);
1118 /* Uh, oh. There was an error. Fall back on our first guess. */
1119 if (!expanded_path) {
1120 expanded_path = newarg;
1123 /* We might get ../ or something goofy. Oh, well. */
1124 expanded_path = newarg;
1127 return expanded_path;
1130 static void add_dynamic_link_opts(command_t *cmd_data, count_chars *args)
1132 #ifdef DYNAMIC_LINK_OPTS
1133 if (cmd_data->options.pic_mode != pic_AVOID) {
1134 if (cmd_data->options.debug) {
1135 printf("Adding: %s\n", DYNAMIC_LINK_OPTS);
1137 push_count_chars(args, DYNAMIC_LINK_OPTS);
1138 if (cmd_data->undefined_flag) {
1139 push_count_chars(args, "-undefined");
1140 #if defined(__APPLE__)
1141 /* -undefined dynamic_lookup is used by the bundled Python in
1142 * 10.4, but if we don't set MACOSX_DEPLOYMENT_TARGET to 10.3+,
1143 * we'll get a linker error if we pass this flag.
1145 if (strcasecmp(cmd_data->undefined_flag,
1146 "dynamic_lookup") == 0) {
1147 insert_count_chars(cmd_data->program_opts,
1148 "MACOSX_DEPLOYMENT_TARGET=10.3", 0);
1151 push_count_chars(args, cmd_data->undefined_flag);
1154 #ifdef DYNAMIC_LINK_UNDEFINED
1155 if (cmd_data->options.debug) {
1156 printf("Adding: %s\n", DYNAMIC_LINK_UNDEFINED);
1158 push_count_chars(args, DYNAMIC_LINK_UNDEFINED);
1165 /* Read the final install location and add it to runtime library search path. */
1167 static void add_rpath(count_chars *cc, const char *path)
1172 #ifdef LINKER_FLAG_PREFIX
1173 size = strlen(LINKER_FLAG_PREFIX);
1175 size = size + strlen(path) + strlen(RPATH) + 2;
1180 #ifdef LINKER_FLAG_PREFIX
1181 strcpy(tmp, LINKER_FLAG_PREFIX);
1186 #ifndef LINKER_FLAG_NO_EQUALS
1191 push_count_chars(cc, tmp);
1194 static void add_rpath_file(count_chars *cc, const char *arg)
1198 path = load_install_path(arg);
1200 add_rpath(cc, path);
1204 static void add_rpath_noinstall(count_chars *cc, const char *arg, int pathlen)
1208 path = load_noinstall_path(arg, pathlen);
1210 add_rpath(cc, path);
1215 #ifdef DYNAMIC_LINK_NO_INSTALL
1216 static void add_dylink_noinstall(count_chars *cc, const char *arg, int pathlen,
1219 const char *install_path, *current_path, *name;
1221 int i_p_len, c_p_len, name_len, dyext_len, cur_len;
1223 install_path = load_install_path(arg);
1224 current_path = load_noinstall_path(arg, pathlen);
1226 if (!install_path || !current_path) {
1230 push_count_chars(cc, DYNAMIC_LINK_NO_INSTALL);
1232 i_p_len = strlen(install_path);
1233 c_p_len = strlen(current_path);
1236 name_len = extlen-pathlen;
1237 dyext_len = sizeof(DYNAMIC_LIB_EXT) - 1;
1239 /* No, we need to replace the extension. */
1240 exp_argument = (char *)malloc(i_p_len + c_p_len + (name_len*2) +
1244 strcpy(exp_argument, install_path);
1246 exp_argument[cur_len++] = '/';
1247 strncpy(exp_argument+cur_len, name, extlen-pathlen);
1248 cur_len += name_len;
1249 strcpy(exp_argument+cur_len, DYNAMIC_LIB_EXT);
1250 cur_len += dyext_len;
1251 exp_argument[cur_len++] = ':';
1252 strcpy(exp_argument+cur_len, current_path);
1254 exp_argument[cur_len++] = '/';
1255 strncpy(exp_argument+cur_len, name, extlen-pathlen);
1256 cur_len += name_len;
1257 strcpy(exp_argument+cur_len, DYNAMIC_LIB_EXT);
1258 cur_len += dyext_len;
1260 push_count_chars(cc, exp_argument);
1264 /* use -L -llibname to allow to use installed libraries */
1265 static void add_minus_l(count_chars *cc, const char *arg)
1268 char *name = strrchr(arg, '/');
1269 char *file = strrchr(arg, '.');
1270 char *lib = strstr(name, "lib");
1272 if (name !=NULL && file != NULL && lib == name+1) {
1277 push_count_chars(cc, "-L");
1278 push_count_chars(cc, arg);
1279 /* we need one argument like -lapr-1 */
1280 newarg = malloc(strlen(file) + 3);
1281 strcpy(newarg, "-l");
1282 strcat(newarg, file);
1283 push_count_chars(cc, newarg);
1285 push_count_chars(cc, arg);
1289 static void add_linker_flag_prefix(count_chars *cc, const char *arg)
1291 #ifndef LINKER_FLAG_PREFIX
1292 push_count_chars(cc, arg);
1295 newarg = (char*)malloc(strlen(arg) + sizeof(LINKER_FLAG_PREFIX) + 1);
1296 strcpy(newarg, LINKER_FLAG_PREFIX);
1297 strcat(newarg, arg);
1298 push_count_chars(cc, newarg);
1302 static int explode_static_lib(command_t *cmd_data, const char *lib)
1304 count_chars tmpdir_cc, libname_cc;
1305 const char *tmpdir, *libname;
1306 char savewd[PATH_MAX];
1309 struct dirent *entry;
1310 const char *lib_args[4];
1313 if (cmd_data->options.dry_run) {
1317 name = jlibtool_basename(lib);
1319 init_count_chars(&tmpdir_cc);
1320 push_count_chars(&tmpdir_cc, ".libs/");
1321 push_count_chars(&tmpdir_cc, name);
1322 push_count_chars(&tmpdir_cc, ".exploded/");
1323 tmpdir = flatten_count_chars(&tmpdir_cc, 0);
1325 if (!cmd_data->options.silent) {
1326 printf("Making: %s\n", tmpdir);
1330 push_count_chars(cmd_data->tmp_dirs, tmpdir);
1332 getcwd(savewd, sizeof(savewd));
1334 if (chdir(tmpdir) != 0) {
1335 if (!cmd_data->options.silent) {
1336 printf("Warning: could not explode %s\n", lib);
1341 if (lib[0] == '/') {
1345 init_count_chars(&libname_cc);
1346 push_count_chars(&libname_cc, "../../");
1347 push_count_chars(&libname_cc, lib);
1348 libname = flatten_count_chars(&libname_cc, 0);
1351 lib_args[0] = LIBRARIAN;
1353 lib_args[2] = libname;
1356 external_spawn(cmd_data, LIBRARIAN, lib_args);
1359 dir = opendir(tmpdir);
1361 while ((entry = readdir(dir)) != NULL) {
1362 #if defined(__APPLE__) && defined(RANLIB)
1363 /* Apple inserts __.SYMDEF which isn't needed.
1364 * Leopard (10.5+) can also add '__.SYMDEF SORTED' which isn't
1365 * much fun either. Just skip them.
1367 if (strstr(entry->d_name, "__.SYMDEF") != NULL) {
1371 if (entry->d_name[0] != '.') {
1372 push_count_chars(&tmpdir_cc, entry->d_name);
1373 name = flatten_count_chars(&tmpdir_cc, 0);
1374 if (cmd_data->options.debug) {
1375 printf("Adding: %s\n", name);
1377 push_count_chars(cmd_data->obj_files, name);
1378 pop_count_chars(&tmpdir_cc);
1386 static int parse_input_file_name(char *arg, command_t *cmd_data)
1388 char *ext = strrchr(arg, '.');
1391 enum lib_type libtype;
1399 name = jlibtool_basename(arg);
1401 pathlen = name - arg;
1403 if (strcmp(ext, "lo") == 0) {
1404 newarg = check_object_exists(cmd_data, arg, ext - arg);
1406 fprintf(stderr, "Can not find suitable object file for %s\n", arg);
1409 if (cmd_data->mode != mLink) {
1410 push_count_chars(cmd_data->arglist, newarg);
1413 push_count_chars(cmd_data->obj_files, newarg);
1418 if (strcmp(ext, "la") == 0) {
1419 switch (cmd_data->mode) {
1421 /* Try the .libs dir first! */
1422 newarg = check_library_exists(cmd_data, arg, pathlen, 1, &libtype);
1424 /* Try the normal dir next. */
1425 newarg = check_library_exists(cmd_data, arg, pathlen, 0, &libtype);
1427 fprintf(stderr, "Can not find suitable library for %s\n", arg);
1432 /* It is not ok to just add the file: a library may added with:
1433 1 - -L path library_name. (For *.so in Linux).
1437 if (libtype == type_DYNAMIC_LIB) {
1438 add_minus_l(cmd_data->shared_opts.dependencies, newarg);
1439 } else if (cmd_data->output == otLibrary &&
1440 libtype == type_STATIC_LIB) {
1441 explode_static_lib(cmd_data, newarg);
1443 push_count_chars(cmd_data->shared_opts.dependencies, newarg);
1446 if (cmd_data->output == otLibrary && libtype == type_STATIC_LIB) {
1447 explode_static_lib(cmd_data, newarg);
1450 push_count_chars(cmd_data->shared_opts.dependencies, newarg);
1453 if (libtype == type_DYNAMIC_LIB) {
1454 if (cmd_data->options.no_install) {
1456 add_rpath_noinstall(cmd_data->shared_opts.dependencies,
1459 #ifdef DYNAMIC_LINK_NO_INSTALL
1461 * This doesn't work as Darwin's linker has no way to
1462 * override at link-time the search paths for a
1463 * non-installed library.
1466 add_dylink_noinstall(cmd_data->shared_opts.dependencies,
1467 arg, pathlen, ext - arg);
1473 add_rpath_file(cmd_data->shared_opts.dependencies, arg);
1479 /* If we've already recorded a library to install, we're most
1480 * likely getting the .la file that we want to install as.
1481 * The problem is that we need to add it as the directory,
1482 * not the .la file itself. Otherwise, we'll do odd things.
1484 if (cmd_data->output == otLibrary) {
1485 arg[pathlen] = '\0';
1486 push_count_chars(cmd_data->arglist, arg);
1489 cmd_data->output = otLibrary;
1490 cmd_data->output_name = arg;
1491 cmd_data->static_name.install = gen_install_name(arg, 0);
1492 cmd_data->shared_name.install = gen_install_name(arg, 1);
1493 cmd_data->module_name.install = gen_install_name(arg, 2);
1502 if (strcmp(ext, "c") == 0) {
1503 /* If we don't already have an idea what our output name will be. */
1504 if (cmd_data->basename == NULL) {
1505 cmd_data->basename = (char *)malloc(strlen(arg) + 4);
1506 strcpy(cmd_data->basename, arg);
1507 strcpy(strrchr(cmd_data->basename, '.') + 1, "lo");
1509 cmd_data->fake_output_name = strrchr(cmd_data->basename, '/');
1510 if (cmd_data->fake_output_name) {
1511 cmd_data->fake_output_name++;
1514 cmd_data->fake_output_name = cmd_data->basename;
1522 static int parse_output_file_name(char *arg, command_t *cmd_data)
1526 char *newarg = NULL;
1529 cmd_data->fake_output_name = arg;
1531 name = jlibtool_basename(arg);
1532 ext = strrchr(name, '.');
1535 if (!ext || strcmp(ext, EXE_EXT) == 0) {
1539 cmd_data->basename = arg;
1540 cmd_data->output = otProgram;
1541 #if defined(_OSD_POSIX)
1542 cmd_data->options.pic_mode = pic_AVOID;
1544 newarg = (char *)malloc(strlen(arg) + 5);
1545 strcpy(newarg, arg);
1548 strcat(newarg, EXE_EXT);
1551 cmd_data->output_name = newarg;
1556 pathlen = name - arg;
1558 if (strcmp(ext, "la") == 0) {
1559 assert(cmd_data->mode == mLink);
1561 cmd_data->basename = arg;
1562 cmd_data->static_name.normal = gen_library_name(arg, 0);
1563 cmd_data->shared_name.normal = gen_library_name(arg, 1);
1564 cmd_data->module_name.normal = gen_library_name(arg, 2);
1565 cmd_data->static_name.install = gen_install_name(arg, 0);
1566 cmd_data->shared_name.install = gen_install_name(arg, 1);
1567 cmd_data->module_name.install = gen_install_name(arg, 2);
1569 if (!cmd_data->options.dry_run) {
1572 cname = malloc(strlen(cmd_data->static_name.normal) + 1);
1574 strcpy(cname, cmd_data->static_name.normal);
1575 ext = strrchr(cname, '/');
1577 /* Check first to see if the dir already exists! */
1578 safe_mkdir(".libs");
1586 #ifdef TRUNCATE_DLL_NAME
1588 arg = truncate_dll_name(arg);
1592 cmd_data->output_name = arg;
1596 if (strcmp(ext, "lo") == 0) {
1597 cmd_data->basename = arg;
1598 cmd_data->output = otObject;
1599 newarg = (char *)malloc(strlen(arg) + 2);
1600 strcpy(newarg, arg);
1601 ext = strrchr(newarg, '.') + 1;
1602 strcpy(ext, OBJECT_EXT);
1603 cmd_data->output_name = newarg;
1610 static void parse_args(int argc, char *argv[], command_t *cmd_data)
1616 for (a = 1; a < argc; a++) {
1620 if (arg[0] == '-') {
1621 if (arg[1] == '-') {
1622 argused = parse_long_opt(arg + 2, cmd_data);
1625 argused = parse_short_opt(arg + 1, cmd_data);
1628 /* We haven't done anything with it yet, try some of the
1629 * more complicated short opts... */
1630 if (argused == 0 && a + 1 < argc) {
1631 if (arg[1] == 'o' && !arg[2]) {
1633 argused = parse_output_file_name(arg, cmd_data);
1634 } else if (strcmp(arg+1, "MT") == 0) {
1635 if (cmd_data->options.debug) {
1636 printf("Adding: %s\n", arg);
1638 push_count_chars(cmd_data->arglist, arg);
1640 if (!cmd_data->options.silent) {
1641 printf(" %s\n", arg);
1643 push_count_chars(cmd_data->arglist, arg);
1645 } else if (strcmp(arg+1, "rpath") == 0) {
1646 /* Aha, we should try to link both! */
1647 cmd_data->install_path = argv[++a];
1649 } else if (strcmp(arg+1, "release") == 0) {
1650 /* Store for later deciphering */
1651 cmd_data->version_info = argv[++a];
1653 } else if (strcmp(arg+1, "version-info") == 0) {
1654 /* Store for later deciphering */
1655 cmd_data->version_info = argv[++a];
1657 } else if (strcmp(arg+1, "export-symbols-regex") == 0) {
1658 /* Skip the argument. */
1661 } else if (strcmp(arg+1, "release") == 0) {
1662 /* Skip the argument. */
1665 } else if (strcmp(arg+1, "undefined") == 0) {
1666 cmd_data->undefined_flag = argv[++a];
1668 } else if (arg[1] == 'R' && !arg[2]) {
1669 /* -R dir Add dir to runtime library search path. */
1670 add_runtimedirlib(argv[++a], cmd_data);
1675 argused = parse_input_file_name(arg, cmd_data);
1679 if (cmd_data->options.debug) {
1680 printf("Adding: %s\n", arg);
1682 push_count_chars(cmd_data->arglist, arg);
1689 static void generate_def_file(command_t *cmd_data)
1691 char def_file[1024];
1692 char implib_file[1024];
1695 char *export_args[1024];
1696 int num_export_args = 0;
1701 if (cmd_data->output_name) {
1702 strcpy(def_file, cmd_data->output_name);
1703 strcat(def_file, ".def");
1704 hDef = fopen(def_file, "w");
1707 fprintf(hDef, "LIBRARY '%s' INITINSTANCE\n", nameof(cmd_data->output_name));
1708 fprintf(hDef, "DATA NONSHARED\n");
1709 fprintf(hDef, "EXPORTS\n");
1712 for (a = 0; a < cmd_data->num_obj_files; a++) {
1713 cmd_size += strlen(cmd_data->obj_files[a]) + 1;
1716 cmd_size += strlen(GEN_EXPORTS) + strlen(def_file) + 3;
1717 cmd = (char *)malloc(cmd_size);
1718 strcpy(cmd, GEN_EXPORTS);
1720 for (a=0; a < cmd_data->num_obj_files; a++) {
1722 strcat(cmd, cmd_data->obj_files[a] );
1726 strcat(cmd, def_file);
1728 export_args[num_export_args++] = SHELL_CMD;
1729 export_args[num_export_args++] = "-c";
1730 export_args[num_export_args++] = cmd;
1731 export_args[num_export_args++] = NULL;
1732 external_spawn(cmd_data, export_args[0], (const char**)export_args);
1733 cmd_data->arglist[cmd_data->num_args++] = strdup(def_file);
1735 /* Now make an import library for the dll */
1736 num_export_args = 0;
1737 export_args[num_export_args++] = DEF2IMPLIB_CMD;
1738 export_args[num_export_args++] = "-o";
1740 strcpy(implib_file, ".libs/");
1741 strcat(implib_file, cmd_data->basename);
1742 ext = strrchr(implib_file, '.');
1747 strcat(implib_file, ".");
1748 strcat(implib_file, STATIC_LIB_EXT);
1750 export_args[num_export_args++] = implib_file;
1751 export_args[num_export_args++] = def_file;
1752 export_args[num_export_args++] = NULL;
1753 external_spawn(cmd_data, export_args[0], (const char**)export_args);
1760 static const char* expand_path(const char *relpath)
1762 char foo[PATH_MAX], *newpath;
1764 getcwd(foo, PATH_MAX-1);
1765 newpath = (char*)malloc(strlen(foo)+strlen(relpath)+2);
1766 strcat(newpath, foo);
1767 strcat(newpath, "/");
1768 strcat(newpath, relpath);
1772 static void link_fixup(command_t *c)
1774 /* If we were passed an -rpath directive, we need to build
1775 * shared objects too. Otherwise, we should only create static
1778 if (!c->install_path && (c->output == otDynamicLibraryOnly ||
1779 c->output == otModule || c->output == otLibrary)) {
1780 c->output = otStaticLibraryOnly;
1782 if (c->options.shared == share_SHARED) {
1783 fprintf(stderr, "Can not build a shared library without -rpath");
1788 if (c->output == otDynamicLibraryOnly ||
1789 c->output == otModule ||
1790 c->output == otLibrary) {
1792 push_count_chars(c->shared_opts.normal, "-o");
1793 if (c->output == otModule) {
1794 push_count_chars(c->shared_opts.normal, c->module_name.normal);
1798 push_count_chars(c->shared_opts.normal, c->shared_name.normal);
1799 #ifdef DYNAMIC_INSTALL_NAME
1800 push_count_chars(c->shared_opts.normal, DYNAMIC_INSTALL_NAME);
1802 tmp = (char*)malloc(PATH_MAX);
1803 strcat(tmp, c->install_path);
1804 strcat(tmp, strrchr(c->shared_name.normal, '/'));
1805 push_count_chars(c->shared_opts.normal, tmp);
1809 append_count_chars(c->shared_opts.normal, c->obj_files);
1810 append_count_chars(c->shared_opts.normal, c->shared_opts.dependencies);
1812 if (c->options.export_all) {
1814 generate_def_file(c);
1819 if (c->output == otLibrary || c->output == otStaticLibraryOnly) {
1820 push_count_chars(c->static_opts.normal, "-o");
1821 push_count_chars(c->static_opts.normal, c->output_name);
1824 if (c->output == otProgram) {
1825 if (c->output_name) {
1826 push_count_chars(c->arglist, "-o");
1827 push_count_chars(c->arglist, c->output_name);
1828 append_count_chars(c->arglist, c->obj_files);
1829 append_count_chars(c->arglist, c->shared_opts.dependencies);
1830 add_dynamic_link_opts(c, c->arglist);
1835 static void post_parse_fixup(command_t *cmd_data)
1837 switch (cmd_data->mode)
1841 if (cmd_data->options.pic_mode != pic_AVOID) {
1842 push_count_chars(cmd_data->arglist, PIC_FLAG);
1845 if (cmd_data->output_name) {
1846 push_count_chars(cmd_data->arglist, "-o");
1847 push_count_chars(cmd_data->arglist, cmd_data->output_name);
1851 link_fixup(cmd_data);
1854 if (cmd_data->output == otLibrary) {
1855 link_fixup(cmd_data);
1862 if (cmd_data->output == otObject ||
1863 cmd_data->output == otProgram ||
1864 cmd_data->output == otLibrary ||
1865 cmd_data->output == otDynamicLibraryOnly) {
1866 push_count_chars(cmd_data->arglist, "-Zomf");
1870 if (cmd_data->options.shared &&
1871 (cmd_data->output == otObject ||
1872 cmd_data->output == otLibrary ||
1873 cmd_data->output == otDynamicLibraryOnly)) {
1875 push_count_chars(cmd_data->arglist, SHARE_SW);
1880 static int run_mode(command_t *cmd_data)
1883 count_chars *cctemp;
1885 cctemp = (count_chars*)malloc(sizeof(count_chars));
1886 init_count_chars(cctemp);
1888 switch (cmd_data->mode)
1891 rv = run_command(cmd_data, cmd_data->arglist);
1897 /* Well, we'll assume it's a file going to a directory... */
1898 /* For brain-dead install-sh based scripts, we have to repeat
1899 * the command N-times. install-sh should die.
1901 if (!cmd_data->output_name) {
1902 rv = run_command(cmd_data, cmd_data->arglist);
1907 if (cmd_data->output_name) {
1908 append_count_chars(cctemp, cmd_data->arglist);
1909 insert_count_chars(cctemp,
1910 cmd_data->output_name,
1912 rv = run_command(cmd_data, cctemp);
1916 clear_count_chars(cctemp);
1918 if (cmd_data->static_name.install) {
1919 append_count_chars(cctemp, cmd_data->arglist);
1920 insert_count_chars(cctemp,
1921 cmd_data->static_name.install,
1923 rv = run_command(cmd_data, cctemp);
1927 #if defined(__APPLE__) && defined(RANLIB)
1928 /* From the Apple libtool(1) manpage on Tiger/10.4:
1930 * With the way libraries used to be created, errors were possible
1931 * if the library was modified with ar(1) and the table of
1932 * contents was not updated by rerunning ranlib(1). Thus the
1933 * link editor, ld, warns when the modification date of a library
1934 * is more recent than the creation date of its table of
1935 * contents. Unfortunately, this means that you get the warning
1936 * even if you only copy the library.
1939 * This means that when we install the static archive, we need to
1940 * rerun ranlib afterwards.
1942 const char *lib_args[3], *static_lib_name;
1945 len1 = strlen(cmd_data->arglist->vals[cmd_data->arglist->num - 1]);
1947 static_lib_name = jlibtool_basename(cmd_data->static_name.install);
1948 len2 = strlen(static_lib_name);
1950 tmp = malloc(len1 + len2 + 2);
1952 snprintf(tmp, len1 + len2 + 2, "%s/%s",
1953 cmd_data->arglist->vals[cmd_data->arglist->num - 1],
1956 lib_args[0] = RANLIB;
1959 external_spawn(cmd_data, RANLIB, lib_args);
1962 clear_count_chars(cctemp);
1964 if (cmd_data->shared_name.install) {
1965 append_count_chars(cctemp, cmd_data->arglist);
1966 insert_count_chars(cctemp,
1967 cmd_data->shared_name.install,
1969 rv = run_command(cmd_data, cctemp);
1973 clear_count_chars(cctemp);
1975 if (cmd_data->module_name.install) {
1976 append_count_chars(cctemp, cmd_data->arglist);
1977 insert_count_chars(cctemp,
1978 cmd_data->module_name.install,
1980 rv = run_command(cmd_data, cctemp);
1984 clear_count_chars(cctemp);
1988 if (cmd_data->output == otStaticLibraryOnly ||
1989 cmd_data->output == otLibrary) {
1991 const char *lib_args[3];
1993 /* Removes compiler! */
1994 cmd_data->program = LIBRARIAN;
1995 push_count_chars(cmd_data->program_opts, LIBRARIAN_OPTS);
1996 push_count_chars(cmd_data->program_opts,
1997 cmd_data->static_name.normal);
1999 rv = run_command(cmd_data, cmd_data->obj_files);
2005 lib_args[0] = RANLIB;
2006 lib_args[1] = cmd_data->static_name.normal;
2008 external_spawn(cmd_data, RANLIB, lib_args);
2012 if (cmd_data->output == otDynamicLibraryOnly ||
2013 cmd_data->output == otModule ||
2014 cmd_data->output == otLibrary) {
2015 cmd_data->program = NULL;
2016 clear_count_chars(cmd_data->program_opts);
2018 append_count_chars(cmd_data->program_opts, cmd_data->arglist);
2019 if (cmd_data->output == otModule) {
2021 push_count_chars(cmd_data->program_opts, MODULE_OPTS);
2025 push_count_chars(cmd_data->program_opts, SHARED_OPTS);
2027 #ifdef dynamic_link_version_func
2028 push_count_chars(cmd_data->program_opts,
2029 dynamic_link_version_func(cmd_data->version_info));
2032 add_dynamic_link_opts(cmd_data, cmd_data->program_opts);
2034 rv = run_command(cmd_data, cmd_data->shared_opts.normal);
2039 if (cmd_data->output == otProgram) {
2040 rv = run_command(cmd_data, cmd_data->arglist);
2048 char *l, libpath[PATH_MAX];
2050 strcpy(libpath, cmd_data->arglist->vals[0]);
2051 add_dotlibs(libpath);
2052 l = strrchr(libpath, '/');
2053 if (!l) l = strrchr(libpath, '\\');
2061 setenv(LD_LIBRARY_PATH_LOCAL, "./build/lib/.libs/", 1);
2062 rv = run_command(cmd_data, cmd_data->arglist);
2076 static void cleanup_tmp_dir(const char *dirname)
2079 struct dirent *entry;
2080 char fullname[1024];
2082 dir = opendir(dirname);
2087 while ((entry = readdir(dir)) != NULL) {
2088 if (entry->d_name[0] != '.') {
2089 strcpy(fullname, dirname);
2090 strcat(fullname, "/");
2091 strcat(fullname, entry->d_name);
2099 static void cleanup_tmp_dirs(command_t *cmd_data)
2103 for (d = 0; d < cmd_data->tmp_dirs->num; d++) {
2104 cleanup_tmp_dir(cmd_data->tmp_dirs->vals[d]);
2108 static int ensure_fake_uptodate(command_t *cmd_data)
2110 /* FIXME: could do the stat/touch here, but nah... */
2111 const char *touch_args[3];
2113 if (cmd_data->mode == mInstall) {
2116 if (!cmd_data->fake_output_name) {
2120 touch_args[0] = "touch";
2121 touch_args[1] = cmd_data->fake_output_name;
2122 touch_args[2] = NULL;
2123 return external_spawn(cmd_data, "touch", touch_args);
2126 /* Store the install path in the *.la file */
2127 static int add_for_runtime(command_t *cmd_data)
2129 if (cmd_data->mode == mInstall) {
2132 if (cmd_data->output == otDynamicLibraryOnly ||
2133 cmd_data->output == otLibrary) {
2134 FILE *f=fopen(cmd_data->fake_output_name,"w");
2138 fprintf(f,"%s\n", cmd_data->install_path);
2142 return(ensure_fake_uptodate(cmd_data));
2146 int main(int argc, char *argv[])
2151 memset(&cmd_data, 0, sizeof(cmd_data));
2153 cmd_data.options.pic_mode = pic_UNKNOWN;
2155 cmd_data.program_opts = (count_chars*)malloc(sizeof(count_chars));
2156 init_count_chars(cmd_data.program_opts);
2157 cmd_data.arglist = (count_chars*)malloc(sizeof(count_chars));
2158 init_count_chars(cmd_data.arglist);
2159 cmd_data.tmp_dirs = (count_chars*)malloc(sizeof(count_chars));
2160 init_count_chars(cmd_data.tmp_dirs);
2161 cmd_data.obj_files = (count_chars*)malloc(sizeof(count_chars));
2162 init_count_chars(cmd_data.obj_files);
2163 cmd_data.dep_rpaths = (count_chars*)malloc(sizeof(count_chars));
2164 init_count_chars(cmd_data.dep_rpaths);
2165 cmd_data.rpaths = (count_chars*)malloc(sizeof(count_chars));
2166 init_count_chars(cmd_data.rpaths);
2167 cmd_data.static_opts.normal = (count_chars*)malloc(sizeof(count_chars));
2168 init_count_chars(cmd_data.static_opts.normal);
2169 cmd_data.shared_opts.normal = (count_chars*)malloc(sizeof(count_chars));
2170 init_count_chars(cmd_data.shared_opts.normal);
2171 cmd_data.shared_opts.dependencies = (count_chars*)malloc(sizeof(count_chars));
2172 init_count_chars(cmd_data.shared_opts.dependencies);
2174 cmd_data.mode = mUnknown;
2175 cmd_data.output = otGeneral;
2177 parse_args(argc, argv, &cmd_data);
2178 post_parse_fixup(&cmd_data);
2180 if (cmd_data.mode == mUnknown) {
2184 rc = run_mode(&cmd_data);
2187 add_for_runtime(&cmd_data);
2190 cleanup_tmp_dirs(&cmd_data);