From 89503c182a73677c1028eb4b776653ea1136115d Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Fri, 1 Jul 2005 16:17:44 +0000 Subject: [PATCH] Added a --target option to allow cross-compilation. --- tools/winebuild/import.c | 2 + tools/winebuild/main.c | 89 +++++++++++++++++++++++++++++++- tools/winebuild/winebuild.man.in | 5 ++ 3 files changed, 94 insertions(+), 2 deletions(-) diff --git a/tools/winebuild/import.c b/tools/winebuild/import.c index 2a9a8a4e849..47885b87961 100644 --- a/tools/winebuild/import.c +++ b/tools/winebuild/import.c @@ -582,6 +582,7 @@ static const char *ldcombine_files( char **argv ) close( fd ); atexit( remove_ld_tmp_file ); + if (!ld_command) ld_command = xstrdup("ld"); for (i = 0; argv[i]; i++) len += strlen(argv[i]) + 1; cmd = xmalloc( len + strlen(ld_tmp_file) + 8 + strlen(ld_command) ); sprintf( cmd, "%s -r -o %s", ld_command, ld_tmp_file ); @@ -612,6 +613,7 @@ void read_undef_symbols( char **argv ) if (argv[1]) name = ldcombine_files( argv ); else name = argv[0]; + if (!nm_command) nm_command = xstrdup("nm"); cmd = xmalloc( strlen(nm_command) + strlen(name) + 5 ); sprintf( cmd, "%s -u %s", nm_command, name ); if (!(f = popen( cmd, "r" ))) diff --git a/tools/winebuild/main.c b/tools/winebuild/main.c index 3ea9931cdf7..33091b645d0 100644 --- a/tools/winebuild/main.c +++ b/tools/winebuild/main.c @@ -77,8 +77,8 @@ char *input_file_name = NULL; char *spec_file_name = NULL; const char *output_file_name = NULL; -char *ld_command = "ld"; -char *nm_command = "nm"; +char *ld_command = NULL; +char *nm_command = NULL; static FILE *output_file; static const char *current_src_dir; @@ -99,6 +99,35 @@ enum exec_mode_values static enum exec_mode_values exec_mode = MODE_NONE; +static const struct +{ + const char *name; + enum target_cpu cpu; +} cpu_names[] = +{ + { "i386", CPU_x86 }, + { "i486", CPU_x86 }, + { "i586", CPU_x86 }, + { "i686", CPU_x86 }, + { "i786", CPU_x86 }, + { "sparc", CPU_SPARC }, + { "alpha", CPU_ALPHA }, + { "powerpc", CPU_POWERPC } +}; + +static const struct +{ + const char *name; + enum target_platform platform; +} platform_names[] = +{ + { "macos", PLATFORM_APPLE }, + { "darwin", PLATFORM_APPLE }, + { "sunos", PLATFORM_SVR4 }, + { "windows", PLATFORM_WINDOWS }, + { "winnt", PLATFORM_WINDOWS } +}; + /* set the dll file name from the input file name */ static void set_dll_file_name( const char *name, DLLSPEC *spec ) { @@ -138,6 +167,56 @@ static void set_subsystem( const char *subsystem, DLLSPEC *spec ) free( str ); } +/* set the target CPU and platform */ +static void set_target( const char *target ) +{ + unsigned int i; + char *p, *platform, *spec = xstrdup( target ); + + /* target specification is in the form CPU-MANUFACTURER-OS or CPU-MANUFACTURER-KERNEL-OS */ + + /* get the CPU part */ + + if (!(p = strchr( spec, '-' ))) fatal_error( "Invalid target specification '%s'\n", target ); + *p++ = 0; + for (i = 0; i < sizeof(cpu_names)/sizeof(cpu_names[0]); i++) + { + if (!strcmp( cpu_names[i].name, spec )) break; + } + if (i < sizeof(cpu_names)/sizeof(cpu_names[0])) target_cpu = cpu_names[i].cpu; + else fatal_error( "Unrecognized CPU '%s'\n", spec ); + + platform = p; + if ((p = strrchr( p, '-' ))) platform = p + 1; + + /* get the OS part */ + + target_platform = PLATFORM_UNSPECIFIED; /* default value */ + for (i = 0; i < sizeof(platform_names)/sizeof(platform_names[0]); i++) + { + if (!strncmp( platform_names[i].name, platform, strlen(platform_names[i].name) )) + { + target_platform = platform_names[i].platform; + break; + } + } + + free( spec ); + + if (!ld_command) + { + ld_command = xmalloc( strlen(target) + sizeof("-ld") ); + strcpy( ld_command, target ); + strcat( ld_command, "-ld" ); + } + if (!nm_command) + { + nm_command = xmalloc( strlen(target) + sizeof("-nm") ); + strcpy( nm_command, target ); + strcat( nm_command, "-nm" ); + } +} + /* cleanup on program exit */ static void cleanup(void) { @@ -178,6 +257,7 @@ static const char usage_str[] = " -o --output=NAME Set the output file name (default: stdout)\n" " -r --res=RSRC.RES Load resources from RSRC.RES\n" " --subsystem=SUBSYS Set the subsystem (one of native, windows, console)\n" +" --target=TARGET Specify target CPU and platform for cross-compiling\n" " --version Print the version and exit\n" " -w --warnings Turn on warnings\n" "\nMode options:\n" @@ -200,6 +280,7 @@ enum long_options_values LONG_OPT_RELAY16, LONG_OPT_RELAY32, LONG_OPT_SUBSYSTEM, + LONG_OPT_TARGET, LONG_OPT_VERSION }; @@ -216,6 +297,7 @@ static const struct option long_options[] = { "relay16", 0, 0, LONG_OPT_RELAY16 }, { "relay32", 0, 0, LONG_OPT_RELAY32 }, { "subsystem",1, 0, LONG_OPT_SUBSYSTEM }, + { "target", 1, 0, LONG_OPT_TARGET }, { "version", 0, 0, LONG_OPT_VERSION }, /* aliases for short options */ { "source-dir", 1, 0, 'C' }, @@ -371,6 +453,9 @@ static char **parse_options( int argc, char **argv, DLLSPEC *spec ) case LONG_OPT_SUBSYSTEM: set_subsystem( optarg, spec ); break; + case LONG_OPT_TARGET: + set_target( optarg ); + break; case LONG_OPT_VERSION: printf( "winebuild version " PACKAGE_VERSION "\n" ); exit(0); diff --git a/tools/winebuild/winebuild.man.in b/tools/winebuild/winebuild.man.in index 19fddf5a648..b76a19ec925 100644 --- a/tools/winebuild/winebuild.man.in +++ b/tools/winebuild/winebuild.man.in @@ -191,6 +191,11 @@ argument array to use Unicode strings. A graphical executable has a Optionally a major and minor subsystem version can also be specified; the default subsystem version is 4.0. .TP +.BI --target= cpu-manufacturer[-kernel]-os +Specify the target CPU and platform on which the generated code will +be built. The target specification is in the standard autoconf format +as returned by config.sub. +.TP .B \--version Display the program version and exit. .TP