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"
184 #define LINK_cxx "g++"
188 #define LIBDIR "/usr/local/lib"
191 #define OBJDIR ".libs"
194 #error Unsupported platform: Please add defines for SHELL_CMD etc. for your platform.
206 #define PATH_MAX 1024
210 /* We want to say we are libtool 1.4 for shlibtool compatibility. */
211 #define VERSION "1.4"
227 otDynamicLibraryOnly,
263 count_chars *install;
264 count_chars *dependencies;
270 enum shared_mode_e shared;
273 enum pic_mode_e pic_mode;
279 enum tool_mode_t mode;
280 enum output_t output;
284 char *fake_output_name;
287 const char *install_path;
288 const char *compiler;
290 count_chars *program_opts;
292 count_chars *arglist;
293 count_chars *tmp_dirs;
294 count_chars *obj_files;
295 count_chars *dep_rpaths;
298 library_name static_name;
299 library_name shared_name;
300 library_name module_name;
302 library_opts static_opts;
303 library_opts shared_opts;
305 const char *version_info;
306 const char *undefined_flag;
310 static void add_rpath(count_chars *cc, const char *path);
313 static void usage(int code)
315 printf("Usage: jlibtool [OPTIONS...] COMMANDS...\n");
316 printf("jlibtool is a replacement for GNU libtool with similar functionality.\n\n");
318 printf(" --config show all configuration variables\n");
319 printf(" --debug enable verbose shell tracing\n");
320 printf(" --dry-run display commands without modifying any files\n");
321 printf(" --help display this help message and exit\n");
322 printf(" --mode=MODE use operational mode MODE (you *must* set mode)\n");
324 printf(" --silent don't print informational messages\n");
325 printf(" --tag=TAG Ignored for libtool compatibility\n");
326 printf(" --version print version information\n");
329 printf(" --shared Build shared libraries when using --mode=link\n");
330 printf(" --export-all Try to export 'def' file on some platforms\n");
332 printf("\nMODE must be one of the following:\n\n");
333 printf(" compile compile a source file into a jlibtool object\n");
334 printf(" execute automatically set library path, then run a program\n");
335 printf(" install install libraries or executables\n");
336 printf(" link create a library or an executable\n");
338 printf("\nMODE-ARGS can be the following:\n\n");
339 printf(" -export-dynamic accepted and ignored\n");
340 printf(" -module create a module when linking\n");
341 printf(" -shared create a shared library when linking\n");
342 printf(" -prefer-pic prefer position-independent-code when compiling\n");
343 printf(" -prefer-non-pic prefer non position-independent-code when compiling\n");
344 printf(" -static create a static library when linking\n");
345 printf(" -no-install link libraries locally\n");
346 printf(" -rpath arg Set install path for shared libraries\n");
347 printf(" -l arg pass '-l arg' to the link stage\n");
348 printf(" -L arg pass '-L arg' to the link stage\n");
349 printf(" -R dir add 'dir' to runtime library search path.\n");
350 printf(" -Zexe accepted and ignored\n");
351 printf(" -avoid-version accepted and ignored\n");
356 #if defined(NEED_SNPRINTF)
357 /* Write at most n characters to the buffer in str, return the
358 * number of chars written or -1 if the buffer would have been
361 * This is portable to any POSIX-compliant system has /dev/null
364 static int vsnprintf( char *str, size_t n, const char *fmt, va_list ap )
369 f = fopen("/dev/null","w");
373 setvbuf( f, str, _IOFBF, n );
375 res = vfprintf( f, fmt, ap );
377 if ( res > 0 && res < n ) {
378 res = vsprintf( str, fmt, ap );
382 static int snprintf( char *str, size_t n, const char *fmt, ... )
388 res = vsnprintf( str, n, fmt, ap );
394 static void init_count_chars(count_chars *cc)
396 cc->vals = (const char**)malloc(PATH_MAX*sizeof(char*));
400 static void clear_count_chars(count_chars *cc)
403 for (i = 0; i < cc->num; i++) {
410 static void push_count_chars(count_chars *cc, const char *newval)
412 cc->vals[cc->num++] = newval;
415 static void pop_count_chars(count_chars *cc)
420 static void insert_count_chars(count_chars *cc, const char *newval, int position)
424 for (i = cc->num; i > position; i--) {
425 cc->vals[i] = cc->vals[i-1];
428 cc->vals[position] = newval;
432 static void append_count_chars(count_chars *cc, count_chars *cctoadd)
435 for (i = 0; i < cctoadd->num; i++) {
436 if (cctoadd->vals[i]) {
437 push_count_chars(cc, cctoadd->vals[i]);
442 static const char *flatten_count_chars(count_chars *cc, int space)
448 for (i = 0; i < cc->num; i++) {
450 size += strlen(cc->vals[i]) + 1;
457 newval = (char*)malloc(size + 1);
460 for (i = 0; i < cc->num; i++) {
462 strcat(newval, cc->vals[i]);
472 static char *shell_esc(const char *str)
477 const unsigned char *s;
479 cmd = (char *)malloc(2 * strlen(str) + 3);
480 d = (unsigned char *)cmd;
481 s = (const unsigned char *)str;
492 else if (*s == '\\' || (*s == ' ' && (in_quote % 2))) {
506 static int external_spawn(command_t *cmd, const char *file, const char **argv)
508 file = file; /* -Wunused */
510 if (!cmd->options.silent) {
511 const char **argument = argv;
512 printf("Executing: ");
514 printf("%s ", *argument);
520 if (cmd->options.dry_run) {
523 #if defined(__EMX__) || defined(__MINGW32__)
524 return spawnvp(P_WAIT, argv[0], argv);
530 return execvp(argv[0], (char**)argv);
534 waitpid(pid, &statuscode, 0);
535 if (WIFEXITED(statuscode)) {
536 return WEXITSTATUS(statuscode);
544 static int run_command(command_t *cmd_data, count_chars *cc)
550 const char *spawn_args[4];
553 init_count_chars(&tmpcc);
555 if (cmd_data->program) {
556 push_count_chars(&tmpcc, cmd_data->program);
559 append_count_chars(&tmpcc, cmd_data->program_opts);
561 append_count_chars(&tmpcc, cc);
563 raw = flatten_count_chars(&tmpcc, 1);
564 command = shell_esc(raw);
566 memcpy(&tmp, &raw, sizeof(tmp));
569 spawn_args[0] = SHELL_CMD;
570 spawn_args[1] = "-c";
571 spawn_args[2] = command;
572 spawn_args[3] = NULL;
573 ret = external_spawn(cmd_data, spawn_args[0], spawn_args);
581 * print configuration
582 * shlibpath_var is used in configure.
584 #define printc(_x,_y) if (!value || !strcmp(value, _x)) printf(_x "=\"%s\"\n", _y)
586 static void print_config(const char *value)
589 printc("runpath_var", LD_RUN_PATH);
591 #ifdef LD_LIBRARY_PATH
592 printc("shlibpath_var", LD_LIBRARY_PATH);
594 #ifdef LD_LIBRARY_PATH_LOCAL
595 printc("shlocallibpath_var", LD_LIBRARY_PATH_LOCAL);
598 printc("SHELL", SHELL_CMD);
601 printc("objext", OBJECT_EXT);
604 printc("objdir", OBJDIR);
606 #ifdef DYNAMIC_LIB_EXT
607 /* add a '.' prefix because libtool does that. */
608 printc("shrext_cmds", "echo ." DYNAMIC_LIB_EXT);
609 /* add a '.' prefix because libtool does that. */
610 printc("shrext", "." DYNAMIC_LIB_EXT);
613 printc("exeext", EXE_EXT);
615 #ifdef STATIC_LIB_EXT
616 printc("libext", STATIC_LIB_EXT);
619 printc("AR", LIBRARIAN);
621 #ifdef LIBRARIAN_OPTS
622 printc("AR_FLAGS", LIBRARIAN_OPTS);
624 #ifdef LINKER_FLAG_PREFIX
625 printc("wl", LINKER_FLAG_PREFIX);
628 printc("ranlib", RANLIB);
633 * Add a directory to the runtime library search path.
635 static void add_runtimedirlib(char *arg, command_t *cmd_data)
638 add_rpath(cmd_data->shared_opts.dependencies, arg);
640 arg = arg; /* -Wunused */
645 static int parse_long_opt(char *arg, command_t *cmd_data)
647 char *equal_pos = strchr(arg, '=');
652 strncpy(var, arg, equal_pos - arg);
653 var[equal_pos - arg] = 0;
654 strlcpy(value, equal_pos + 1, sizeof(var));
656 strncpy(var, arg, sizeof(var) - 1);
657 var[sizeof(var) - 1] = '\0';
662 if (strcmp(var, "silent") == 0) {
663 cmd_data->options.silent = 1;
664 } else if (strcmp(var, "quiet") == 0) {
665 cmd_data->options.silent = 1;
666 } else if (strcmp(var, "debug") == 0) {
667 cmd_data->options.debug = 1;
668 } else if (strcmp(var, "mode") == 0) {
669 if (cmd_data->mode != mUnknown) {
670 fprintf(stderr, "Cannot set --mode twice\n");
674 if (strcmp(value, "compile") == 0) {
675 cmd_data->mode = mCompile;
676 cmd_data->output = otObject;
678 } else if (strcmp(value, "link") == 0) {
679 cmd_data->mode = mLink;
680 cmd_data->output = otLibrary;
682 } else if (strcmp(value, "install") == 0) {
683 cmd_data->mode = mInstall;
685 } else if (strcmp(value, "execute") == 0) {
686 cmd_data->mode = mExecute;
689 printf("Unknown mode \"%s\"\n", value);
691 } else if (strcmp(var, "shared") == 0) {
692 if ((cmd_data->mode == mLink) &&
693 (cmd_data->output == otGeneral)) {
694 cmd_data->output = otDynamicLibraryOnly;
696 cmd_data->options.shared = share_SHARED;
697 } else if (strcmp(var, "export-all") == 0) {
698 cmd_data->options.export_all = 1;
699 } else if (strcmp(var, "dry-run") == 0) {
700 printf("Dry-run mode on!\n");
701 cmd_data->options.dry_run = 1;
702 } else if (strcmp(var, "version") == 0) {
703 printf("Version " VERSION "\n");
704 } else if (strcmp(var, "help") == 0) {
706 } else if (strcmp(var, "config") == 0) {
709 } else if (strcmp(var, "tag") == 0) {
710 if (strcmp(value, "CC") == 0) {
713 if (strcmp(value, "CXX") == 0) {
723 /* Return 1 if we eat it. */
724 static int parse_short_opt(char *arg, command_t *cmd_data)
726 if (strcmp(arg, "export-dynamic") == 0) {
727 cmd_data->options.export_dynamic = 1;
731 if (strcmp(arg, "module") == 0) {
732 cmd_data->output = otModule;
736 if (strcmp(arg, "shared") == 0) {
737 if (cmd_data->mode == mLink) {
738 cmd_data->output = otDynamicLibraryOnly;
740 cmd_data->options.shared = share_SHARED;
744 if (strcmp(arg, "Zexe") == 0) {
748 if (strcmp(arg, "avoid-version") == 0) {
752 if (strcmp(arg, "prefer-pic") == 0) {
753 cmd_data->options.pic_mode = pic_PREFER;
757 if (strcmp(arg, "prefer-non-pic") == 0) {
758 cmd_data->options.pic_mode = pic_AVOID;
762 if (strcmp(arg, "static") == 0) {
763 if ((cmd_data->mode == mLink) &&
764 (cmd_data->output == otLibrary)) {
765 cmd_data->output = otStaticLibraryOnly;
767 cmd_data->options.shared = share_STATIC;
771 if (cmd_data->mode == mLink) {
772 if (strcmp(arg, "no-install") == 0) {
773 cmd_data->options.no_install = 1;
776 if (arg[0] == 'L' || arg[0] == 'l') {
779 push_count_chars(cmd_data->shared_opts.dependencies, arg);
781 } else if (arg[0] == 'R' && arg[1]) {
782 /* -Rdir Add dir to runtime library search path. */
783 add_runtimedirlib(&arg[1], cmd_data);
790 #ifdef TRUNCATE_DLL_NAME
791 static char *truncate_dll_name(char *path)
793 /* Cut DLL name down to 8 characters after removing any mod_ prefix */
794 char *tmppath = strdup(path);
795 char *newname = strrchr(tmppath, '/') + 1;
796 char *ext = strrchr(newname, '.');
804 if (strncmp(newname, "mod_", 4) == 0) {
805 strcpy(newname, newname + 4);
810 strcpy(newname + 8, strchr(newname, '.'));
817 static long safe_strtol(const char *nptr, const char **endptr, int base)
823 rv = strtol(nptr, (char**)endptr, 10);
825 if (errno == ERANGE) {
832 static void safe_mkdir(const char *path)
837 old_umask = umask(0);
840 #ifdef MKDIR_NO_UMASK
841 status = mkdir(path);
843 status = mkdir(path, ~old_umask);
845 if ((status < 0) && (errno != EEXIST)) {
846 printf("Warning: mkdir of %s failed\n", path);
850 /* returns just a file's name without the path */
851 static const char *jlibtool_basename(const char *fullpath)
853 const char *name = strrchr(fullpath, '/');
856 name = strrchr(fullpath, '\\');
869 /* returns just a file's name without path or extension */
870 static const char *nameof(const char *fullpath)
875 name = jlibtool_basename(fullpath);
876 ext = strrchr(name, '.');
880 trimmed = malloc(ext - name + 1);
881 strncpy(trimmed, name, ext - name);
882 trimmed[ext-name] = 0;
890 /* version_info is in the form of MAJOR:MINOR:PATCH */
891 static const char *darwin_dynamic_link_function(const char *version_info)
894 long major, minor, patch;
901 major = safe_strtol(version_info, &version_info, 10);
904 if (version_info[0] == ':') {
908 minor = safe_strtol(version_info, &version_info, 10);
911 if (version_info[0] == ':') {
915 patch = safe_strtol(version_info, &version_info, 10);
921 /* Avoid -dylib_compatibility_version must be greater than zero errors. */
925 newarg = (char*)malloc(100);
927 "-compatibility_version %ld -current_version %ld.%ld",
928 major, major, minor);
935 * Add a '.libs/' to the buffer. The caller ensures that
936 * The buffer is large enough to handle 6 extra characters.
938 static void add_dotlibs(char *buffer)
940 char *name = strrchr(buffer, '/');
944 strcpy(buffer, ".libs/");
951 memmove(name + 6, name, strlen(name));
952 memcpy(name, ".libs/", 6);
955 static char *gen_library_name(const char *name, enum lib_type genlib)
957 char *newarg, *newext;
959 newarg = (char *)calloc(strlen(name) + 11, 1);
961 if (genlib == type_MODULE_LIB && strncmp(name, "lib", 3) == 0) {
965 if (genlib == type_MODULE_LIB) {
966 strcpy(newarg, jlibtool_basename(name));
969 strcpy(newarg, name);
972 newext = strrchr(newarg, '.');
974 printf("Error: Library path does not have an extension");
982 case type_STATIC_LIB:
983 strcpy(newext, STATIC_LIB_EXT);
985 case type_DYNAMIC_LIB:
986 strcpy(newext, DYNAMIC_LIB_EXT);
988 case type_MODULE_LIB:
989 strcpy(newext, MODULE_LIB_EXT);
1001 static char *gen_install_name(const char *name, enum lib_type genlib)
1007 newname = gen_library_name(name, genlib);
1008 if (!newname) return NULL;
1010 /* Check if it exists. If not, return NULL. */
1011 rv = stat(newname, &sb);
1021 static const char *check_object_exists(command_t *cmd, const char *arg, int arglen)
1026 newarg = (char *)malloc(arglen + 10);
1027 memcpy(newarg, arg, arglen);
1029 ext = newarg + arglen;
1038 strcpy(ext, OBJECT_EXT);
1042 strcpy(ext, NO_PIC_EXT);
1049 if (cmd->options.debug) {
1050 printf("Checking (obj): %s\n", newarg);
1052 rv = stat(newarg, &sb);
1054 while (rv != 0 && ++pass < 1);
1065 /* libdircheck values:
1066 * 0 - no .libs suffix
1069 static char *check_library_exists(command_t *cmd, const char *arg, int pathlen,
1070 int libdircheck, enum lib_type *libtype)
1073 int pass, rv, newpathlen;
1075 newarg = (char *)malloc(strlen(arg) + 10);
1076 strcpy(newarg, arg);
1077 newarg[pathlen] = '\0';
1079 newpathlen = pathlen;
1081 add_dotlibs(newarg);
1082 newpathlen += sizeof(".libs/") - 1;
1085 strcpy(newarg + newpathlen, arg + pathlen);
1086 ext = strrchr(newarg, '.');
1088 printf("Error: Library path does not have an extension");
1102 if (cmd->options.pic_mode != pic_AVOID &&
1103 cmd->options.shared != share_STATIC) {
1104 strcpy(ext, DYNAMIC_LIB_EXT);
1105 *libtype = type_DYNAMIC_LIB;
1111 strcpy(ext, STATIC_LIB_EXT);
1112 *libtype = type_STATIC_LIB;
1115 strcpy(ext, MODULE_LIB_EXT);
1116 *libtype = type_MODULE_LIB;
1119 strcpy(ext, OBJECT_EXT);
1120 *libtype = type_OBJECT;
1123 *libtype = type_UNKNOWN;
1127 if (cmd->options.debug) {
1128 printf("Checking (lib): %s\n", newarg);
1130 rv = stat(newarg, &sb);
1132 while (rv != 0 && ++pass < 4);
1143 static char * load_install_path(const char *arg)
1153 path = malloc(PATH_MAX);
1155 fgets(path, PATH_MAX, f);
1158 if (path[strlen(path)-1] == '\n') {
1159 path[strlen(path)-1] = '\0';
1162 /* Check that we have an absolute path.
1163 * Otherwise the file could be a GNU libtool file.
1165 if (path[0] != '/') {
1173 static char * load_noinstall_path(const char *arg, int pathlen)
1175 char *newarg, *expanded_path;
1178 newarg = (char *)malloc(strlen(arg) + 10);
1179 strcpy(newarg, arg);
1180 newarg[pathlen] = 0;
1182 newpathlen = pathlen;
1183 strcat(newarg, ".libs");
1184 newpathlen += sizeof(".libs") - 1;
1185 newarg[newpathlen] = 0;
1188 expanded_path = malloc(PATH_MAX);
1189 expanded_path = realpath(newarg, expanded_path);
1190 /* Uh, oh. There was an error. Fall back on our first guess. */
1191 if (!expanded_path) {
1192 expanded_path = newarg;
1195 /* We might get ../ or something goofy. Oh, well. */
1196 expanded_path = newarg;
1199 return expanded_path;
1202 static void add_dynamic_link_opts(command_t *cmd_data, count_chars *args)
1204 #ifdef DYNAMIC_LINK_OPTS
1205 if (cmd_data->options.pic_mode != pic_AVOID) {
1206 if (cmd_data->options.debug) {
1207 printf("Adding: %s\n", DYNAMIC_LINK_OPTS);
1209 push_count_chars(args, DYNAMIC_LINK_OPTS);
1210 if (cmd_data->undefined_flag) {
1211 push_count_chars(args, "-undefined");
1212 #if defined(__APPLE__)
1213 /* -undefined dynamic_lookup is used by the bundled Python in
1214 * 10.4, but if we don't set MACOSX_DEPLOYMENT_TARGET to 10.3+,
1215 * we'll get a linker error if we pass this flag.
1217 if (strcasecmp(cmd_data->undefined_flag,
1218 "dynamic_lookup") == 0) {
1219 insert_count_chars(cmd_data->program_opts,
1220 "MACOSX_DEPLOYMENT_TARGET=10.3", 0);
1223 push_count_chars(args, cmd_data->undefined_flag);
1226 #ifdef DYNAMIC_LINK_UNDEFINED
1227 if (cmd_data->options.debug) {
1228 printf("Adding: %s\n", DYNAMIC_LINK_UNDEFINED);
1230 push_count_chars(args, DYNAMIC_LINK_UNDEFINED);
1237 /* Read the final install location and add it to runtime library search path. */
1239 static void add_rpath(count_chars *cc, const char *path)
1244 #ifdef LINKER_FLAG_PREFIX
1245 size = strlen(LINKER_FLAG_PREFIX);
1247 size = size + strlen(path) + strlen(RPATH) + 2;
1252 #ifdef LINKER_FLAG_PREFIX
1253 strcpy(tmp, LINKER_FLAG_PREFIX);
1258 #ifndef LINKER_FLAG_NO_EQUALS
1263 push_count_chars(cc, tmp);
1266 static void add_rpath_file(count_chars *cc, const char *arg)
1270 path = load_install_path(arg);
1272 add_rpath(cc, path);
1277 static void add_rpath_noinstall(count_chars *cc, const char *arg, int pathlen)
1281 path = load_noinstall_path(arg, pathlen);
1283 add_rpath(cc, path);
1289 #ifdef DYNAMIC_LINK_NO_INSTALL
1290 static void add_dylink_noinstall(count_chars *cc, const char *arg, int pathlen,
1293 const char *install_path, *current_path, *name;
1295 int i_p_len, c_p_len, name_len, dyext_len, cur_len;
1297 install_path = load_install_path(arg);
1298 current_path = load_noinstall_path(arg, pathlen);
1300 if (!install_path || !current_path) {
1304 push_count_chars(cc, DYNAMIC_LINK_NO_INSTALL);
1306 i_p_len = strlen(install_path);
1307 c_p_len = strlen(current_path);
1310 name_len = extlen-pathlen;
1311 dyext_len = sizeof(DYNAMIC_LIB_EXT) - 1;
1313 /* No, we need to replace the extension. */
1314 exp_argument = (char *)malloc(i_p_len + c_p_len + (name_len*2) +
1318 strcpy(exp_argument, install_path);
1320 exp_argument[cur_len++] = '/';
1321 strncpy(exp_argument+cur_len, name, extlen-pathlen);
1322 cur_len += name_len;
1323 strcpy(exp_argument+cur_len, DYNAMIC_LIB_EXT);
1324 cur_len += dyext_len;
1325 exp_argument[cur_len++] = ':';
1326 strcpy(exp_argument+cur_len, current_path);
1328 exp_argument[cur_len++] = '/';
1329 strncpy(exp_argument+cur_len, name, extlen-pathlen);
1330 cur_len += name_len;
1331 strcpy(exp_argument+cur_len, DYNAMIC_LIB_EXT);
1332 cur_len += dyext_len;
1334 push_count_chars(cc, exp_argument);
1339 /* use -L -llibname to allow to use installed libraries */
1340 static void add_minus_l(count_chars *cc, const char *arg)
1343 char *name = strrchr(arg, '/');
1344 char *file = strrchr(arg, '.');
1346 if ((name != NULL) && (file != NULL) &&
1347 (strstr(name, "lib") == (name + 1))) {
1352 push_count_chars(cc, "-L");
1353 push_count_chars(cc, arg);
1354 /* we need one argument like -lapr-1 */
1355 newarg = malloc(strlen(file) + 3);
1356 strcpy(newarg, "-l");
1357 strcat(newarg, file);
1358 push_count_chars(cc, newarg);
1360 push_count_chars(cc, arg);
1366 static void add_linker_flag_prefix(count_chars *cc, const char *arg)
1368 #ifndef LINKER_FLAG_PREFIX
1369 push_count_chars(cc, arg);
1372 newarg = (char*)malloc(strlen(arg) + sizeof(LINKER_FLAG_PREFIX) + 1);
1373 strcpy(newarg, LINKER_FLAG_PREFIX);
1374 strcat(newarg, arg);
1375 push_count_chars(cc, newarg);
1380 static int explode_static_lib(command_t *cmd_data, const char *lib)
1382 count_chars tmpdir_cc, libname_cc;
1383 const char *tmpdir, *libname;
1384 char savewd[PATH_MAX];
1387 struct dirent *entry;
1388 const char *lib_args[4];
1391 if (cmd_data->options.dry_run) {
1395 name = jlibtool_basename(lib);
1397 init_count_chars(&tmpdir_cc);
1398 push_count_chars(&tmpdir_cc, ".libs/");
1399 push_count_chars(&tmpdir_cc, name);
1400 push_count_chars(&tmpdir_cc, ".exploded/");
1401 tmpdir = flatten_count_chars(&tmpdir_cc, 0);
1403 if (!cmd_data->options.silent) {
1404 printf("Making: %s\n", tmpdir);
1408 push_count_chars(cmd_data->tmp_dirs, tmpdir);
1410 getcwd(savewd, sizeof(savewd));
1412 if (chdir(tmpdir) != 0) {
1413 if (!cmd_data->options.silent) {
1414 printf("Warning: could not explode %s\n", lib);
1419 if (lib[0] == '/') {
1423 init_count_chars(&libname_cc);
1424 push_count_chars(&libname_cc, "../../");
1425 push_count_chars(&libname_cc, lib);
1426 libname = flatten_count_chars(&libname_cc, 0);
1429 lib_args[0] = LIBRARIAN;
1431 lib_args[2] = libname;
1434 external_spawn(cmd_data, LIBRARIAN, lib_args);
1437 dir = opendir(tmpdir);
1439 while ((entry = readdir(dir)) != NULL) {
1440 #if defined(__APPLE__) && defined(RANLIB)
1441 /* Apple inserts __.SYMDEF which isn't needed.
1442 * Leopard (10.5+) can also add '__.SYMDEF SORTED' which isn't
1443 * much fun either. Just skip them.
1445 if (strstr(entry->d_name, "__.SYMDEF") != NULL) {
1449 if (entry->d_name[0] != '.') {
1450 push_count_chars(&tmpdir_cc, entry->d_name);
1451 name = flatten_count_chars(&tmpdir_cc, 0);
1452 if (cmd_data->options.debug) {
1453 printf("Adding: %s\n", name);
1455 push_count_chars(cmd_data->obj_files, name);
1456 pop_count_chars(&tmpdir_cc);
1464 static int parse_input_file_name(char *arg, command_t *cmd_data)
1466 const char *ext = strrchr(arg, '.');
1469 enum lib_type libtype;
1477 name = jlibtool_basename(arg);
1479 pathlen = name - arg;
1481 if (strcmp(ext, "lo") == 0) {
1482 newarg = check_object_exists(cmd_data, arg, ext - arg);
1484 fprintf(stderr, "Can not find suitable object file for %s\n", arg);
1487 if (cmd_data->mode != mLink) {
1488 push_count_chars(cmd_data->arglist, newarg);
1491 push_count_chars(cmd_data->obj_files, newarg);
1496 if (strcmp(ext, "la") == 0) {
1497 switch (cmd_data->mode) {
1499 /* Try the .libs dir first! */
1500 newarg = check_library_exists(cmd_data, arg, pathlen, 1, &libtype);
1502 /* Try the normal dir next. */
1503 newarg = check_library_exists(cmd_data, arg, pathlen, 0, &libtype);
1505 fprintf(stderr, "Can not find suitable library for %s\n", arg);
1510 /* It is not ok to just add the file: a library may added with:
1511 1 - -L path library_name. (For *.so in Linux).
1515 if (libtype == type_DYNAMIC_LIB) {
1516 add_minus_l(cmd_data->shared_opts.dependencies, newarg);
1517 } else if (cmd_data->output == otLibrary &&
1518 libtype == type_STATIC_LIB) {
1519 explode_static_lib(cmd_data, newarg);
1521 push_count_chars(cmd_data->shared_opts.dependencies, newarg);
1524 if (cmd_data->output == otLibrary && libtype == type_STATIC_LIB) {
1525 explode_static_lib(cmd_data, newarg);
1528 push_count_chars(cmd_data->shared_opts.dependencies, newarg);
1531 if (libtype == type_DYNAMIC_LIB) {
1532 if (cmd_data->options.no_install) {
1534 add_rpath_noinstall(cmd_data->shared_opts.dependencies,
1537 #ifdef DYNAMIC_LINK_NO_INSTALL
1539 * This doesn't work as Darwin's linker has no way to
1540 * override at link-time the search paths for a
1541 * non-installed library.
1544 add_dylink_noinstall(cmd_data->shared_opts.dependencies,
1545 arg, pathlen, ext - arg);
1551 add_rpath_file(cmd_data->shared_opts.dependencies, arg);
1557 /* If we've already recorded a library to install, we're most
1558 * likely getting the .la file that we want to install as.
1559 * The problem is that we need to add it as the directory,
1560 * not the .la file itself. Otherwise, we'll do odd things.
1562 if (cmd_data->output == otLibrary) {
1563 arg[pathlen] = '\0';
1564 push_count_chars(cmd_data->arglist, arg);
1567 cmd_data->output = otLibrary;
1568 cmd_data->output_name = arg;
1569 cmd_data->static_name.install = gen_install_name(arg, 0);
1570 cmd_data->shared_name.install = gen_install_name(arg, 1);
1571 cmd_data->module_name.install = gen_install_name(arg, 2);
1573 if (!cmd_data->static_name.install &&
1574 !cmd_data->shared_name.install &&
1575 !cmd_data->module_name.install) {
1576 fprintf(stderr, "Files to install do not exist\n");
1588 if (strcmp(ext, "c") == 0) {
1589 /* If we don't already have an idea what our output name will be. */
1590 if (cmd_data->basename == NULL) {
1591 cmd_data->basename = (char *)malloc(strlen(arg) + 4);
1592 strcpy(cmd_data->basename, arg);
1593 strcpy(strrchr(cmd_data->basename, '.') + 1, "lo");
1595 cmd_data->fake_output_name = strrchr(cmd_data->basename, '/');
1596 if (cmd_data->fake_output_name) {
1597 cmd_data->fake_output_name++;
1600 cmd_data->fake_output_name = cmd_data->basename;
1608 static int parse_output_file_name(char *arg, command_t *cmd_data)
1612 char *newarg = NULL;
1615 cmd_data->fake_output_name = arg;
1617 name = jlibtool_basename(arg);
1618 ext = strrchr(name, '.');
1621 if (!ext || strcmp(ext, EXE_EXT) == 0) {
1625 cmd_data->basename = arg;
1626 cmd_data->output = otProgram;
1627 #if defined(_OSD_POSIX)
1628 cmd_data->options.pic_mode = pic_AVOID;
1630 newarg = (char *)malloc(strlen(arg) + 5);
1631 strcpy(newarg, arg);
1634 strcat(newarg, EXE_EXT);
1637 cmd_data->output_name = newarg;
1642 pathlen = name - arg;
1644 if (strcmp(ext, "la") == 0) {
1645 assert(cmd_data->mode == mLink);
1647 cmd_data->basename = arg;
1648 cmd_data->static_name.normal = gen_library_name(arg, type_STATIC_LIB);
1649 cmd_data->shared_name.normal = gen_library_name(arg, type_DYNAMIC_LIB);
1650 cmd_data->module_name.normal = gen_library_name(arg, type_MODULE_LIB);
1651 cmd_data->static_name.install = gen_install_name(arg, type_STATIC_LIB);
1652 cmd_data->shared_name.install = gen_install_name(arg, type_DYNAMIC_LIB);
1653 cmd_data->module_name.install = gen_install_name(arg, type_MODULE_LIB);
1655 if (!cmd_data->options.dry_run) {
1658 newname = malloc(strlen(cmd_data->static_name.normal) + 1);
1660 strcpy(newname, cmd_data->static_name.normal);
1661 newext = strrchr(newname, '/');
1663 /* Check first to see if the dir already exists! */
1664 safe_mkdir(".libs");
1667 safe_mkdir(newname);
1672 #ifdef TRUNCATE_DLL_NAME
1674 arg = truncate_dll_name(arg);
1678 cmd_data->output_name = arg;
1682 if (strcmp(ext, STATIC_LIB_EXT) == 0) {
1683 assert(cmd_data->mode == mLink);
1685 cmd_data->basename = arg;
1686 cmd_data->options.shared = share_STATIC;
1687 cmd_data->output = otStaticLibraryOnly;
1688 cmd_data->static_name.normal = gen_library_name(arg, type_STATIC_LIB);
1689 cmd_data->static_name.install = gen_install_name(arg, type_STATIC_LIB);
1691 if (!cmd_data->options.dry_run) {
1694 newname = malloc(strlen(cmd_data->static_name.normal) + 1);
1696 strcpy(newname, cmd_data->static_name.normal);
1697 newext = strrchr(newname, '/');
1699 /* Check first to see if the dir already exists! */
1700 safe_mkdir(".libs");
1703 safe_mkdir(newname);
1708 cmd_data->output_name = arg;
1712 if (strcmp(ext, DYNAMIC_LIB_EXT) == 0) {
1713 assert(cmd_data->mode == mLink);
1715 cmd_data->basename = arg;
1716 cmd_data->options.shared = share_SHARED;
1717 cmd_data->output = otDynamicLibraryOnly;
1718 cmd_data->shared_name.normal = gen_library_name(arg, type_DYNAMIC_LIB);
1719 cmd_data->module_name.normal = gen_library_name(arg, type_MODULE_LIB);
1720 cmd_data->shared_name.install = gen_install_name(arg, type_DYNAMIC_LIB);
1721 cmd_data->module_name.install = gen_install_name(arg, type_MODULE_LIB);
1723 if (!cmd_data->options.dry_run) {
1726 newname = malloc(strlen(cmd_data->shared_name.normal) + 1);
1728 strcpy(newname, cmd_data->shared_name.normal);
1729 newext = strrchr(newname, '/');
1731 /* Check first to see if the dir already exists! */
1732 safe_mkdir(".libs");
1735 safe_mkdir(newname);
1740 cmd_data->output_name = arg;
1744 if (strcmp(ext, "lo") == 0) {
1746 cmd_data->basename = arg;
1747 cmd_data->output = otObject;
1748 newarg = (char *)malloc(strlen(arg) + 2);
1749 strcpy(newarg, arg);
1750 newext = strrchr(newarg, '.') + 1;
1751 strcpy(newext, OBJECT_EXT);
1752 cmd_data->output_name = newarg;
1756 if (strcmp(ext, DYNAMIC_LIB_EXT) == 0) {
1757 fprintf(stderr, "Please build libraries with .la target, not ."
1758 DYNAMIC_LIB_EXT "\n");
1762 if (strcmp(ext, STATIC_LIB_EXT) == 0) {
1763 fprintf(stderr, "Please build libraries with .la target, not ."
1764 STATIC_LIB_EXT "\n");
1771 static char *automode(char *arg, command_t *cmd_data)
1773 if (cmd_data->mode != mUnknown) return arg;
1775 if (strcmp(arg, "CC") == 0) {
1777 cmd_data->mode = mCompile;
1779 } else if (strcmp(arg, "CXX") == 0) {
1781 cmd_data->mode = mCompile;
1783 } else if (strcmp(arg, "LINK") == 0) {
1785 cmd_data->mode = mLink;
1787 } else if (strcmp(arg, "LINK.c") == 0) {
1789 cmd_data->mode = mLink;
1791 } else if (strcmp(arg, "LINK.cxx") == 0) {
1793 cmd_data->mode = mLink;
1799 static void parse_args(int argc, char *argv[], command_t *cmd_data)
1806 * We now take a major step past libtool.
1808 * IF there's no "--mode=...", AND we recognise
1809 * the binary as a "special" name, THEN replace it
1810 * with the correct one, and set the correct mode.
1812 base = jlibtool_basename(argv[0]);
1813 arg = automode(base, cmd_data);
1816 if (cmd_data->options.debug) {
1817 printf("Adding: %s\n", arg);
1819 push_count_chars(cmd_data->arglist, arg);
1820 assert(cmd_data->mode != mUnknown);
1824 * We first pass over the command-line arguments looking for
1825 * "--mode", etc. If so, then use the libtool compatibility
1826 * method for building the software. Otherwise, auto-detect it
1827 * via "-o" and the extensions.
1830 if (cmd_data->mode == mUnknown) for (a = 1; a < argc; a++) {
1833 if (strncmp(arg, "--mode=", 7) == 0) {
1839 * Stop if we get another magic method
1842 ((strncmp(arg, "LINK", 4) == 0) ||
1843 (strcmp(arg, "CC") == 0) ||
1844 (strcmp(arg, "CXX") == 0))) {
1849 if (strncmp(arg, "-o", 2) == 0) {
1855 arg = strrchr(base, '.');
1857 cmd_data->mode = mLink;
1858 push_count_chars(cmd_data->arglist, LINK_c);
1861 else if (strcmp(arg, EXE_EXT) == 0) {
1862 cmd_data->mode = mLink;
1863 push_count_chars(cmd_data->arglist, LINK_c);
1866 else if (strcmp(arg + 1, DYNAMIC_LIB_EXT) == 0) {
1867 cmd_data->mode = mLink;
1868 push_count_chars(cmd_data->arglist, LINK_c);
1870 else if (strcmp(arg + 1, STATIC_LIB_EXT) == 0) {
1871 cmd_data->mode = mLink;
1872 push_count_chars(cmd_data->arglist, LINK_c);
1874 else if (strcmp(arg + 1, "la") == 0) {
1875 cmd_data->mode = mLink;
1876 push_count_chars(cmd_data->arglist, LINK_c);
1878 else if ((strcmp(arg + 1, "lo") == 0) ||
1879 (strcmp(arg + 1, "o") == 0)) {
1880 cmd_data->mode = mCompile;
1881 push_count_chars(cmd_data->arglist, CC);
1885 for (a = 1; a < argc; a++) {
1889 if (arg[0] == '-') {
1890 if (arg[1] == '-') {
1891 argused = parse_long_opt(arg + 2, cmd_data);
1894 argused = parse_short_opt(arg + 1, cmd_data);
1897 /* We haven't done anything with it yet, try some of the
1898 * more complicated short opts... */
1899 if (argused == 0 && a + 1 < argc) {
1900 if (arg[1] == 'o' && !arg[2]) {
1902 argused = parse_output_file_name(arg, cmd_data);
1903 } else if (strcmp(arg+1, "MT") == 0) {
1904 if (cmd_data->options.debug) {
1905 printf("Adding: %s\n", arg);
1907 push_count_chars(cmd_data->arglist, arg);
1909 if (!cmd_data->options.silent) {
1910 printf(" %s\n", arg);
1912 push_count_chars(cmd_data->arglist, arg);
1914 } else if (strcmp(arg+1, "rpath") == 0) {
1915 /* Aha, we should try to link both! */
1916 cmd_data->install_path = argv[++a];
1918 } else if (strcmp(arg+1, "release") == 0) {
1919 /* Store for later deciphering */
1920 cmd_data->version_info = argv[++a];
1922 } else if (strcmp(arg+1, "version-info") == 0) {
1923 /* Store for later deciphering */
1924 cmd_data->version_info = argv[++a];
1926 } else if (strcmp(arg+1, "export-symbols-regex") == 0) {
1927 /* Skip the argument. */
1930 } else if (strcmp(arg+1, "release") == 0) {
1931 /* Skip the argument. */
1934 } else if (strcmp(arg+1, "undefined") == 0) {
1935 cmd_data->undefined_flag = argv[++a];
1937 } else if (arg[1] == 'R' && !arg[2]) {
1938 /* -R dir Add dir to runtime library search path. */
1939 add_runtimedirlib(argv[++a], cmd_data);
1944 argused = parse_input_file_name(arg, cmd_data);
1949 * If we still don't have a run mode, look for a magic
1950 * program name CC, LINK, or whatever. Then replace that
1951 * with the name of the real program we want to run.
1953 if ((cmd_data->arglist->num == 0) &&
1954 (cmd_data->mode == mUnknown)) {
1955 arg = automode(arg, cmd_data);
1958 if (cmd_data->options.debug) {
1959 printf("Adding: %s\n", arg);
1961 push_count_chars(cmd_data->arglist, arg);
1968 static void generate_def_file(command_t *cmd_data)
1970 char def_file[1024];
1971 char implib_file[1024];
1974 char *export_args[1024];
1975 int num_export_args = 0;
1980 if (cmd_data->output_name) {
1981 strcpy(def_file, cmd_data->output_name);
1982 strcat(def_file, ".def");
1983 hDef = fopen(def_file, "w");
1986 fprintf(hDef, "LIBRARY '%s' INITINSTANCE\n", nameof(cmd_data->output_name));
1987 fprintf(hDef, "DATA NONSHARED\n");
1988 fprintf(hDef, "EXPORTS\n");
1991 for (a = 0; a < cmd_data->num_obj_files; a++) {
1992 cmd_size += strlen(cmd_data->obj_files[a]) + 1;
1995 cmd_size += strlen(GEN_EXPORTS) + strlen(def_file) + 3;
1996 cmd = (char *)malloc(cmd_size);
1997 strcpy(cmd, GEN_EXPORTS);
1999 for (a=0; a < cmd_data->num_obj_files; a++) {
2001 strcat(cmd, cmd_data->obj_files[a] );
2005 strcat(cmd, def_file);
2007 export_args[num_export_args++] = SHELL_CMD;
2008 export_args[num_export_args++] = "-c";
2009 export_args[num_export_args++] = cmd;
2010 export_args[num_export_args++] = NULL;
2011 external_spawn(cmd_data, export_args[0], (const char**)export_args);
2012 cmd_data->arglist[cmd_data->num_args++] = strdup(def_file);
2014 /* Now make an import library for the dll */
2015 num_export_args = 0;
2016 export_args[num_export_args++] = DEF2IMPLIB_CMD;
2017 export_args[num_export_args++] = "-o";
2019 strcpy(implib_file, ".libs/");
2020 strcat(implib_file, cmd_data->basename);
2021 ext = strrchr(implib_file, '.');
2026 strcat(implib_file, ".");
2027 strcat(implib_file, STATIC_LIB_EXT);
2029 export_args[num_export_args++] = implib_file;
2030 export_args[num_export_args++] = def_file;
2031 export_args[num_export_args++] = NULL;
2032 external_spawn(cmd_data, export_args[0], (const char**)export_args);
2040 static const char* expand_path(const char *relpath)
2042 char foo[PATH_MAX], *newpath;
2044 getcwd(foo, PATH_MAX-1);
2045 newpath = (char*)malloc(strlen(foo)+strlen(relpath)+2);
2046 strcpy(newpath, foo);
2047 strcat(newpath, "/");
2048 strcat(newpath, relpath);
2053 static void link_fixup(command_t *c)
2055 /* If we were passed an -rpath directive, we need to build
2056 * shared objects too. Otherwise, we should only create static
2059 if (!c->install_path && (c->output == otDynamicLibraryOnly ||
2060 c->output == otModule || c->output == otLibrary)) {
2061 if (c->options.shared == share_SHARED) {
2062 c->install_path = LIBDIR;
2066 if (c->output == otDynamicLibraryOnly ||
2067 c->output == otModule ||
2068 c->output == otLibrary) {
2070 push_count_chars(c->shared_opts.normal, "-o");
2071 if (c->output == otModule) {
2072 push_count_chars(c->shared_opts.normal, c->module_name.normal);
2076 push_count_chars(c->shared_opts.normal, c->shared_name.normal);
2077 #ifdef DYNAMIC_INSTALL_NAME
2078 push_count_chars(c->shared_opts.normal, DYNAMIC_INSTALL_NAME);
2080 if (!c->install_path) {
2081 fprintf(stderr, "Installation mode requires -rpath\n");
2085 tmp = (char*)malloc(PATH_MAX);
2086 strcpy(tmp, c->install_path);
2087 if (c->shared_name.install) {
2088 strcat(tmp, strrchr(c->shared_name.install, '/'));
2090 strcat(tmp, strrchr(c->shared_name.normal, '/'));
2092 push_count_chars(c->shared_opts.normal, tmp);
2096 append_count_chars(c->shared_opts.normal, c->obj_files);
2097 append_count_chars(c->shared_opts.normal, c->shared_opts.dependencies);
2099 if (c->options.export_all) {
2101 generate_def_file(c);
2106 if (c->output == otLibrary || c->output == otStaticLibraryOnly) {
2107 push_count_chars(c->static_opts.normal, "-o");
2108 push_count_chars(c->static_opts.normal, c->output_name);
2111 if (c->output == otProgram) {
2112 if (c->output_name) {
2113 push_count_chars(c->arglist, "-o");
2114 push_count_chars(c->arglist, c->output_name);
2115 append_count_chars(c->arglist, c->obj_files);
2116 append_count_chars(c->arglist, c->shared_opts.dependencies);
2117 add_dynamic_link_opts(c, c->arglist);
2122 static void post_parse_fixup(command_t *cmd_data)
2124 switch (cmd_data->mode)
2128 if (cmd_data->options.pic_mode != pic_AVOID) {
2129 push_count_chars(cmd_data->arglist, PIC_FLAG);
2132 if (cmd_data->output_name) {
2133 push_count_chars(cmd_data->arglist, "-o");
2134 push_count_chars(cmd_data->arglist, cmd_data->output_name);
2138 link_fixup(cmd_data);
2141 if (cmd_data->output == otLibrary) {
2142 link_fixup(cmd_data);
2149 if (cmd_data->output == otObject ||
2150 cmd_data->output == otProgram ||
2151 cmd_data->output == otLibrary ||
2152 cmd_data->output == otDynamicLibraryOnly) {
2153 push_count_chars(cmd_data->arglist, "-Zomf");
2157 if (cmd_data->options.shared &&
2158 (cmd_data->output == otObject ||
2159 cmd_data->output == otLibrary ||
2160 cmd_data->output == otDynamicLibraryOnly)) {
2162 push_count_chars(cmd_data->arglist, SHARE_SW);
2167 static int run_mode(command_t *cmd_data)
2170 count_chars *cctemp;
2172 cctemp = (count_chars*)malloc(sizeof(count_chars));
2173 init_count_chars(cctemp);
2175 switch (cmd_data->mode)
2178 rv = run_command(cmd_data, cmd_data->arglist);
2179 if (rv) goto finish;
2182 /* Well, we'll assume it's a file going to a directory... */
2183 /* For brain-dead install-sh based scripts, we have to repeat
2184 * the command N-times. install-sh should die.
2186 if (!cmd_data->output_name) {
2187 rv = run_command(cmd_data, cmd_data->arglist);
2188 if (rv) goto finish;
2190 if (cmd_data->output_name) {
2191 append_count_chars(cctemp, cmd_data->arglist);
2192 insert_count_chars(cctemp,
2193 cmd_data->output_name,
2195 rv = run_command(cmd_data, cctemp);
2196 if (rv) goto finish;
2197 clear_count_chars(cctemp);
2199 if (cmd_data->static_name.install) {
2200 append_count_chars(cctemp, cmd_data->arglist);
2201 insert_count_chars(cctemp,
2202 cmd_data->static_name.install,
2204 rv = run_command(cmd_data, cctemp);
2205 if (rv) goto finish;
2206 #if defined(__APPLE__) && defined(RANLIB)
2207 /* From the Apple libtool(1) manpage on Tiger/10.4:
2209 * With the way libraries used to be created, errors were possible
2210 * if the library was modified with ar(1) and the table of
2211 * contents was not updated by rerunning ranlib(1). Thus the
2212 * link editor, ld, warns when the modification date of a library
2213 * is more recent than the creation date of its table of
2214 * contents. Unfortunately, this means that you get the warning
2215 * even if you only copy the library.
2218 * This means that when we install the static archive, we need to
2219 * rerun ranlib afterwards.
2221 const char *lib_args[3], *static_lib_name;
2224 len1 = strlen(cmd_data->arglist->vals[cmd_data->arglist->num - 1]);
2226 static_lib_name = jlibtool_basename(cmd_data->static_name.install);
2227 len2 = strlen(static_lib_name);
2229 tmp = malloc(len1 + len2 + 2);
2231 snprintf(tmp, len1 + len2 + 2, "%s/%s",
2232 cmd_data->arglist->vals[cmd_data->arglist->num - 1],
2235 lib_args[0] = RANLIB;
2238 external_spawn(cmd_data, RANLIB, lib_args);
2241 clear_count_chars(cctemp);
2243 if (cmd_data->shared_name.install) {
2244 append_count_chars(cctemp, cmd_data->arglist);
2245 insert_count_chars(cctemp,
2246 cmd_data->shared_name.install,
2248 rv = run_command(cmd_data, cctemp);
2249 if (rv) goto finish;
2250 clear_count_chars(cctemp);
2252 if (cmd_data->module_name.install) {
2253 append_count_chars(cctemp, cmd_data->arglist);
2254 insert_count_chars(cctemp,
2255 cmd_data->module_name.install,
2257 rv = run_command(cmd_data, cctemp);
2258 if (rv) goto finish;
2259 clear_count_chars(cctemp);
2263 if (cmd_data->output == otStaticLibraryOnly ||
2264 cmd_data->output == otLibrary) {
2266 const char *lib_args[3];
2268 /* Removes compiler! */
2269 cmd_data->program = LIBRARIAN;
2270 push_count_chars(cmd_data->program_opts, LIBRARIAN_OPTS);
2271 push_count_chars(cmd_data->program_opts,
2272 cmd_data->static_name.normal);
2274 rv = run_command(cmd_data, cmd_data->obj_files);
2275 if (rv) goto finish;
2278 lib_args[0] = RANLIB;
2279 lib_args[1] = cmd_data->static_name.normal;
2281 external_spawn(cmd_data, RANLIB, lib_args);
2285 if (cmd_data->output == otDynamicLibraryOnly ||
2286 cmd_data->output == otModule ||
2287 cmd_data->output == otLibrary) {
2288 cmd_data->program = NULL;
2289 clear_count_chars(cmd_data->program_opts);
2291 append_count_chars(cmd_data->program_opts, cmd_data->arglist);
2292 if (cmd_data->output == otModule) {
2294 push_count_chars(cmd_data->program_opts, MODULE_OPTS);
2298 push_count_chars(cmd_data->program_opts, SHARED_OPTS);
2300 #ifdef dynamic_link_version_func
2301 push_count_chars(cmd_data->program_opts,
2302 dynamic_link_version_func(cmd_data->version_info));
2305 add_dynamic_link_opts(cmd_data, cmd_data->program_opts);
2307 rv = run_command(cmd_data, cmd_data->shared_opts.normal);
2308 if (rv) goto finish;
2310 if (cmd_data->output == otProgram) {
2311 rv = run_command(cmd_data, cmd_data->arglist);
2312 if (rv) goto finish;
2317 char *l, libpath[PATH_MAX];
2319 if (strlen(cmd_data->arglist->vals[0]) >= PATH_MAX) {
2320 fprintf(stderr, "Libpath too long no buffer space");
2326 strcpy(libpath, cmd_data->arglist->vals[0]);
2327 add_dotlibs(libpath);
2328 l = strrchr(libpath, '/');
2329 if (!l) l = strrchr(libpath, '\\');
2337 l = "./build/lib/.libs";
2338 setenv(LD_LIBRARY_PATH_LOCAL, l, 1);
2339 rv = run_command(cmd_data, cmd_data->arglist);
2340 if (rv) goto finish;
2354 static void cleanup_tmp_dir(const char *dirname)
2357 struct dirent *entry;
2358 char fullname[1024];
2360 dir = opendir(dirname);
2365 if ((strlen(dirname) + 1 + sizeof(entry->d_name)) >= sizeof(fullname)) {
2366 fprintf(stderr, "Dirname too long out of buffer space");
2367 (void) closedir(dir);
2371 while ((entry = readdir(dir)) != NULL) {
2372 if (entry->d_name[0] != '.') {
2373 strcpy(fullname, dirname);
2374 strcat(fullname, "/");
2375 strcat(fullname, entry->d_name);
2376 (void) remove(fullname);
2382 (void) closedir(dir);
2385 static void cleanup_tmp_dirs(command_t *cmd_data)
2389 for (d = 0; d < cmd_data->tmp_dirs->num; d++) {
2390 cleanup_tmp_dir(cmd_data->tmp_dirs->vals[d]);
2394 static int ensure_fake_uptodate(command_t *cmd_data)
2396 /* FIXME: could do the stat/touch here, but nah... */
2397 const char *touch_args[3];
2399 if (cmd_data->mode == mInstall) {
2402 if (!cmd_data->fake_output_name) {
2406 touch_args[0] = "touch";
2407 touch_args[1] = cmd_data->fake_output_name;
2408 touch_args[2] = NULL;
2409 return external_spawn(cmd_data, "touch", touch_args);
2412 /* Store the install path in the *.la file */
2413 static int add_for_runtime(command_t *cmd_data)
2415 if (cmd_data->mode == mInstall) {
2418 if (cmd_data->output == otDynamicLibraryOnly ||
2419 cmd_data->output == otLibrary) {
2420 FILE *f=fopen(cmd_data->fake_output_name,"w");
2424 fprintf(f,"%s\n", cmd_data->install_path);
2428 return(ensure_fake_uptodate(cmd_data));
2432 int main(int argc, char *argv[])
2437 memset(&cmd_data, 0, sizeof(cmd_data));
2439 cmd_data.options.pic_mode = pic_UNKNOWN;
2441 cmd_data.program_opts = (count_chars*)malloc(sizeof(count_chars));
2442 init_count_chars(cmd_data.program_opts);
2443 cmd_data.arglist = (count_chars*)malloc(sizeof(count_chars));
2444 init_count_chars(cmd_data.arglist);
2445 cmd_data.tmp_dirs = (count_chars*)malloc(sizeof(count_chars));
2446 init_count_chars(cmd_data.tmp_dirs);
2447 cmd_data.obj_files = (count_chars*)malloc(sizeof(count_chars));
2448 init_count_chars(cmd_data.obj_files);
2449 cmd_data.dep_rpaths = (count_chars*)malloc(sizeof(count_chars));
2450 init_count_chars(cmd_data.dep_rpaths);
2451 cmd_data.rpaths = (count_chars*)malloc(sizeof(count_chars));
2452 init_count_chars(cmd_data.rpaths);
2453 cmd_data.static_opts.normal = (count_chars*)malloc(sizeof(count_chars));
2454 init_count_chars(cmd_data.static_opts.normal);
2455 cmd_data.shared_opts.normal = (count_chars*)malloc(sizeof(count_chars));
2456 init_count_chars(cmd_data.shared_opts.normal);
2457 cmd_data.shared_opts.dependencies = (count_chars*)malloc(sizeof(count_chars));
2458 init_count_chars(cmd_data.shared_opts.dependencies);
2460 cmd_data.mode = mUnknown;
2461 cmd_data.output = otGeneral;
2463 parse_args(argc, argv, &cmd_data);
2464 post_parse_fixup(&cmd_data);
2466 if (cmd_data.mode == mUnknown) {
2470 rc = run_mode(&cmd_data);
2473 add_for_runtime(&cmd_data);
2476 cleanup_tmp_dirs(&cmd_data);