makefiles: Explicitly import all the needed libraries.

Don't rely on winegcc adding any default libraries.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2021-11-11 11:38:31 +01:00
parent ce9d006a45
commit 6ebcc54a5c
3 changed files with 85 additions and 84 deletions

View File

@ -1,8 +1,7 @@
MODULE = krnl386.exe16
IMPORTLIB = kernel
IMPORTS = kernel32 ntdll winecrt0
DELAYIMPORTS = user32
EXTRADLLFLAGS = -m16 -nodefaultlibs -Wb,--dll-name,kernel
EXTRADLLFLAGS = -m16 -Wb,--dll-name,kernel
C_SRCS = \
atom.c \

View File

@ -2075,6 +2075,80 @@ static struct strarray add_unix_libraries( const struct makefile *make, struct s
}
/*******************************************************************
* is_crt_module
*/
static int is_crt_module( const char *file )
{
return !strncmp( file, "msvcr", 5 ) || !strncmp( file, "ucrt", 4 ) || !strcmp( file, "crtdll.dll" );
}
/*******************************************************************
* get_default_crt
*/
static const char *get_default_crt( const struct makefile *make )
{
if (!make->use_msvcrt) return NULL;
if (make->module && is_crt_module( make->module )) return NULL; /* don't add crt import to crt dlls */
return !make->testdll && (!make->staticlib || make->extlib) ? "ucrtbase" : "msvcrt";
}
/*******************************************************************
* get_crt_define
*/
static const char *get_crt_define( const struct makefile *make )
{
const char *crt_dll = NULL;
unsigned int i, version = 0;
for (i = 0; i < make->imports.count; i++)
{
if (!is_crt_module( make->imports.str[i] )) continue;
if (crt_dll) fatal_error( "More than one C runtime DLL imported: %s and %s\n",
crt_dll, make->imports.str[i] );
crt_dll = make->imports.str[i];
}
if (!crt_dll)
{
if (strarray_exists( &make->extradllflags, "-nodefaultlibs" )) return "-D_MSVCR_VER=0";
if (!(crt_dll = get_default_crt( make ))) crt_dll = make->module;
}
if (!strncmp( crt_dll, "ucrt", 4 )) return "-D_UCRT";
sscanf( crt_dll, "msvcr%u", &version );
return strmake( "-D_MSVCR_VER=%u", version );
}
/*******************************************************************
* add_default_imports
*/
static struct strarray add_default_imports( const struct makefile *make, struct strarray imports )
{
struct strarray ret = empty_strarray;
const char *crt_dll = get_default_crt( make );
unsigned int i;
for (i = 0; i < imports.count; i++)
{
if (is_crt_module( imports.str[i] )) crt_dll = imports.str[i];
else strarray_add( &ret, imports.str[i] );
}
strarray_add( &ret, "winecrt0" );
if (crt_dll) strarray_add( &ret, crt_dll );
if (make->is_win16 && (!make->importlib || strcmp( make->importlib, "kernel" )))
strarray_add( &ret, "kernel" );
strarray_add( &ret, "kernel32" );
strarray_add( &ret, "ntdll" );
return ret;
}
/*******************************************************************
* add_import_libs
*/
@ -2085,6 +2159,9 @@ static struct strarray add_import_libs( const struct makefile *make, struct stra
unsigned int i, j;
int is_cross = make->is_cross && !is_unix;
if (!delay && !is_unix && !strarray_exists( &make->extradllflags, "-nodefaultlibs" ))
imports = add_default_imports( make, imports );
for (i = 0; i < imports.count; i++)
{
const char *name = imports.str[i];
@ -2109,9 +2186,9 @@ static struct strarray add_import_libs( const struct makefile *make, struct stra
lib = obj_dir_path( submakes[j], strmake( "lib%s.a", name ));
else
{
strarray_add( deps, strmake( "%s/lib%s.def", submakes[j]->obj_dir, name ));
strarray_add_uniq( deps, strmake( "%s/lib%s.def", submakes[j]->obj_dir, name ));
if (needs_implib_symlink( submakes[j] ))
strarray_add( deps, strmake( "dlls/lib%s.def", name ));
strarray_add_uniq( deps, strmake( "dlls/lib%s.def", name ));
}
break;
}
@ -2126,10 +2203,10 @@ static struct strarray add_import_libs( const struct makefile *make, struct stra
if (delay && !delay_load_flag && (is_cross || !*dll_ext)) ext = ".delay.a";
else if (is_cross) ext = ".cross.a";
if (ext) lib = replace_extension( lib, ".a", ext );
strarray_add( deps, lib );
strarray_add_uniq( deps, lib );
strarray_add( &ret, lib );
if (needs_implib_symlink( submakes[j] ))
strarray_add( deps, strmake( "dlls/lib%s%s", name, ext ? ext : ".a" ));
strarray_add_uniq( deps, strmake( "dlls/lib%s%s", name, ext ? ext : ".a" ));
}
else strarray_add( &ret, strmake( "-l%s", name ));
}
@ -2137,69 +2214,6 @@ static struct strarray add_import_libs( const struct makefile *make, struct stra
}
/*******************************************************************
* get_default_imports
*/
static struct strarray get_default_imports( const struct makefile *make )
{
struct strarray ret = empty_strarray;
if (strarray_exists( &make->extradllflags, "-nodefaultlibs" )) return ret;
strarray_add( &ret, "winecrt0" );
if (make->is_win16) strarray_add( &ret, "kernel" );
strarray_add( &ret, "kernel32" );
strarray_add( &ret, "ntdll" );
return ret;
}
/*******************************************************************
* is_crt_module
*/
static int is_crt_module( const char *file )
{
return !strncmp( file, "msvcr", 5 ) || !strncmp( file, "ucrt", 4 ) || !strcmp( file, "crtdll.dll" );
}
/*******************************************************************
* add_crt_import
*/
static void add_crt_import( const struct makefile *make, struct strarray *imports, struct strarray *defs )
{
unsigned int i;
const char *crt_dll = NULL;
for (i = 0; i < imports->count; i++)
{
if (!is_crt_module( imports->str[i])) continue;
if (crt_dll) fatal_error( "More than one C runtime DLL imported: %s and %s\n", crt_dll, imports->str[i] );
crt_dll = imports->str[i];
}
if (!crt_dll && !strarray_exists( &make->extradllflags, "-nodefaultlibs" ))
{
if (make->module && is_crt_module( make->module ))
{
crt_dll = make->module;
}
else
{
crt_dll = !make->testdll && (!make->staticlib || make->extlib) ? "ucrtbase" : "msvcrt";
strarray_add( imports, crt_dll );
}
}
if (!defs) return;
if (crt_dll && !strncmp( crt_dll, "ucrt", 4 )) strarray_add( defs, "-D_UCRT" );
else
{
unsigned int version = 0;
if (crt_dll) sscanf( crt_dll, "msvcr%u", &version );
strarray_add( defs, strmake( "-D_MSVCR_VER=%u", version ));
}
}
/*******************************************************************
* add_install_rule
*/
@ -2962,11 +2976,9 @@ static void output_source_spec( struct makefile *make, struct incl_file *source,
const char *debug_file;
if (!imports.count) imports = make->imports;
else if (make->use_msvcrt) add_crt_import( make, &imports, NULL );
if (!dll_flags.count) dll_flags = make->extradllflags;
all_libs = add_import_libs( make, &dep_libs, imports, 0, 0 );
add_import_libs( make, &dep_libs, get_default_imports( make ), 0, 0 ); /* dependencies only */
dll_name = strmake( "%s.dll%s", obj, make->is_cross ? "" : dll_ext );
obj_name = strmake( "%s%s", obj_dir_path( make, obj ), make->is_cross ? ".cross.o" : ".o" );
output_file = obj_dir_path( make, dll_name );
@ -3195,7 +3207,6 @@ static void output_module( struct makefile *make )
if (!make->is_exe) spec_file = src_dir_path( make, replace_extension( make->module, ".dll", ".spec" ));
strarray_addall( &all_libs, add_import_libs( make, &dep_libs, make->delayimports, 1, 0 ));
strarray_addall( &all_libs, add_import_libs( make, &dep_libs, make->imports, 0, 0 ));
add_import_libs( make, &dep_libs, get_default_imports( make ), 0, 0 ); /* dependencies only */
if (make->is_cross)
{
@ -3266,11 +3277,8 @@ static void output_module( struct makefile *make )
{
struct strarray unix_imports = empty_strarray;
if (!strarray_exists( &make->extradllflags, "-nodefaultlibs" ))
{
strarray_add( &unix_imports, "ntdll" );
strarray_add( &unix_deps, obj_dir_path( top_makefile, "dlls/ntdll/ntdll.so" ));
}
strarray_add( &unix_imports, "ntdll" );
strarray_add( &unix_deps, obj_dir_path( top_makefile, "dlls/ntdll/ntdll.so" ));
strarray_add( &unix_imports, "winecrt0" );
if (spec_file) strarray_add( &unix_deps, spec_file );
@ -3300,7 +3308,6 @@ static void output_module( struct makefile *make )
output_filename( "-munix" );
output_filename( "-shared" );
if (spec_file) output_filename( spec_file );
if (strarray_exists( &make->extradllflags, "-nodefaultlibs" )) output_filename( "-nodefaultlibs" );
}
output_filenames_obj_dir( make, make->unixobj_files );
output_filenames( unix_libs );
@ -3471,7 +3478,6 @@ static void output_test_module( struct makefile *make )
const char *debug_file;
char *output_file;
add_import_libs( make, &dep_libs, get_default_imports( make ), 0, 0 ); /* dependencies only */
strarray_add( &make->all_targets, strmake( "%s%s", testmodule, ext ));
strarray_add( &make->clean_files, strmake( "%s%s", stripped, ext ));
output_file = strmake( "%s%s", obj_dir_path( make, testmodule ), ext );
@ -4185,7 +4191,7 @@ static void load_sources( struct makefile *make )
add_generated_sources( make );
if (!make->unixlib) make->unixlib = get_unix_lib_name( make );
if (make->use_msvcrt) add_crt_import( make, &make->imports, &make->define_args );
if (make->use_msvcrt) strarray_add( &make->define_args, get_crt_define( make ));
LIST_FOR_EACH_ENTRY( file, &make->includes, struct incl_file, entry ) parse_file( make, file, 0 );
LIST_FOR_EACH_ENTRY( file, &make->sources, struct incl_file, entry ) get_dependencies( file, file );

View File

@ -1321,10 +1321,6 @@ static void build(struct options* opts)
}
add_library(opts, lib_dirs, &files, "advapi32");
add_library(opts, lib_dirs, &files, "user32");
}
if (!opts->nodefaultlibs && !opts->unix_lib)
{
add_library(opts, lib_dirs, &files, "winecrt0");
if (opts->use_msvcrt)
{