Skip to content

Commit

Permalink
Add "sources" option support for library. (#1631)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
NexushasTaken authored Nov 24, 2024
1 parent 6010183 commit c273f26
Show file tree
Hide file tree
Showing 7 changed files with 83 additions and 58 deletions.
1 change: 1 addition & 0 deletions releasenotes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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!`.
Expand Down
2 changes: 2 additions & 0 deletions src/build/build.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;
Expand Down
22 changes: 20 additions & 2 deletions src/build/libraries.c
Original file line number Diff line number Diff line change
Expand Up @@ -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')."},
Expand All @@ -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."},
Expand Down Expand Up @@ -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");
}
Expand All @@ -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"));
Expand Down Expand Up @@ -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);
Expand All @@ -312,4 +330,4 @@ void resolve_libraries(BuildTarget *build_target)
puts(execute_cmd(exec, false, NULL));
}
}
}
}
3 changes: 3 additions & 0 deletions src/build/project_creation.c
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ const char* JSON_DYNAMIC =
const char *MANIFEST_TEMPLATE =
"{\n"
" \"provides\" : \"%s\",\n"
" // \"sources\" : [ \"src/**\" ],\n"
" \"targets\" : {\n"
"%s"
" }\n"
Expand Down Expand Up @@ -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();
Expand Down
54 changes: 0 additions & 54 deletions src/compiler/compiler.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
56 changes: 55 additions & 1 deletion src/utils/file_utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -731,4 +785,4 @@ char *realpath(const char *path, char *const resolved_path)
return result;
}

#endif
#endif
3 changes: 2 additions & 1 deletion src/utils/lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);

0 comments on commit c273f26

Please sign in to comment.