diff --git a/releasenotes.md b/releasenotes.md index 9a1e897b9..d3576265e 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -23,6 +23,7 @@ - Add experimental `@noalias` attribute. - Add a `--run-once` option to delete the output file after running it. - Add `@const` attribute for macros, for better error messages with constant macros. +- Add `wincrt` setting to libraries. ### Fixes diff --git a/src/build/build.h b/src/build/build.h index 4a585ac3f..4df9ec0d3 100644 --- a/src/build/build.h +++ b/src/build/build.h @@ -463,6 +463,7 @@ typedef struct ArchOsTarget arch_os; const char *cc; const char *cflags; + WinCrtLinking win_crt; const char **csource_dirs; const char **csources; const char **execs; @@ -480,6 +481,7 @@ typedef struct Library__ const char *cc; const char *cflags; const char **csource_dirs; + WinCrtLinking win_crt; LibraryTarget *target_used; LibraryTarget **targets; } Library; diff --git a/src/build/common_build.c b/src/build/common_build.c index e0223acd6..64bd60c51 100644 --- a/src/build/common_build.c +++ b/src/build/common_build.c @@ -16,11 +16,11 @@ void check_json_keys(const char* valid_keys[][2], size_t key_count, const char* { if (str_eq(key, deprecated_keys[j])) { - eprintf("Note: Target '%s' is using the deprecated parameter '%s'\n", target_name, key); + WARNING("Target '%s' is using the deprecated parameter '%s'.", target_name, key); goto OK; } } - eprintf("WARNING: Unknown parameter '%s' in '%s'.\n", key, target_name); + WARNING("Unknown parameter '%s' in '%s'", target_name, key); failed = true; OK:; } diff --git a/src/build/libraries.c b/src/build/libraries.c index 5616b7707..77f88cf8d 100644 --- a/src/build/libraries.c +++ b/src/build/libraries.c @@ -10,7 +10,8 @@ const char *manifest_default_keys[][2] = { {"dependencies", "List of C3 libraries to also include."}, {"exec", "Scripts run for all platforms."}, {"provides", "The library name"}, - {"targets", "The map of supported platforms"} + {"targets", "The map of supported platforms"}, + {"wincrt", "Windows CRT linking: none, static, dynamic."} }; const int manifest_default_keys_count = ELEMENTLEN(manifest_default_keys); @@ -25,6 +26,7 @@ const char *manifest_target_keys[][2] = { {"exec", "Scripts to also run for the target."}, {"linked-libraries", "Libraries linked by the linker for this target, overriding global settings."}, {"link-args", "Linker arguments for this target."}, + {"wincrt", "Windows CRT linking: none, static, dynamic."} }; @@ -50,6 +52,7 @@ static inline void parse_library_type(Library *library, LibraryTarget ***target_ check_json_keys(manifest_target_keys, manifest_target_keys_count, manifest_deprecated_target_keys, manifest_deprecated_target_key_count, member, key, "--list-library-properties"); LibraryTarget *library_target = CALLOCS(LibraryTarget); library_target->parent = library; + library_target->win_crt = WIN_CRT_DEFAULT; ArchOsTarget target = arch_os_target_from_string(key); if (target == ARCH_OS_TARGET_DEFAULT) { @@ -58,6 +61,7 @@ static inline void parse_library_type(Library *library, LibraryTarget ***target_ library_target->arch_os = target; vec_add(*target_group, library_target); parse_library_target(library, library_target, key, member); + if (library_target->win_crt == WIN_CRT_DEFAULT) library_target->win_crt = library->win_crt; } } @@ -79,6 +83,7 @@ static inline void parse_library_target(Library *library, LibraryTarget *target, target->cc = get_string(library->dir, target_name, object, "cc", library->cc); target->cflags = get_cflags(library->dir, target_name, object, library->cflags); target->csource_dirs = library->csource_dirs; + target->win_crt = (WinCrtLinking)get_valid_string_setting(library->dir, target_name, object, "wincrt", wincrt_linking, 0, 3, "'none', 'static' or 'dynamic'."); get_list_append_strings(library->dir, target_name, object, &target->csource_dirs, "c-sources", "c-sources-override", "c-sources-add"); } @@ -100,6 +105,7 @@ static Library *add_library(JSONObject *object, const char *dir) library->dependencies = get_optional_string_array(library->dir, NULL, object, "dependencies"); library->cc = get_optional_string(dir, NULL, object, "cc"); library->cflags = get_cflags(library->dir, NULL, object, NULL); + library->win_crt = (WinCrtLinking)get_valid_string_setting(library->dir, NULL, object, "wincrt", wincrt_linking, 0, 3, "'none', 'static' or 'dynamic'."); get_list_append_strings(library->dir, NULL, object, &library->csource_dirs, "c-sources", "c-sources-override", "c-sources-add"); parse_library_type(library, &library->targets, json_obj_get(object, "targets")); return library; diff --git a/src/compiler/linker.c b/src/compiler/linker.c index 5d5325a4a..e66ff835e 100644 --- a/src/compiler/linker.c +++ b/src/compiler/linker.c @@ -88,6 +88,19 @@ static void linker_setup_windows(const char ***args_ref, Linker linker_type) // so we do not link with debug dll versions of libc. link_with_dynamic_debug_libc = false; #endif + WinCrtLinking linking = active_target.win.crt_linking; + FOREACH(Library *, library, active_target.library_list) + { + WinCrtLinking wincrt = library->target_used->win_crt; + if (wincrt == WIN_CRT_DEFAULT) continue; + if (linking != WIN_CRT_DEFAULT) + { + WARNING("Mismatch between CRT linking in library %s and previously selected type.", library->dir); + continue; + } + linking = wincrt; + } + if (!active_target.win.sdk) { const char *path = windows_cross_compile_library(); diff --git a/src/utils/common.h b/src/utils/common.h index f46685bc3..cce6449d4 100644 --- a/src/utils/common.h +++ b/src/utils/common.h @@ -106,7 +106,7 @@ #define FATAL_ERROR(_string, ...) do { error_exit("FATAL ERROR %s -> in %s @ in %s:%d ", _string, __func__, __FILE__, __LINE__, ##__VA_ARGS__); } while(0) #define ASSERT(_condition, _string, ...) while (!(_condition)) { FATAL_ERROR(_string, ##__VA_ARGS__); } - +#define WARNING(_string, ...) do { eprintf("WARNING: "); eprintf(_string, ##__VA_ARGS__); eprintf("\n"); } while(0) #define UNREACHABLE FATAL_ERROR("Should be unreachable"); #define TODO FATAL_ERROR("TODO reached");