aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--flake.nix9
-rw-r--r--justfile5
-rw-r--r--src/cli.c16
-rw-r--r--src/cli.h2
-rw-r--r--src/main.c2
-rw-r--r--src/preprocess.c21
-rw-r--r--src/preprocess.h2
-rw-r--r--tests/helpers.sh10
9 files changed, 55 insertions, 14 deletions
diff --git a/Makefile b/Makefile
index e9b1143..70c141b 100644
--- a/Makefile
+++ b/Makefile
@@ -30,6 +30,6 @@ $(BUILD_ROOT_DIR)/$(TARGET): $(OBJECTS)
# TODO: provide release build?
$(BUILD_DIR)/%.o: src/%.c
- $(CC) -c -Wall -MMD -g -O0 --std=c23 -o $@ $<
+ $(CC) -c $(CFLAGS) -Wall -MMD -g -O0 --std=c23 -o $@ $<
-include $(BUILD_DIR)/*.d
diff --git a/flake.nix b/flake.nix
index 8cbc8ec..82e041b 100644
--- a/flake.nix
+++ b/flake.nix
@@ -53,6 +53,15 @@
# Disable some kinds of hardening to disable GCC optimization.
# cf. https://nixos.wiki/wiki/C#Hardening_flags
hardeningDisable = [ "fortify" ];
+ shellHook = ''
+ export CFLAGS="$(
+ gcc -E -Wp,-v -xc /dev/null 2>&1 |
+ sed -n '/#include <...>/,/End of search list/p' |
+ sed '1d;$d' |
+ awk '{ print "-I"$1; }' |
+ xargs
+ )"
+ '';
};
formatter = treefmt.config.build.wrapper;
diff --git a/justfile b/justfile
index 71da21c..bea5863 100644
--- a/justfile
+++ b/justfile
@@ -3,15 +3,18 @@ build N="1":
set -e
if [[ {{N}} = 1 ]]; then
cc=gcc
+ cflags=
target=ducc
elif [[ {{N}} = 2 ]]; then
cc=./build/ducc
+ cflags="${CFLAGS:-}"
target=ducc{{N}}
else
cc="./build/ducc$(({{N}} - 1))"
+ cflags="${CFLAGS:-}"
target=ducc{{N}}
fi
- CC="$cc" TARGET="$target" make
+ CC="$cc" CFLAGS="$cflags" TARGET="$target" make
build-upto-5-gen:
just build 1
diff --git a/src/cli.c b/src/cli.c
index 7388370..9b62614 100644
--- a/src/cli.c
+++ b/src/cli.c
@@ -14,6 +14,8 @@ CliArgs* parse_cli_args(int argc, char** argv) {
bool opt_c = false;
bool opt_E = false;
bool opt_MMD = false;
+ StrArray include_dirs;
+ strings_init(&include_dirs);
for (int i = 1; i < argc; ++i) {
if (argv[i][0] != '-') {
@@ -29,6 +31,19 @@ CliArgs* parse_cli_args(int argc, char** argv) {
// ignore
} else if (c == 'M' && argv[i][2] == '\0') {
// ignore -M
+ } else if (c == 'I') {
+ const char* dir = NULL;
+ if (argv[i][2] != '\0') {
+ // -Ipath format
+ dir = argv[i] + 2;
+ } else if (argc > i + 1) {
+ // -I path format
+ dir = argv[i + 1];
+ ++i;
+ } else {
+ fatal_error("-I requires directory");
+ }
+ strings_push(&include_dirs, dir);
} else if (c == 'o') {
if (argc <= i + 1) {
fatal_error("-o requires filename");
@@ -63,6 +78,7 @@ CliArgs* parse_cli_args(int argc, char** argv) {
a->totally_deligate_to_gcc = false;
a->gcc_command = NULL;
a->generate_deps = opt_MMD;
+ a->include_dirs = include_dirs;
if (!a->only_compile && str_ends_with(a->input_filename, ".o")) {
a->totally_deligate_to_gcc = true;
diff --git a/src/cli.h b/src/cli.h
index 3b1e7f5..51263e2 100644
--- a/src/cli.h
+++ b/src/cli.h
@@ -1,6 +1,7 @@
#ifndef DUCC_CLI_H
#define DUCC_CLI_H
+#include "common.h"
#include "std.h"
typedef struct {
@@ -12,6 +13,7 @@ typedef struct {
bool generate_deps;
bool totally_deligate_to_gcc;
const char* gcc_command;
+ StrArray include_dirs;
} CliArgs;
CliArgs* parse_cli_args(int argc, char** argv);
diff --git a/src/main.c b/src/main.c
index 469e5db..bd1391c 100644
--- a/src/main.c
+++ b/src/main.c
@@ -22,7 +22,7 @@ int main(int argc, char** argv) {
StrArray included_files;
strings_init(&included_files);
- TokenArray* pp_tokens = preprocess(source, &included_files);
+ TokenArray* pp_tokens = preprocess(source, &included_files, &cli_args->include_dirs);
if (cli_args->preprocess_only) {
FILE* output_file = cli_args->output_filename ? fopen(cli_args->output_filename, "w") : stdout;
diff --git a/src/preprocess.c b/src/preprocess.c
index 5e029f2..00b01dd 100644
--- a/src/preprocess.c
+++ b/src/preprocess.c
@@ -562,7 +562,8 @@ typedef struct {
StrArray* included_files;
} Preprocessor;
-static TokenArray* do_preprocess(InFile* src, int depth, MacroArray* macros, StrArray* included_files);
+static TokenArray* do_preprocess(InFile* src, int depth, MacroArray* macros, StrArray* included_files,
+ StrArray* user_include_dirs);
static Preprocessor* preprocessor_new(TokenArray* pp_tokens, int include_depth, MacroArray* macros,
StrArray* included_files) {
@@ -744,7 +745,7 @@ static void expand_include_directive(Preprocessor* pp, const char* include_name,
}
TokenArray* include_pp_tokens =
- do_preprocess(include_source, pp->include_depth + 1, pp->macros, pp->included_files);
+ do_preprocess(include_source, pp->include_depth + 1, pp->macros, pp->included_files, NULL);
tokens_pop(include_pp_tokens); // pop EOF token
pp->pos = insert_pp_tokens(pp, pp->pos, include_pp_tokens);
}
@@ -1541,23 +1542,33 @@ static char* get_ducc_include_path() {
return buf;
}
-static TokenArray* do_preprocess(InFile* src, int depth, MacroArray* macros, StrArray* included_files) {
+static TokenArray* do_preprocess(InFile* src, int depth, MacroArray* macros, StrArray* included_files,
+ StrArray* user_include_dirs) {
TokenArray* pp_tokens = pp_tokenize(src);
Preprocessor* pp = preprocessor_new(pp_tokens, depth, macros, included_files);
+
+ // Ducc's built-in headers has highest priority.
add_include_path(pp, get_ducc_include_path());
+
+ if (user_include_dirs) {
+ for (size_t i = 0; i < user_include_dirs->len; ++i) {
+ add_include_path(pp, user_include_dirs->data[i]);
+ }
+ }
add_include_path(pp, "/usr/local/include");
add_include_path(pp, "/usr/include/x86_64-linux-gnu");
add_include_path(pp, "/usr/include");
+
preprocess_preprocessing_file(pp);
remove_pp_directives(pp);
return pp->pp_tokens;
}
-TokenArray* preprocess(InFile* src, StrArray* included_files) {
+TokenArray* preprocess(InFile* src, StrArray* included_files, StrArray* user_include_dirs) {
MacroArray* macros = macros_new();
add_predefined_macros(macros);
strings_push(included_files, src->loc.filename);
- return do_preprocess(src, 0, macros, included_files);
+ return do_preprocess(src, 0, macros, included_files, user_include_dirs);
}
void print_token_to_file(FILE* out, TokenArray* pp_tokens) {
diff --git a/src/preprocess.h b/src/preprocess.h
index 5449857..e78776f 100644
--- a/src/preprocess.h
+++ b/src/preprocess.h
@@ -6,7 +6,7 @@
#include "io.h"
#include "token.h"
-TokenArray* preprocess(InFile* src, StrArray* included_files);
+TokenArray* preprocess(InFile* src, StrArray* included_files, StrArray* user_include_dirs);
void print_token_to_file(FILE* output_file, TokenArray* pp_tokens);
#endif
diff --git a/tests/helpers.sh b/tests/helpers.sh
index a69e213..adc9511 100644
--- a/tests/helpers.sh
+++ b/tests/helpers.sh
@@ -1,7 +1,7 @@
function test_exit_code() {
cat > main.c
- "$ducc" -o a.out main.c
+ "$ducc" "${CFLAGS:-}" -o a.out main.c
set +e
./a.out
exit_code=$?
@@ -18,7 +18,7 @@ function test_exit_code() {
function test_diff() {
cat > main.c
- "$ducc" -o a.out main.c
+ "$ducc" "${CFLAGS:-}" -o a.out main.c
if [[ ! -f input ]]; then
touch input
fi
@@ -37,7 +37,7 @@ function test_compile_error() {
cat > main.c
set +e
- "$ducc" main.c > /dev/null 2> output
+ "$ducc" "${CFLAGS:-}" main.c > /dev/null 2> output
exit_code=$?
set -e
@@ -52,14 +52,14 @@ function test_compile_error() {
function test_cpp() {
cat > main.c
- "$ducc" -E main.c > output
+ "$ducc" "${CFLAGS:-}" -E main.c > output
diff -u -Z expected output
}
function test_example() {
filename="../../../examples/$1.c"
- "$ducc" -o a.out "$filename"
+ "$ducc" "${CFLAGS:-}" -o a.out "$filename"
if [[ ! -f input ]]; then
touch input
fi