From c273f26cb3037b38184eb0382d23f11927b98f01 Mon Sep 17 00:00:00 2001 From: Nexus <84789900+NexushasTaken@users.noreply.github.com> Date: Sun, 24 Nov 2024 22:37:15 +0800 Subject: [PATCH] Add "sources" option support for library. (#1631) * Add "sources" support for library manifest * Add "sources" to library manifest creation * Add "sources" key to target manifest * Added fallback for already made libraries * Remove src/ in library creation * add changes to releasenotes.md --- releasenotes.md | 1 + src/build/build.h | 2 ++ src/build/libraries.c | 22 ++++++++++++-- src/build/project_creation.c | 3 ++ src/compiler/compiler.c | 54 ---------------------------------- src/utils/file_utils.c | 56 +++++++++++++++++++++++++++++++++++- src/utils/lib.h | 3 +- 7 files changed, 83 insertions(+), 58 deletions(-) diff --git a/releasenotes.md b/releasenotes.md index 6feffa5d8..8edd32004 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -7,6 +7,7 @@ - Init command will now add `test-sources` to `project.json` #1520 - `a++` may be discarded if `a` is optional and ++/-- works for overloaded operators. - Improve support for Windows cross compilation on targets with case sensitive file systems. +- Add "sources" support to library `manifest.json`, defaults to root folder if unspecified. ### Fixes - Fix bug where `a > 0 ? f() : g()` could cause a compiler crash if both returned `void!`. diff --git a/src/build/build.h b/src/build/build.h index 9326578cc..eb112e5ea 100644 --- a/src/build/build.h +++ b/src/build/build.h @@ -523,6 +523,7 @@ typedef struct const char *cc; const char *cflags; WinCrtLinking win_crt; + const char **source_dirs; const char **csource_dirs; const char **csources; const char **cinclude_dirs; @@ -540,6 +541,7 @@ typedef struct Library__ const char **execs; const char *cc; const char *cflags; + const char **source_dirs; const char **csource_dirs; const char **cinclude_dirs; WinCrtLinking win_crt; diff --git a/src/build/libraries.c b/src/build/libraries.c index 840312271..252183e04 100644 --- a/src/build/libraries.c +++ b/src/build/libraries.c @@ -4,6 +4,7 @@ #define MANIFEST_FILE "manifest.json" const char *manifest_default_keys[][2] = { + {"sources", "Paths to library sources for targets, such as interface files."}, {"c-sources", "Set the C sources to be compiled."}, {"c-include-dirs", "Set the include directories for C sources."}, {"cc", "Set C compiler (defaults to 'cc')."}, @@ -19,6 +20,8 @@ const char *manifest_default_keys[][2] = { const int manifest_default_keys_count = ELEMENTLEN(manifest_default_keys); const char *manifest_target_keys[][2] = { + {"sources", "Additional library sources to be compiled for this target."}, + {"sources-override", "Paths to library sources for this target, overriding global settings."}, {"c-sources", "Additional C sources to be compiled for the target."}, {"c-sources-override", "C sources to be compiled, overriding global settings."}, {"c-include-dirs", "C source include directories for the target."}, @@ -86,9 +89,11 @@ static inline void parse_library_target(Library *library, LibraryTarget *target, target->execs = get_string_array(library->dir, target_name, object, "exec", false); target->cc = get_string(library->dir, target_name, object, "cc", library->cc); target->cflags = get_cflags(library->dir, target_name, object, library->cflags); + target->source_dirs = library->source_dirs; target->csource_dirs = library->csource_dirs; target->cinclude_dirs = library->cinclude_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->source_dirs, "sources", "sources-override", "sources-add"); get_list_append_strings(library->dir, target_name, object, &target->csource_dirs, "c-sources", "c-sources-override", "c-sources-add"); get_list_append_strings(library->dir, target_name, object, &target->cinclude_dirs, "c-include-dirs", "c-include-dirs-override", "c-include-dirs-add"); } @@ -112,6 +117,7 @@ static Library *add_library(JSONObject *object, const char *dir) 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->source_dirs, "sources", "sources-override", "sources-add"); get_list_append_strings(library->dir, NULL, object, &library->csource_dirs, "c-sources", "c-sources-override", "c-sources-add"); get_list_append_strings(library->dir, NULL, object, &library->cinclude_dirs, "c-include-dirs", "c-include-dirs-override", "c-include-dirs-add"); parse_library_type(library, &library->targets, json_map_get(object, "targets")); @@ -291,7 +297,19 @@ void resolve_libraries(BuildTarget *build_target) { vec_add(build_target->ccompiling_libraries, target); } - file_add_wildcard_files(&build_target->sources, library->dir, false, c3_suffix_list, 3); + if (target->source_dirs) + { + const char **files = target_expand_source_names(library->dir, target->source_dirs, c3_suffix_list, &build_target->object_files, 3, true); + FOREACH(const char *, file, files) + { + vec_add(build_target->sources, file); + } + } + else + { + // fallback if sources doesn't exist + file_add_wildcard_files(&build_target->sources, library->dir, false, c3_suffix_list, 3); + } vec_add(build_target->library_list, library); const char *libdir = file_append_path(library->dir, arch_os_target[build_target->arch_os_target]); if (file_is_dir(libdir)) vec_add(build_target->linker_libdirs, libdir); @@ -312,4 +330,4 @@ void resolve_libraries(BuildTarget *build_target) puts(execute_cmd(exec, false, NULL)); } } -} \ No newline at end of file +} diff --git a/src/build/project_creation.c b/src/build/project_creation.c index 7374d3b99..aed49de16 100644 --- a/src/build/project_creation.c +++ b/src/build/project_creation.c @@ -138,6 +138,7 @@ const char* JSON_DYNAMIC = const char *MANIFEST_TEMPLATE = "{\n" " \"provides\" : \"%s\",\n" + " // \"sources\" : [ \"src/**\" ],\n" " \"targets\" : {\n" "%s" " }\n" @@ -219,9 +220,11 @@ void create_library(BuildOptions *build_options) } chdir_or_fail(build_options, dir); + create_file_or_fail(build_options, "LICENSE", NULL); create_file_or_fail(build_options, "README.md", LIB_README, build_options->project_name); mkdir_or_fail(build_options, "scripts"); + scratch_buffer_clear(); scratch_buffer_printf("%s.c3i", build_options->project_name); const char *interface_file = scratch_buffer_copy(); diff --git a/src/compiler/compiler.c b/src/compiler/compiler.c index 46fe17407..aa5987a5e 100644 --- a/src/compiler/compiler.c +++ b/src/compiler/compiler.c @@ -751,60 +751,6 @@ void compiler_compile(void) } free(obj_files); } - -static const char **target_expand_source_names(const char *base_dir, const char** dirs, const char **suffix_list, const char ***object_list_ref, int suffix_count, bool error_on_mismatch) -{ - const char **files = NULL; - FOREACH(const char *, name, dirs) - { - if (base_dir) name = file_append_path(base_dir, name); - INFO_LOG("Searching for sources in %s", name); - size_t name_len = strlen(name); - if (name_len < 1) goto INVALID_NAME; - if (object_list_ref && (str_has_suffix(name, ".o") || str_has_suffix(name, ".obj"))) - { - if (!file_exists(name)) - { - if (!error_on_mismatch) continue; - error_exit("The object file '%s' could not be found.", name); - } - vec_add(*object_list_ref, name); - continue; - } - if (name[name_len - 1] == '*') - { - if (name_len == 1 || name[name_len - 2] == '/') - { - char *path = str_copy(name, name_len - 1); - file_add_wildcard_files(&files, path, false, suffix_list, suffix_count); - continue; - } - if (name[name_len - 2] != '*') goto INVALID_NAME; - INFO_LOG("Searching for wildcard sources in %s", name); - if (name_len == 2 || name[name_len - 3] == '/') - { - const char *path = str_copy(name, name_len - 2); - DEBUG_LOG("Reduced path %s", path); - file_add_wildcard_files(&files, path, true, suffix_list, suffix_count); - continue; - } - goto INVALID_NAME; - } - if (!file_has_suffix_in_list(name, name_len, suffix_list, suffix_count)) goto INVALID_NAME; - vec_add(files, name); - continue; - INVALID_NAME: - if (file_is_dir(name)) - { - file_add_wildcard_files(&files, name, true, suffix_list, suffix_count); - continue; - } - if (!error_on_mismatch) continue; - error_exit("File names must be a non-empty name followed by %s or they cannot be compiled: '%s' is invalid.", suffix_list[0], name); - } - return files; -} - INLINE void expand_csources(const char *base_dir, const char **source_dirs, const char ***sources_ref) { if (source_dirs) diff --git a/src/utils/file_utils.c b/src/utils/file_utils.c index b10fc0088..a8f0c1f6f 100644 --- a/src/utils/file_utils.c +++ b/src/utils/file_utils.c @@ -640,6 +640,60 @@ void file_add_wildcard_files(const char ***files, const char *path, bool recursi #endif +const char **target_expand_source_names(const char *base_dir, const char** dirs, const char **suffix_list, const char ***object_list_ref, int suffix_count, bool error_on_mismatch) +{ + const char **files = NULL; + FOREACH(const char *, name, dirs) + { + if (base_dir) name = file_append_path(base_dir, name); + INFO_LOG("Searching for sources in %s", name); + size_t name_len = strlen(name); + if (name_len < 1) goto INVALID_NAME; + if (object_list_ref && (str_has_suffix(name, ".o") || str_has_suffix(name, ".obj"))) + { + if (!file_exists(name)) + { + if (!error_on_mismatch) continue; + error_exit("The object file '%s' could not be found.", name); + } + vec_add(*object_list_ref, name); + continue; + } + if (name[name_len - 1] == '*') + { + if (name_len == 1 || name[name_len - 2] == '/') + { + char *path = str_copy(name, name_len - 1); + file_add_wildcard_files(&files, path, false, suffix_list, suffix_count); + continue; + } + if (name[name_len - 2] != '*') goto INVALID_NAME; + INFO_LOG("Searching for wildcard sources in %s", name); + if (name_len == 2 || name[name_len - 3] == '/') + { + const char *path = str_copy(name, name_len - 2); + DEBUG_LOG("Reduced path %s", path); + file_add_wildcard_files(&files, path, true, suffix_list, suffix_count); + continue; + } + goto INVALID_NAME; + } + if (!file_has_suffix_in_list(name, name_len, suffix_list, suffix_count)) goto INVALID_NAME; + vec_add(files, name); + continue; + INVALID_NAME: + if (file_is_dir(name)) + { + file_add_wildcard_files(&files, name, true, suffix_list, suffix_count); + continue; + } + if (!error_on_mismatch) continue; + error_exit("File names must be a non-empty name followed by %s or they cannot be compiled: '%s' is invalid.", suffix_list[0], name); + } + return files; +} + + #define BUFSIZE 1024 const char *execute_cmd(const char *cmd, bool ignore_failure, const char *stdin_string) { @@ -731,4 +785,4 @@ char *realpath(const char *path, char *const resolved_path) return result; } -#endif +#endif \ No newline at end of file diff --git a/src/utils/lib.h b/src/utils/lib.h index c131638a7..b9eb5b6d6 100644 --- a/src/utils/lib.h +++ b/src/utils/lib.h @@ -90,6 +90,8 @@ void file_add_wildcard_files(const char ***files, const char *path, bool recursi const char *file_append_path(const char *path, const char *name); const char *file_append_path_temp(const char *path, const char *name); +const char **target_expand_source_names(const char *base_dir, const char** dirs, const char **suffix_list, const char ***object_list_ref, int suffix_count, bool error_on_mismatch); + const char *execute_cmd(const char *cmd, bool ignore_failure, const char *stdin_string); bool execute_cmd_failable(const char *cmd, const char **result, const char *stdin_string); @@ -713,4 +715,3 @@ const char *zip_dir_iterator(FILE *zip, ZipDirIterator *iterator); const char *zip_dir_iterator_next(ZipDirIterator *iterator, ZipFile *file); const char *zip_file_read(FILE *zip, ZipFile *file, void **buffer_ptr); const char *zip_file_write(FILE *zip, ZipFile *file, const char *dir, bool overwrite); -