mirror of
https://https.git.savannah.gnu.org/git/libtool.git
synced 2026-01-29 02:44:20 +00:00
318 lines
9.2 KiB
C
318 lines
9.2 KiB
C
/* 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 */
|