Add support from compiling c from c3c.

This commit is contained in:
Christoffer Lerno
2021-12-09 23:38:57 +01:00
parent 379a66a14b
commit 8aa00b015b
10 changed files with 98 additions and 20 deletions

View File

@@ -0,0 +1,4 @@
int test_doubler(int d)
{
return d * d;
}

View File

@@ -1,11 +1,13 @@
module hello_world;
import bar;
extern fn void printf(char *hello);
extern fn int test_doubler(int);
extern fn void printf(char *, ...);
fn int main(int x)
{
printf("Hello World!\n");
bar::test();
printf("Hello double: %d\n", test_doubler(11));
return 1;
}

View File

@@ -8,3 +8,7 @@ warnings = ["no-unused"]
sources = ["./**"]
# libraries to use
libs = []
# c compiler
cc = "cc"
# c sources
csources = ["./csource/**"]

View File

@@ -242,6 +242,9 @@ typedef struct
CompilerBackend backend;
uint32_t symtab_size;
uint32_t switchrange_max_size;
const char *cc;
const char **csource_dirs;
const char **csources;
struct
{
SoftFloat soft_float : 3;

View File

@@ -134,10 +134,8 @@ void project_add_target(Project *project, TomlValue *wrapped_table, const char *
target->arch_os_target = ARCH_OS_TARGET_DEFAULT;
target->debug_info = DEBUG_INFO_NONE;
target->symtab_size = DEFAULT_SYMTAB_SIZE;
vec_add(project->targets, target);
TomlTable *table = wrapped_table->value.table;
target->name = get_valid_string(table, "name", type, true);
VECEACH(project->targets, i)
{
@@ -148,6 +146,10 @@ void project_add_target(Project *project, TomlValue *wrapped_table, const char *
error_exit("More %s contained more than one target with the name %s. Please make all target names unique.", PROJECT_TOML, target->name);
}
}
target->cc = get_valid_string(table, "cc", type, false);
if (!target->cc) target->cc = "cc";
target->csource_dirs = get_valid_array(table, "csources", type, false);
type = strformat("%s %s", type, target->name);
target->version = get_valid_string(table, "version", type, false);
if (!target->version) target->version = "1.0.0";

View File

@@ -303,7 +303,7 @@ void compiler_compile(void)
if (global_context.lib_dir)
{
file_add_wildcard_files(&global_context.sources, global_context.lib_dir, true);
file_add_wildcard_files(&global_context.sources, global_context.lib_dir, true, ".c3", ".c3i");
}
bool has_error = false;
VECEACH(global_context.sources, i)
@@ -417,8 +417,28 @@ void compiler_compile(void)
error_exit("No output files found.");
}
unsigned cfiles = vec_size(active_target.csources);
CompileData *compile_data = malloc(sizeof(CompileData) * output_file_count);
const char **obj_files = malloc(sizeof(char*) * output_file_count);
const char **obj_files = malloc(sizeof(char*) * (output_file_count + cfiles));
if (cfiles)
{
platform_compiler(active_target.csources, cfiles);
for (int i = 0; i < cfiles; i++)
{
char *filename = NULL;
char *dir = NULL;
bool split_worked = filenamesplit(active_target.csources[i], &filename, &dir);
assert(split_worked);
free(dir);
size_t len = strlen(filename);
// .c -> .o (quick hack to fix the name on linux)
filename[len - 1] = 'o';
obj_files[output_file_count + i] = filename;
}
}
TaskQueueRef queue = taskqueue_create(16);
@@ -439,6 +459,7 @@ void compiler_compile(void)
assert(obj_files[i] || !create_exe);
}
output_file_count += cfiles;
free(compile_data);
if (create_exe)
@@ -466,12 +487,14 @@ void compiler_compile(void)
exit_compiler(COMPILER_SUCCESS_EXIT);
}
static void target_expand_source_names(BuildTarget *target)
static const char **target_expand_source_names(const char** dirs, const char *suffix1, const char *suffix2, bool error_on_mismatch)
{
const char **files = NULL;
VECEACH(target->source_dirs, i)
size_t len1 = strlen(suffix1);
size_t len2 = strlen(suffix2);
VECEACH(dirs, i)
{
const char *name = target->source_dirs[i];
const char *name = dirs[i];
size_t name_len = strlen(name);
if (name_len < 1) goto INVALID_NAME;
if (name[name_len - 1] == '*')
@@ -480,7 +503,7 @@ static void target_expand_source_names(BuildTarget *target)
{
char *path = strdup(name);
path[name_len - 1] = '\0';
file_add_wildcard_files(&files, path, false);
file_add_wildcard_files(&files, path, false, suffix1, suffix2);
free(path);
continue;
}
@@ -489,21 +512,22 @@ static void target_expand_source_names(BuildTarget *target)
{
char *path = strdup(name);
path[name_len - 2] = '\0';
file_add_wildcard_files(&files, path, true);
file_add_wildcard_files(&files, path, true, suffix1, suffix2);
free(path);
continue;
}
goto INVALID_NAME;
}
if (name_len < 4) goto INVALID_NAME;
if (strcmp(&name[name_len - 3], ".c3") != 0 &&
(name_len < 5 || strcmp(&name[name_len - 4], ".c3t") != 0)) goto INVALID_NAME;
if (strcmp(&name[name_len - len1], suffix1) != 0 &&
(name_len < 5 || strcmp(&name[name_len - len2], suffix2) != 0)) goto INVALID_NAME;
vec_add(files, name);
continue;
INVALID_NAME:
error_exit("File names must end with .c3 or they cannot be compiled: '%s' is invalid.", name);
if (!error_on_mismatch) continue;
error_exit("File names must end with %s or they cannot be compiled: '%s' is invalid.", name, suffix1);
}
target->sources = files;
return files;
}
void compile_target(BuildOptions *options)
@@ -520,7 +544,11 @@ void compile_file_list(BuildOptions *options)
void compile()
{
target_expand_source_names(&active_target);
active_target.sources = target_expand_source_names(active_target.source_dirs, ".c3", ".c3t", true);
if (active_target.csource_dirs)
{
active_target.csources = target_expand_source_names(active_target.csource_dirs, ".c", ".c", false);
}
global_context.sources = active_target.sources;
symtab_init(active_target.symtab_size ? active_target.symtab_size : 64 * 1024);
target_setup(&active_target);

View File

@@ -2462,6 +2462,7 @@ static inline AlignSize type_min_alignment(AlignSize a, AlignSize b)
bool obj_format_linking_supported(ObjectFormatType format_type);
bool linker(const char *output_file, const char **files, unsigned file_count);
void platform_linker(const char *output_file, const char **files, unsigned file_count);
void platform_compiler(const char **files, unsigned file_count);
#define CAT(a,b) CAT2(a,b) // force expand
#define CAT2(a,b) a##b // actually concatenate

View File

@@ -285,7 +285,7 @@ const char *concat_string_parts(const char **args)
void platform_linker(const char *output_file, const char **files, unsigned file_count)
{
const char **parts = NULL;
vec_add(parts, "cc");
vec_add(parts, active_target.cc);
VECEACH(active_target.link_args, i)
{
vec_add(parts, active_target.link_args[i]);
@@ -319,6 +319,38 @@ void platform_linker(const char *output_file, const char **files, unsigned file_
}
printf("Program linked to executable '%s'.\n", output_file);
}
void platform_compiler(const char **files, unsigned file_count)
{
const char **parts = NULL;
vec_add(parts, active_target.cc);
switch (platform_target.pie)
{
case PIE_DEFAULT:
UNREACHABLE
case PIE_NONE:
vec_add(parts, "-fno-PIE");
vec_add(parts, "-fno-pie");
break;
case PIE_SMALL:
vec_add(parts, "-fpie");
break;
case PIE_BIG:
vec_add(parts, "-fPIE");
break;
}
vec_add(parts, "-c");
for (unsigned i = 0; i < file_count; i++)
{
vec_add(parts, files[i]);
}
const char *output = concat_string_parts(parts);
if (system(output) != 0)
{
error_exit("Failed to compile c sources using command '%s'.\n", output);
}
}
bool linker(const char *output_file, const char **files, unsigned file_count)
{
return link_exe(output_file, files, file_count);

View File

@@ -278,7 +278,7 @@ void file_find_top_dir()
}
}
void file_add_wildcard_files(const char ***files, const char *path, bool recursive)
void file_add_wildcard_files(const char ***files, const char *path, bool recursive, const char *suffix1, const char *suffix2)
{
#ifdef _MSC_VER
DIR *dir = opendir(strip_drive_prefix(path));
@@ -291,13 +291,15 @@ void file_add_wildcard_files(const char ***files, const char *path, bool recursi
error_exit("Can't open the directory '%s'. Please check the paths. %s", path, strerror(errno));
}
struct dirent *ent;
size_t len1 = strlen(suffix1);
size_t len2 = strlen(suffix2);
while ((ent = readdir(dir)))
{
size_t namelen = strlen(ent->d_name);
if (namelen < 3) continue;
// Doesn't end with .c3
if (strncmp(&ent->d_name[namelen - 3], ".c3", 3) != 0)
if (strncmp(&ent->d_name[namelen - len1], suffix1, len1) != 0 && strncmp(&ent->d_name[namelen - len2], suffix2, len2) != 0)
{
char *new_path = NULL;
char *format = path_ends_with_slash ? "%s%s" : "%s/%s";
@@ -315,7 +317,7 @@ void file_add_wildcard_files(const char ***files, const char *path, bool recursi
is_directory = S_ISDIR(st.st_mode);
if (is_directory && ent->d_name[0] != '.' && recursive)
{
file_add_wildcard_files(files, new_path, recursive);
file_add_wildcard_files(files, new_path, recursive, suffix1, suffix2);
}
free(new_path);
continue;

View File

@@ -33,7 +33,7 @@ const char* find_lib_dir(void);
char *read_file(const char *path, size_t *return_size);
void path_get_dir_and_filename_from_full(const char *full_path, char **filename, char **dir_path);
void file_find_top_dir();
void file_add_wildcard_files(const char ***files, const char *path, bool recursive);
void file_add_wildcard_files(const char ***files, const char *path, bool recursive, const char *suffix1, const char *suffix2);
void *cmalloc(size_t size);
void memory_init(void);
void memory_release();