0.1.1: Add -L and -l parameters, also incomplete support of .c3i files.

This commit is contained in:
Christoffer Lerno
2022-04-15 18:52:36 +02:00
parent 828724f593
commit ecdcd8f959
9 changed files with 86 additions and 22 deletions

View File

@@ -100,6 +100,8 @@ static void usage(void)
OUTPUT(" -gline-tables-only - Only emit line tables for debugging.");
OUTPUT("");
OUTPUT("");
OUTPUT(" -l <library> - Link with the library provided.");
OUTPUT(" -L <library dir> - Append the directory to the linker search paths.");
OUTPUT(" -z <argument> - Send the <argument> as a parameter to the linker.");
OUTPUT("");
OUTPUT(" --reloc=<option> - Relocation model: none, pic, PIC, pie, PIE");
@@ -301,6 +303,15 @@ static void print_version(void)
OUTPUT("LLVM default target: %s", llvm_target);
}
static void add_linker_arg(BuildOptions *options, const char *arg)
{
if (options->linker_arg_count == MAX_LIB_DIRS)
{
error_exit("Too many linker arguments are given, more than %d\n", MAX_LIB_DIRS);
}
options->linker_args[options->linker_arg_count++] = arg;
}
static int parse_multi_option(const char *start, unsigned count, const char** elements)
{
const char *arg = current_arg;
@@ -349,7 +360,7 @@ static void parse_option(BuildOptions *options)
break;
case 'z':
if (at_end()) error_exit("error: -z needs a value");
options->linker_args[options->linker_arg_count++] = next_arg();
add_linker_arg(options, next_arg());
return;
case 'o':
if (at_end()) error_exit("error: -o needs a name");
@@ -396,6 +407,28 @@ static void parse_option(BuildOptions *options)
}
options->compile_option = COMPILE_LEX_ONLY;
return;
case 'L':
if (at_end() || next_is_opt()) error_exit("error: -L needs a directory.");
add_linker_arg(options, "-L");
add_linker_arg(options, check_dir(next_arg()));
return;
case 'l':
{
if (at_end() || next_is_opt()) error_exit("error: -l needs a library name.");
const char *lib = next_arg();
const char *framework = str_without_suffix(lib, ".framework");
if (framework)
{
add_linker_arg(options, "-framework");
add_linker_arg(options, framework);
}
else
{
add_linker_arg(options, "-l");
add_linker_arg(options, lib);
}
return;
}
case 'P':
if (options->compile_option != COMPILE_NORMAL)
{

View File

@@ -204,9 +204,13 @@ typedef struct BuildOptions_
{
const char* lib_dir[MAX_LIB_DIRS];
const char* linker_args[MAX_LIB_DIRS];
const char* linker_lib_dir[MAX_LIB_DIRS];
const char* linker_libs[MAX_LIB_DIRS];
const char* std_lib_dir;
int lib_count;
int linker_arg_count;
int linker_lib_dir_count;
int linker_lib_count;
int build_threads;
const char** files;
const char* output_name;

View File

@@ -25,6 +25,8 @@ double compiler_ir_gen_time;
double compiler_codegen_time;
double compiler_link_time;
const char* c3_suffix_list[3] = { ".c3", ".c3t", ".c3i" };
void compiler_init(const char *std_lib_dir)
{
compiler_init_time = -1;
@@ -334,11 +336,9 @@ void compiler_compile(void)
free(obj_files);
}
static const char **target_expand_source_names(const char** dirs, const char *suffix1, const char *suffix2, bool error_on_mismatch)
static const char **target_expand_source_names(const char** dirs, const char **suffix_list, int suffix_count, bool error_on_mismatch)
{
const char **files = NULL;
size_t len1 = strlen(suffix1);
size_t len2 = strlen(suffix2);
VECEACH(dirs, i)
{
const char *name = dirs[i];
@@ -349,26 +349,25 @@ static const char **target_expand_source_names(const char** dirs, const char *su
if (name_len == 1 || name[name_len - 2] == '/')
{
char *path = copy_string(name, name_len - 1);
file_add_wildcard_files(&files, path, false, suffix1, suffix2);
file_add_wildcard_files(&files, path, false, suffix_list, suffix_count);
continue;
}
if (name[name_len - 2] != '*') goto INVALID_NAME;
if (name_len == 2 || name[name_len - 3] == '/')
{
char *path = copy_string(name, name_len - 2);
file_add_wildcard_files(&files, path, true, suffix1, suffix2);
file_add_wildcard_files(&files, path, true, suffix_list, suffix_count);
continue;
}
goto INVALID_NAME;
}
if (name_len < 4) goto INVALID_NAME;
if (strcmp(&name[name_len - len1], suffix1) != 0 &&
(name_len < 5 || strcmp(&name[name_len - len2], suffix2) != 0)) goto INVALID_NAME;
if (name_len < 5 || !file_has_suffix_in_list(name, name_len, suffix_list, suffix_count)) goto INVALID_NAME;
vec_add(files, name);
continue;
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);
error_exit("File names must end with %s or they cannot be compiled: '%s' is invalid.", suffix_list[0], name);
}
return files;
}
@@ -490,12 +489,14 @@ void print_syntax(BuildOptions *options)
}
}
void compile()
{
active_target.sources = target_expand_source_names(active_target.source_dirs, ".c3", ".c3t", true);
active_target.sources = target_expand_source_names(active_target.source_dirs, c3_suffix_list, 3, true);
if (active_target.csource_dirs)
{
active_target.csources = target_expand_source_names(active_target.csource_dirs, ".c", ".c", false);
static const char* c_suffix_list[3] = { ".c" };
active_target.csources = target_expand_source_names(active_target.csource_dirs, c_suffix_list, 1, false);
}
global_context.sources = active_target.sources;
symtab_init(active_target.symtab_size);

View File

@@ -21,4 +21,5 @@ extern double compiler_parsing_time;
extern double compiler_sema_time;
extern double compiler_ir_gen_time;
extern double compiler_codegen_time;
extern double compiler_link_time;
extern double compiler_link_time;
extern const char* c3_suffix_list[3];

View File

@@ -250,7 +250,7 @@ void sema_analysis_run(void)
// Add the standard library
if (global_context.lib_dir && !active_target.no_stdlib)
{
file_add_wildcard_files(&global_context.sources, global_context.lib_dir, true, ".c3", ".c3i");
file_add_wildcard_files(&global_context.sources, global_context.lib_dir, true, c3_suffix_list, 3);
}
// Load and parse all files.

View File

@@ -75,6 +75,7 @@ static inline bool is_path_separator(char c)
#endif
}
/**
* Split a file into path + filename, allocating memory for them and returning them in
* the out params
@@ -273,7 +274,18 @@ void file_find_top_dir()
}
}
void file_add_wildcard_files(const char ***files, const char *path, bool recursive, const char *suffix1, const char *suffix2)
bool file_has_suffix_in_list(const char *file_name, int name_len, const char **suffix_list, int suffix_count)
{
for (int i = 0; i < suffix_count; i++)
{
const char *suffix = suffix_list[i];
int len = (int)strlen(suffix);
if (strncmp(&file_name[name_len - len], suffix, len) == 0) return true;
}
return false;
}
void file_add_wildcard_files(const char ***files, const char *path, bool recursive, const char **suffix_list, int suffix_count)
{
#ifdef _MSC_VER
DIR *dir = opendir(strip_drive_prefix(path));
@@ -286,15 +298,12 @@ 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 == 0 || ent->d_name[0] == '.') continue;
// Doesn't end with .c3
if (namelen < 3 || (strncmp(&ent->d_name[namelen - len1], suffix1, len1) != 0 && strncmp(&ent->d_name[namelen - len2], suffix2, len2) != 0))
if (namelen < 3 || !file_has_suffix_in_list(ent->d_name, namelen, suffix_list, suffix_count))
{
char *new_path = NULL;
char *format = path_ends_with_slash ? "%s%s" : "%s/%s";
@@ -312,7 +321,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, suffix1, suffix2);
file_add_wildcard_files(files, new_path, recursive, suffix_list, suffix_count);
}
free(new_path);
continue;

View File

@@ -28,13 +28,15 @@ typedef struct Task_
typedef void *TaskQueueRef;
const char *str_without_suffix(const char *name, const char *suffix);
bool filenamesplit(const char *path, char** filename_ptr, char** directory_ptr);
const char* expand_path(const char* path);
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, const char *suffix1, const char *suffix2);
bool file_has_suffix_in_list(const char *file_name, int name_len, const char **suffix_list, int suffix_count);
void file_add_wildcard_files(const char ***files, const char *path, bool recursive, const char **suffix_list, int suffix_count);
void *cmalloc(size_t size);
void *ccalloc(size_t size, size_t elements);
void memory_init(void);
@@ -508,7 +510,7 @@ typedef struct StringSlice_
char *strcat_arena(const char *a, const char *b);
int str_in_list(const char *value, unsigned count, const char** elements);
char *strformat(const char *var, ...) __printflike(1, 2);
char *stringcopy(const char *start, size_t len);
StringSlice strnexttok(StringSlice *slice, char separator);
static inline bool slicestrcmp(StringSlice slice, const char *other)
{

View File

@@ -33,6 +33,20 @@ char *strformat(const char *var, ...)
return buffer;
}
const char *str_without_suffix(const char *name, const char *suffix)
{
size_t name_len = strlen(name);
size_t suffix_len = strlen(suffix);
if (name_len <= suffix_len) return NULL;
if (memcmp(name + name_len - suffix_len, suffix, suffix_len) != 0) return NULL;
size_t result_len = name_len - suffix_len;
char *name_copy = malloc_string(result_len + 1);
memcpy(name_copy, name, result_len);
name_copy[result_len] = 0;
return name_copy;
}
StringSlice strnexttok(StringSlice *slice, char separator)
{
for (size_t i = 0; i < slice->len; i++)

View File

@@ -1 +1 @@
#define COMPILER_VERSION "0.1.0"
#define COMPILER_VERSION "0.1.1"