📄 jlibtool.c
字号:
/* Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#include <stdio.h>#include <string.h>#include <stdlib.h>#include <sys/stat.h>#include <sys/types.h>#if !defined(__MINGW32__)#include <sys/wait.h>#endif#include <unistd.h>#include <dirent.h>#include <errno.h>#include <assert.h>#ifdef __EMX__# define SHELL_CMD "sh"# define GEN_EXPORTS "emxexp"# define DEF2IMPLIB_CMD "emximp"# define SHARE_SW "-Zdll -Zmtd"# define USE_OMF 1# define TRUNCATE_DLL_NAME# define DYNAMIC_LIB_EXT "dll"# define EXE_EXT ".exe"# if USE_OMF /* OMF is the native format under OS/2 */# define STATIC_LIB_EXT "lib"# define OBJECT_EXT "obj"# define LIBRARIAN "emxomfar"# define LIBRARIAN_OPTS "cr"# else /* but the alternative, a.out, can fork() which is sometimes necessary */# define STATIC_LIB_EXT "a"# define OBJECT_EXT "o"# define LIBRARIAN "ar"# define LIBRARIAN_OPTS "cr"# endif#endif#if defined(__APPLE__)# define SHELL_CMD "/bin/sh"# define DYNAMIC_LIB_EXT "dylib"# define MODULE_LIB_EXT "bundle"# define STATIC_LIB_EXT "a"# define OBJECT_EXT "o"# define LIBRARIAN "ar"# define LIBRARIAN_OPTS "cr"/* man libtool(1) documents ranlib option of -c. */# define RANLIB "ranlib"# define PIC_FLAG "-fPIC -fno-common"# define SHARED_OPTS "-dynamiclib"# define MODULE_OPTS "-bundle"# define DYNAMIC_LINK_OPTS "-flat_namespace"# define DYNAMIC_LINK_UNDEFINED "-undefined suppress"# define dynamic_link_version_func darwin_dynamic_link_function# define DYNAMIC_INSTALL_NAME "-install_name"# define DYNAMIC_LINK_NO_INSTALL "-dylib_file"# define HAS_REALPATH/*-install_name /Users/jerenk/apache-2.0-cvs/lib/libapr.0.dylib -compatibility_version 1 -current_version 1.0 */# define LD_LIBRARY_PATH "DYLD_LIBRARY_PATH"#endif#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)# define SHELL_CMD "/bin/sh"# define DYNAMIC_LIB_EXT "so"# define MODULE_LIB_EXT "so"# define STATIC_LIB_EXT "a"# define OBJECT_EXT "o"# define LIBRARIAN "ar"# define LIBRARIAN_OPTS "cr"# define RANLIB "ranlib"# define PIC_FLAG "-fPIC"# define RPATH "-rpath"# define SHARED_OPTS "-shared"# define MODULE_OPTS "-shared"# define DYNAMIC_LINK_OPTS "-export-dynamic"# define LINKER_FLAG_PREFIX "-Wl,"# define ADD_MINUS_L# define LD_RUN_PATH "LD_RUN_PATH"# define LD_LIBRARY_PATH "LD_LIBRARY_PATH"#endif#if defined(sun)# define SHELL_CMD "/bin/sh"# define DYNAMIC_LIB_EXT "so"# define MODULE_LIB_EXT "so"# define STATIC_LIB_EXT "a"# define OBJECT_EXT "o"# define LIBRARIAN "ar"# define LIBRARIAN_OPTS "cr"# define RANLIB "ranlib"# define PIC_FLAG "-KPIC"# define RPATH "-R"# define SHARED_OPTS "-G"# define MODULE_OPTS "-G"# define DYNAMIC_LINK_OPTS ""# define LINKER_FLAG_NO_EQUALS# define ADD_MINUS_L# define HAS_REALPATH# define LD_RUN_PATH "LD_RUN_PATH"# define LD_LIBRARY_PATH "LD_LIBRARY_PATH"#endif#if defined(_OSD_POSIX)# define SHELL_CMD "/usr/bin/sh"# define DYNAMIC_LIB_EXT "so"# define MODULE_LIB_EXT "so"# define STATIC_LIB_EXT "a"# define OBJECT_EXT "o"# define LIBRARIAN "ar"# define LIBRARIAN_OPTS "cr"# define SHARED_OPTS "-G"# define MODULE_OPTS "-G"# define LINKER_FLAG_PREFIX "-Wl,"# define NEED_SNPRINTF#endif#if defined(sinix) && defined(mips) && defined(__SNI_TARG_UNIX)# define SHELL_CMD "/usr/bin/sh"# define DYNAMIC_LIB_EXT "so"# define MODULE_LIB_EXT "so"# define STATIC_LIB_EXT "a"# define OBJECT_EXT "o"# define LIBRARIAN "ar"# define LIBRARIAN_OPTS "cr"# define RPATH "-Brpath"# define SHARED_OPTS "-G"# define MODULE_OPTS "-G"# define DYNAMIC_LINK_OPTS "-Wl,-Blargedynsym"# define LINKER_FLAG_PREFIX "-Wl,"# define NEED_SNPRINTF# define LD_RUN_PATH "LD_RUN_PATH"# define LD_LIBRARY_PATH "LD_LIBRARY_PATH"#endif#if defined(__MINGW32__)# define SHELL_CMD "sh"# define DYNAMIC_LIB_EXT "dll"# define MODULE_LIB_EXT "dll"# define STATIC_LIB_EXT "a"# define OBJECT_EXT "o"# define LIBRARIAN "ar"# define LIBRARIAN_OPTS "cr"# define RANLIB "ranlib"# define LINKER_FLAG_PREFIX "-Wl,"# define SHARED_OPTS "-shared"# define MODULE_OPTS "-shared"# define MKDIR_NO_UMASK# define EXE_EXT ".exe"#endif#ifndef SHELL_CMD#error Unsupported platform: Please add defines for SHELL_CMD etc. for your platform.#endif#ifdef NEED_SNPRINTF#include <stdarg.h>#endif#ifdef __EMX__#include <process.h>#endif#ifndef PATH_MAX#define PATH_MAX 1024#endif/* We want to say we are libtool 1.4 for shlibtool compatibility. */#define VERSION "1.4"enum tool_mode_t { mUnknown, mCompile, mLink, mInstall,};enum output_t { otGeneral, otObject, otProgram, otLibrary, otStaticLibraryOnly, otDynamicLibraryOnly, otModule,};enum pic_mode_e { pic_UNKNOWN, pic_PREFER, pic_AVOID,};enum shared_mode_e { share_UNSET, share_STATIC, share_SHARED,};enum lib_type { type_UNKNOWN, type_DYNAMIC_LIB, type_STATIC_LIB, type_MODULE_LIB, type_OBJECT,};typedef struct { const char **vals; int num; } count_chars;typedef struct { const char *normal; const char *install;} library_name;typedef struct { count_chars *normal; count_chars *install; count_chars *dependencies;} library_opts;typedef struct { int silent; enum shared_mode_e shared; int export_all; int dry_run; enum pic_mode_e pic_mode; int export_dynamic; int no_install;} options_t;typedef struct { enum tool_mode_t mode; enum output_t output; options_t options; char *output_name; char *fake_output_name; char *basename; const char *install_path; const char *compiler; const char *program; count_chars *program_opts; count_chars *arglist; count_chars *tmp_dirs; count_chars *obj_files; count_chars *dep_rpaths; count_chars *rpaths; library_name static_name; library_name shared_name; library_name module_name; library_opts static_opts; library_opts shared_opts; const char *version_info; const char *undefined_flag;} command_t;#ifdef RPATHvoid add_rpath(count_chars *cc, const char *path);#endif#if defined(NEED_SNPRINTF)/* Write at most n characters to the buffer in str, return the * number of chars written or -1 if the buffer would have been * overflowed. * * This is portable to any POSIX-compliant system has /dev/null */static FILE *f=NULL;static int vsnprintf( char *str, size_t n, const char *fmt, va_list ap ){ int res; if (f == NULL) f = fopen("/dev/null","w"); if (f == NULL) return -1; setvbuf( f, str, _IOFBF, n ); res = vfprintf( f, fmt, ap ); if ( res > 0 && res < n ) { res = vsprintf( str, fmt, ap ); } return res;}static int snprintf( char *str, size_t n, const char *fmt, ... ){ va_list ap; int res; va_start( ap, fmt ); res = vsnprintf( str, n, fmt, ap ); va_end( ap ); return res;}#endifvoid init_count_chars(count_chars *cc){ cc->vals = (const char**)malloc(PATH_MAX*sizeof(char*)); cc->num = 0;}void clear_count_chars(count_chars *cc){ int i; for (i = 0; i < cc->num; i++) { cc->vals[i] = 0; } cc->num = 0;}void push_count_chars(count_chars *cc, const char *newval){ cc->vals[cc->num++] = newval;}void pop_count_chars(count_chars *cc){ cc->num--;}void insert_count_chars(count_chars *cc, const char *newval, int position){ int i; for (i = cc->num; i > position; i--) { cc->vals[i] = cc->vals[i-1]; } cc->vals[position] = newval; cc->num++;}void append_count_chars(count_chars *cc, count_chars *cctoadd){ int i; for (i = 0; i < cctoadd->num; i++) { if (cctoadd->vals[i]) { push_count_chars(cc, cctoadd->vals[i]); } }}const char *flatten_count_chars(count_chars *cc, int space){ int i, size; char *newval; size = 0; for (i = 0; i < cc->num; i++) { if (cc->vals[i]) { size += strlen(cc->vals[i]) + 1; if (space) { size++; } } } newval = (char*)malloc(size + 1); newval[0] = 0; for (i = 0; i < cc->num; i++) { if (cc->vals[i]) { strcat(newval, cc->vals[i]); if (space) { strcat(newval, " "); } } } return newval;}char *shell_esc(const char *str){ int in_quote = 0; char *cmd; unsigned char *d; const unsigned char *s; cmd = (char *)malloc(2 * strlen(str) + 3); d = (unsigned char *)cmd; s = (const unsigned char *)str;#ifdef __MINGW32__ *d++ = '\"';#endif for (; *s; ++s) { if (*s == '"') { *d++ = '\\'; in_quote++; } else if (*s == '\\' || (*s == ' ' && (in_quote % 2))) { *d++ = '\\'; } *d++ = *s; }#ifdef __MINGW32__ *d++ = '\"';#endif *d = '\0'; return cmd;}int external_spawn(command_t *cmd, const char *file, const char **argv){ if (!cmd->options.silent) { const char **argument = argv; printf("Executing: "); while (*argument) { printf("%s ", *argument); argument++; } puts(""); } if (cmd->options.dry_run) { return 0; }#if defined(__EMX__) || defined(__MINGW32__) return spawnvp(P_WAIT, argv[0], argv);#else { pid_t pid; pid = fork(); if (pid == 0) { return execvp(argv[0], (char**)argv); } else { int statuscode; waitpid(pid, &statuscode, 0); if (WIFEXITED(statuscode)) { return WEXITSTATUS(statuscode); } return 0; } }#endif}int run_command(command_t *cmd_data, count_chars *cc){ char *command; const char *spawn_args[4]; count_chars tmpcc; init_count_chars(&tmpcc); if (cmd_data->program) { push_count_chars(&tmpcc, cmd_data->program); } append_count_chars(&tmpcc, cmd_data->program_opts); append_count_chars(&tmpcc, cc); command = shell_esc(flatten_count_chars(&tmpcc, 1)); spawn_args[0] = SHELL_CMD; spawn_args[1] = "-c"; spawn_args[2] = command; spawn_args[3] = NULL; return external_spawn(cmd_data, spawn_args[0], (const char**)spawn_args);}/* * print configuration * shlibpath_var is used in configure. */void print_config(){#ifdef LD_RUN_PATH printf("runpath_var=%s\n", LD_RUN_PATH);#endif#ifdef LD_LIBRARY_PATH printf("shlibpath_var=%s\n", LD_LIBRARY_PATH);#endif#ifdef SHELL_CMD printf("SHELL=\"%s\"\n", SHELL_CMD);#endif}/*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -