mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
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
This commit is contained in:
@@ -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!`.
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
@@ -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);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user