diff --git a/Makefile b/Makefile index c22748cc..a60e1aba 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,12 @@ test-stage2: $(TESTS:test/%=stage2/test/%) # Misc. +install: + test -d /usr/local/include/x86_64-linux-gnu/chibicc || \ + sudo mkdir -p /usr/local/include/x86_64-linux-gnu/chibicc + sudo cp include/* /usr/local/include/x86_64-linux-gnu/chibicc/ + sudo cp chibicc /usr/local/bin/chibicc + clean: rm -rf chibicc tmp* $(TESTS) test/*.s test/*.exe stage2 find * -type f '(' -name '*~' -o -name '*.o' ')' -exec rm {} ';' diff --git a/chibicc.h b/chibicc.h index f73eeec0..1713af4f 100644 --- a/chibicc.h +++ b/chibicc.h @@ -18,6 +18,10 @@ #include #include +#ifndef VERSION +#define VERSION "0.1" +#endif + #define MAX(x, y) ((x) < (y) ? (y) : (x)) #define MIN(x, y) ((x) < (y) ? (x) : (y)) @@ -61,7 +65,7 @@ typedef enum { typedef struct { char *name; - int file_no; + unsigned file_no; char *contents; // For #line directive @@ -83,7 +87,7 @@ struct Token { File *file; // Source location char *filename; // Filename - int line_no; // Line number + unsigned line_no; // Line number int line_delta; // Line number bool at_bol; // True if this token is at beginning of line bool has_space; // True if this token follows a space character @@ -100,13 +104,13 @@ Token *skip(Token *tok, char *op); bool consume(Token **rest, Token *tok, char *str); void convert_pp_tokens(Token *tok); File **get_input_files(void); -File *new_file(char *name, int file_no, char *contents); +File *new_file(char *name, unsigned file_no, char *contents); Token *tokenize_string_literal(Token *tok, Type *basety); Token *tokenize(File *file); Token *tokenize_file(char *filename); #define unreachable() \ - error("internal error at %s:%d", __FILE__, __LINE__) + error("internal error at %s:%u", __FILE__, __LINE__) // // preprocess.c diff --git a/codegen.c b/codegen.c index da11fd72..d7226685 100644 --- a/codegen.c +++ b/codegen.c @@ -690,7 +690,7 @@ static void builtin_alloca(void) { // Generate code for a given node. static void gen_expr(Node *node) { - println(" .loc %d %d", node->tok->file->file_no, node->tok->line_no); + println(" .loc %u %u", node->tok->file->file_no, node->tok->line_no); switch (node->kind) { case ND_NULL_EXPR: @@ -1186,7 +1186,7 @@ static void gen_expr(Node *node) { } static void gen_stmt(Node *node) { - println(" .loc %d %d", node->tok->file->file_no, node->tok->line_no); + println(" .loc %u %u", node->tok->file->file_no, node->tok->line_no); switch (node->kind) { case ND_IF: { diff --git a/main.c b/main.c index ffaabf41..a1017be6 100644 --- a/main.c +++ b/main.c @@ -39,9 +39,15 @@ static void usage(int status) { exit(status); } +static void version() { + fprintf(stderr, "chibicc %s\n", VERSION); + exit(0); +} + static bool take_arg(char *arg) { char *x[] = { "-o", "-I", "-idirafter", "-include", "-x", "-MF", "-MT", "-Xlinker", + "-soname" }; for (int i = 0; i < sizeof(x) / sizeof(*x); i++) @@ -57,6 +63,7 @@ static void add_default_include_paths(char *argv0) { // Add standard include paths. strarray_push(&include_paths, "/usr/local/include"); + strarray_push(&include_paths, "/usr/local/include/x86_64-linux-gnu/chibicc"); strarray_push(&include_paths, "/usr/include/x86_64-linux-gnu"); strarray_push(&include_paths, "/usr/include"); @@ -135,6 +142,9 @@ static void parse_args(int argc, char **argv) { if (!strcmp(argv[i], "--help")) usage(0); + if (!strcmp(argv[i], "--version")) + version(); + if (!strcmp(argv[i], "-o")) { opt_o = argv[++i]; continue; @@ -145,6 +155,12 @@ static void parse_args(int argc, char **argv) { continue; } + if (!strcmp(argv[i], "-soname")) { + strarray_push(&ld_extra_args, argv[i]); + strarray_push(&ld_extra_args, argv[++i]); + continue; + } + if (!strcmp(argv[i], "-S")) { opt_S = true; continue; @@ -691,7 +707,8 @@ static FileType get_file_type(char *filename) { return FILE_OBJ; if (endswith(filename, ".c")) return FILE_C; - if (endswith(filename, ".s")) + if (endswith(filename, ".s") || endswith(filename, ".S") || + endswith(filename, ".asm")) return FILE_ASM; error(": unknown file extension: %s", filename); @@ -747,7 +764,7 @@ int main(int argc, char **argv) { continue; } - // Handle .s + // Handle .s, -S, .asm if (type == FILE_ASM) { if (!opt_S) assemble(input, output); diff --git a/test/driver.sh b/test/driver.sh index c9a7b837..362cb5ec 100755 --- a/test/driver.sh +++ b/test/driver.sh @@ -18,7 +18,12 @@ check() { rm -f $tmp/out ./chibicc -c -o $tmp/out $tmp/empty.c [ -f $tmp/out ] -check -o +check -o out + +rm -f $tmp/out +./chibicc -c -o$tmp/out $tmp/empty.c +[ -f $tmp/out ] +check -oout # --help $chibicc --help 2>&1 | grep -q chibicc @@ -309,4 +314,9 @@ echo 'int main() {}' | $chibicc -c -o $tmp/baz.o -xc - cc -Xlinker -z -Xlinker muldefs -Xlinker --gc-sections -o $tmp/foo $tmp/foo.o $tmp/bar.o $tmp/baz.o check -Xlinker +# -soname +echo 'int main() { return 0; }' | $chibicc -c -o $tmp/foo.o -xc - +$chibicc -shared -soname libfoo.so.0 -o $tmp/libfoo.so $tmp/foo.o +check -soname + echo OK diff --git a/tokenize.c b/tokenize.c index 5c49c024..56392074 100644 --- a/tokenize.c +++ b/tokenize.c @@ -25,7 +25,7 @@ void error(char *fmt, ...) { // // foo.c:10: x = y + 1; // ^ -static void verror_at(char *filename, char *input, int line_no, +static void verror_at(char *filename, char *input, unsigned line_no, char *loc, char *fmt, va_list ap) { // Find a line containing `loc`. char *line = loc; @@ -37,7 +37,7 @@ static void verror_at(char *filename, char *input, int line_no, end++; // Print out the line. - int indent = fprintf(stderr, "%s:%d: ", filename, line_no); + int indent = fprintf(stderr, "%s:%u: ", filename, line_no); fprintf(stderr, "%.*s\n", (int)(end - line), line); // Show the error message. @@ -50,7 +50,7 @@ static void verror_at(char *filename, char *input, int line_no, } void error_at(char *loc, char *fmt, ...) { - int line_no = 1; + unsigned line_no = 1; for (char *p = current_file->contents; p < loc; p++) if (*p == '\n') line_no++; @@ -678,7 +678,7 @@ File **get_input_files(void) { return input_files; } -File *new_file(char *name, int file_no, char *contents) { +File *new_file(char *name, unsigned file_no, char *contents) { File *file = calloc(1, sizeof(File)); file->name = name; file->display_name = name; @@ -792,7 +792,7 @@ Token *tokenize_file(char *path) { convert_universal_chars(p); // Save the filename for assembler .file directive. - static int file_no; + static unsigned file_no; File *file = new_file(path, file_no + 1, p); // Save the filename for assembler .file directive.