| /* ltmain.c - C implementation of GNU Libtool |
| * |
| * Copyright (C) 1998-2000 Free Software Foundation, Inc. |
| * |
| * This program is free software; you can redistribute it and/or modify |
| * it under the terms of the GNU General Public License as published by |
| * the Free Software Foundation; either version 2, or (at your option) |
| * any later version. |
| * |
| * This program is distributed in the hope that it will be useful, |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| * GNU General Public License for more details. |
| * |
| * You should have received a copy of the GNU General Public License |
| * along with this software; see the file COPYING. If not, write to |
| * the Free Software Foundation, Inc., 59 Temple Place, Suite 330, |
| * Boston, MA 02111-1307 USA |
| * |
| * As a special exception to the GNU General Public License, if you |
| * distribute this file as part of a program that contains a |
| * configuration script generated by Autoconf, you may include it under |
| * the same distribution terms that you use for the rest of that program. |
| */ |
| |
| #include <sys/types.h> |
| #include <stdio.h> /* printf */ |
| #include <stdlib.h> /* exit */ |
| #include <string.h> |
| #include <unistd.h> |
| #include <errno.h> |
| #include <sys/stat.h> |
| #include <sys/wait.h> |
| #include <signal.h> |
| |
| #include "ltopts.h" |
| #include "ltstr.h" |
| |
| static char* pzTarget = NULL; |
| static char* pzSource = NULL; |
| static int oldLibs = 0; |
| static char* pzPicMode = "default"; |
| static int xCompile = 0; |
| |
| /* BEGIN-STATIC-FORWARD */ |
| LOCAL void |
| parseCompileOpts LT_PARAMS(( |
| int* pArgc, |
| char*** pArgv )); |
| |
| /* END-STATIC-FORWARD */ |
| |
| EXPORT void |
| emitCompile( argc, argv ) |
| int argc; |
| char** argv; /*end-decl*/ |
| { |
| tSCC zDbgFmt[] = "set -x\n"; |
| tSCC zQuiet[] = "run=\nshow=%s\n"; |
| tSCC zDynFmt[] = "build_libtool_libs=%s\n"; |
| tSCC zStatic[] = "build_old_libs=%s\n"; |
| tSCC zModeName[] = "suppress_output=\nmodename='%s: %s'\nmode='%s'\n"; |
| |
| /* |
| * When we emit our script, we want the interpreter to invoke *US* |
| * if echo does not work right. |
| */ |
| tSCC zChkEcho[] = |
| "\n\nif test \"X`($echo '\\t') 2>/dev/null`\" = 'X\\t'\n\ |
| then :\n\ |
| else echo='%s --echo --' ; fi\n"; |
| |
| FILE* fp = HAVE_OPT( DRY_RUN ) ? stdout : popen( pz_shell, "w" ); |
| if (fp == (FILE*)NULL) { |
| tSCC zErr[] = "%s error: fs error %d (%s) on popen( \"%s\",\"w\")\n"; |
| fprintf( stderr, zErr, libtoolOptions.pzProgPath, errno, |
| strerror( errno ), pz_shell ); |
| exit( EXIT_FAILURE ); |
| } |
| |
| # define CKSERV if (signalReceived != 0) { \ |
| closeScript( fp ); if (scriptStatus == 0) scriptStatus = EXIT_FAILURE; \ |
| return; } |
| |
| # define CLOSEOK if (signalReceived != 0) { closeScript( fp ); return; } |
| |
| parseCompileOpts( &argc, &argv ); |
| |
| /* |
| * Emit the default configuration set up at program configuration time |
| */ |
| fputs( pz_ltconfig, fp ); |
| CKSERV; |
| fputs( apz_mode_cmd[ 0 ], fp ); |
| CKSERV; |
| fprintf( fp, zChkEcho, libtoolOptions.pzProgPath ); |
| CKSERV; |
| |
| fprintf( fp, zQuiet, HAVE_OPT( QUIET ) ? ":" : "\"$echo\"" ); |
| CKSERV; |
| |
| /* |
| * IF we have DYNAMIC or STATIC, then we override the configured |
| * values. We emitted the configured values with `z_ltconfig'. |
| */ |
| if (HAVE_OPT( DYNAMIC ) && (oldLibs == 0)) |
| fprintf( fp, zDynFmt, ENABLED_OPT( DYNAMIC ) ? "yes" : "no" ); |
| if (HAVE_OPT( STATIC ) || oldLibs) |
| fprintf( fp, zStatic, ENABLED_OPT( STATIC ) |
| ? "yes" : (oldLibs ? "yes" : "no") ); |
| |
| if (HAVE_OPT( DEBUG )) { |
| fprintf( stderr, "%s: enabling shell trace mode\n", |
| libtoolOptions.pzProgName ); |
| fputs( zDbgFmt, fp ); |
| } |
| CKSERV; |
| |
| if (HAVE_OPT( DLOPEN )) { |
| emitDlopenOption( fp ); |
| CKSERV; |
| } |
| |
| /* |
| * Insert our modal stuff and one shell option processing dinkleberry |
| * that one of the command scripts depends upon. |
| */ |
| fprintf( fp, zModeName, libtoolOptions.pzProgName, |
| apzModeName[ OPT_VALUE_MODE ], libtoolOptions.pzProgName ); |
| CKSERV; |
| |
| if (pzTarget == NULL) { |
| pzTarget = strrchr( pzSource, '/' ); |
| if (pzTarget == NULL) |
| pzTarget = pzSource; |
| else |
| pzTarget++; |
| } |
| |
| fputs( "libobj='", fp ); |
| emitRawQuoted( pzTarget, fp ); |
| fprintf( fp, "'\nbuild_old_libs=%s\n", oldLibs ? "yes" : "no" ); |
| CKSERV; |
| |
| fprintf( fp, "pic_mode=%s\n", pzPicMode ); |
| CKSERV; |
| |
| fputs( "base_compile='", fp ); |
| for (;;) { |
| emitShellArg( *(argv++), fp, '"' ); |
| CKSERV; |
| if (--argc <= 0) |
| break; |
| fputc( ' ', fp ); |
| } |
| fputs( "'\n", fp ); |
| |
| { |
| struct stat stbf; |
| |
| if (stat( pzSource, &stbf ) != 0) do { |
| char* pz = getenv( "source" ); |
| if ( (pz != NULL) |
| && (stat( pz, &stbf ) == 0)) { |
| pzSource = pz; |
| break; |
| } |
| |
| pz = getenv( "srcdir" ); |
| if (pz == NULL) |
| pz = getenv( "VPATH" ); |
| |
| if (pz != NULL) { |
| char* p = xmalloc( strlen( pz ) + strlen( pzSource ) + 2 ); |
| sprintf( p, "%s/%s", pz, pzSource ); |
| if (stat( p, &stbf ) == 0) |
| pzSource = p; |
| else |
| free( p ); |
| } |
| } while (0); |
| |
| fprintf( fp, "srcfile='%s'\n", pzSource ); |
| } |
| |
| emitCommands( fp, apz_mode_cmd[ OPT_VALUE_MODE ]); |
| } |
| |
| |
| EXPORT void* |
| xmalloc( size ) |
| size_t size; /*end-decl*/ |
| { |
| void* p = malloc( size ); |
| if (p == NULL) { |
| fprintf( stderr, "%s error: cannot allocate %d bytes\n", |
| libtoolOptions.pzProgPath ); |
| exit( EXIT_FAILURE ); |
| } |
| return p; |
| } |
| |
| |
| LOCAL void |
| parseCompileOpts( pArgc, pArgv ) |
| int* pArgc; |
| char*** pArgv; /*end-decl*/ |
| { |
| tSCC zTooManyTargets[] = |
| "%s compile: you cannot specify `-o' more than once\n"; |
| tSCC zNoTarget[] = |
| "%s compile: `-o' must specify an output file name\n"; |
| tSCC zNoXcompile[] = |
| "%s compile: `-Xcompiler' must specify a cross compiler\n"; |
| tSCC zEarlyOpts[] = |
| "%s compile: error: you cannot supply options before the command\n"; |
| |
| int argc = *pArgc; |
| char** argv = *pArgv; |
| |
| tCC** newArgv = xmalloc( sizeof( char* ) * argc ); |
| int newCt = 0; |
| int alocCt = argc; |
| |
| tCC* pzCmd = NULL; |
| int i; |
| |
| for (i=0; i<argc; i++) { |
| if (strncmp( argv[i], "-o", 2 ) == 0) { |
| if (pzTarget != NULL) { |
| fprintf( stderr, zTooManyTargets, libtoolOptions.pzProgPath ); |
| exit( EXIT_FAILURE ); |
| } |
| if (argv[i][2] != '\0') |
| pzTarget = (argv[i]) + 2; |
| else { |
| pzTarget = argv[ ++i ]; |
| if (pzTarget == NULL) { |
| fprintf( stderr, zNoTarget, libtoolOptions.pzProgPath ); |
| exit( EXIT_FAILURE ); |
| } |
| } |
| |
| } else if (strcmp( argv[i], "-static" ) == 0) { |
| oldLibs = 1; |
| |
| } else if (strcmp( argv[i], "-prefer-pic" ) == 0) { |
| pzPicMode = "yes"; |
| |
| } else if (strcmp( argv[i], "-prefer-non-pic" ) == 0) { |
| pzPicMode = "no"; |
| |
| } else if (strcmp( argv[i], "-Xcompiler" ) == 0) { |
| if (argv[++i] == NULL) { |
| fprintf( stderr, zNoXcompile, libtoolOptions.pzProgPath ); |
| exit( EXIT_FAILURE ); |
| } |
| if (++newCt >= alocCt) { |
| alocCt = (alocCt + 8) & ~0x07; |
| newArgv = realloc( newArgv, alocCt * sizeof( char* )); |
| } |
| pzCmd = newArgv[ newCt-1 ] = argv[i]; |
| |
| } else if (strncmp( argv[i], "-Wc,", 4 ) == 0) { |
| char* pz = argv[i] + 4; |
| for (;;) { |
| while (isspace( *pz )) pz++; |
| if (*pz == NUL) |
| break; |
| |
| if (++newCt >= alocCt) { |
| alocCt = (alocCt + 8) & ~0x07; |
| newArgv = realloc( newArgv, alocCt * sizeof( char* )); |
| } |
| newArgv[ newCt-1 ] = pz; |
| pz = strchr( pz, ',' ); |
| if (pz == NULL) |
| break; |
| *(pz++) = NUL; |
| } |
| |
| } else if (pzCmd == NULL) { |
| pzCmd = newArgv[ newCt++ ] = argv[i]; |
| |
| } else if (pzSource == NULL) { |
| pzSource = argv[i]; |
| |
| } else { |
| if (++newCt >= alocCt) { |
| alocCt = (alocCt + 8) & ~0x07; |
| newArgv = realloc( newArgv, alocCt * sizeof( char* )); |
| } |
| pzCmd = newArgv[ newCt-1 ] = pzSource; |
| pzSource = argv[i]; |
| } |
| } |
| |
| if (pzSource == NULL) { |
| fprintf( stderr, "%s compile: error: no source file to compile\n", |
| libtoolOptions.pzProgName ); |
| exit( EXIT_FAILURE ); |
| } |
| |
| if (++newCt >= alocCt) |
| newArgv = realloc( newArgv, ++alocCt * sizeof( char* )); |
| |
| newArgv[ newCt-1 ] = NULL; |
| *pArgc = newCt; |
| *pArgv = (char**)newArgv; |
| } |
| /* |
| * Local Variables: |
| * c-file-style: "stroustrup" |
| * indent-tabs-mode: nil |
| * tab-width: 4 |
| * End: |
| * end of ltcompile.c */ |