diff options
| author | hachem <im@hachem.wtf> | 2026-09-08 00:52:52 +0200 |
|---|---|---|
| committer | hachem <im@hachem.wtf> | 2026-09-08 00:52:52 +0200 |
| commit | 051fe9e5ac7369827639fc4b59fd20228b053efa (patch) | |
| tree | 5c99ad5608d58e9441c0dad1799a7fcd21049e4f | |
| parent | 11863e3b26124f96595e416952f4d676ccbe62fe (diff) | |
refactor: cleanup Makefile
| -rw-r--r-- | Makefile | 4 | ||||
| -rw-r--r-- | mkproj.c | 254 |
2 files changed, 136 insertions, 122 deletions
@@ -35,8 +35,8 @@ $(TARGET): $(SRC) check: bear -- make clean all cppcheck --enable=warning,style,performance,portability \ - --project=compile_commands.json \ - --error-exitcode=1 + --project=compile_commands.json \ + --error-exitcode=1 clean: rm -f $(TARGET) @@ -41,37 +41,37 @@ enum Build_System struct Language_Info { - const char *key; - const char *name; - const char *compiler; - const char *extension; - const char *const *standards; + const char* key; + const char* name; + const char* compiler; + const char* extension; + const char* const* standards; size_t standard_count; - const char *default_standard; + const char* default_standard; }; struct Build_Info { - const char *key; - const char *name; - const char *default_bin; - const char *default_bin_int; + const char* key; + const char* name; + const char* default_bin; + const char* default_bin_int; }; struct Config { - const char *name; + const char* name; enum Language language; - const char *standard; + const char* standard; enum Build_System build; - const char *bin_dir; - const char *bin_int_dir; + const char* bin_dir; + const char* bin_int_dir; int use_git; int use_intermediate; int use_clangd_ignore; }; -static const char *const c_standards[] = +static const char* const c_standards[] = { "c89", "c99", @@ -81,7 +81,7 @@ static const char *const c_standards[] = "c2y" }; -static const char *const cpp_standards[] = +static const char* const cpp_standards[] = { "c++98", "c++03", @@ -156,7 +156,7 @@ static void print_version(void) (void) printf("%s %s\n", mkproj_program, mkproj_version); } -static void print_usage(FILE *stream) +static void print_usage(FILE* stream) { (void) fprintf( stream, @@ -186,7 +186,7 @@ static void print_usage(FILE *stream) mkproj_program, mkproj_program); } -static int find_language(const char *key, enum Language *out) +static int find_language(const char* key, enum Language* out) { for (enum Language language = 0; language < language_count; language++) if (strcmp(languages[language].key, key) == 0) @@ -198,7 +198,7 @@ static int find_language(const char *key, enum Language *out) return 0; } -static int find_build_system(const char *key, enum Build_System *out) +static int find_build_system(const char* key, enum Build_System* out) { for (enum Build_System build = 0; build < build_system_count; build++) if (strcmp(build_systems[build].key, key) == 0) @@ -210,9 +210,9 @@ static int find_build_system(const char *key, enum Build_System *out) return 0; } -static int valid_standard(enum Language language, const char *standard) +static int valid_standard(enum Language language, const char* standard) { - const struct Language_Info *info = &languages[language]; + const struct Language_Info* info = &languages[language]; for (size_t i = 0; i < info->standard_count; i++) if (strcmp(info->standards[i], standard) == 0) @@ -221,11 +221,10 @@ static int valid_standard(enum Language language, const char *standard) return 0; } -static void error(const char *message, const char *detail) +static void error(const char* message, const char* detail) { if (detail != NULL) - (void) fprintf(stderr, "%s: error: %s: %s\n", - mkproj_program, message, detail); + (void) fprintf(stderr, "%s: error: %s: %s\n", mkproj_program, message, detail); else (void) fprintf(stderr, "%s: error: %s\n", mkproj_program, message); } @@ -235,18 +234,18 @@ static void error(const char *message, const char *detail) * program should exit successfully (help/version), or a positive value on a * usage error. */ -static int parse_args(int argc, char **argv, struct Config *config) +static int parse_args(int argc, char** argv, struct Config* config) { - const char *lang_arg = NULL; - const char *std_arg = NULL; - const char *build_arg = NULL; - const char *bin_arg = NULL; - const char *bin_int_arg = NULL; - const char *name = NULL; + const char* lang_arg = NULL; + const char* std_arg = NULL; + const char* build_arg = NULL; + const char* bin_arg = NULL; + const char* bin_int_arg = NULL; + const char* name = NULL; for (int i = 1; i < argc; i++) { - const char *arg = argv[i]; + const char* arg = argv[i]; if (strcmp(arg, "-h") == 0 || strcmp(arg, "--help") == 0) { @@ -393,23 +392,19 @@ static int parse_args(int argc, char **argv, struct Config *config) && config->build != build_make && config->build != build_premake) { - error("--intermediate/--bin-int only apply to make and premake", - build_systems[config->build].key); + error("--intermediate/--bin-int only apply to make and premake", build_systems[config->build].key); return 1; } - config->bin_dir = - bin_arg != NULL ? bin_arg : build_systems[config->build].default_bin; - config->bin_int_dir = - bin_int_arg != NULL ? bin_int_arg - : build_systems[config->build].default_bin_int; + config->bin_dir = bin_arg != NULL ? bin_arg : build_systems[config->build].default_bin; + config->bin_int_dir = bin_int_arg != NULL ? bin_int_arg : build_systems[config->build].default_bin_int; return 0; } /* run argv to completion. returns the exit code, 127 if it could not be * executed, or -1 on a fork/wait failure. */ -static int run(char *const argv[], int quiet) +static int run(char* const argv[], int quiet) { pid_t pid = fork(); @@ -445,14 +440,14 @@ static int run(char *const argv[], int quiet) return -1; } -static int git_init(const char *root) +static int git_init(const char* root) { - char *const argv[] = { "git", "-C", (char *) root, "init", NULL }; + char* const argv[] = { "git", "-C", (char*) root, "init", NULL }; return run(argv, 1); } -static const char *main_source(const struct Config *config) +static const char* main_source(const struct Config* config) { if (config->language == language_objc) return @@ -467,7 +462,7 @@ static const char *main_source(const struct Config *config) if (config->language == language_cpp) { - const char *std = config->standard; + const char* std = config->standard; if (strcmp(std, "c++23") == 0 || strcmp(std, "c++26") == 0) return @@ -505,29 +500,37 @@ static const char *main_source(const struct Config *config) "}\n"; } -static void write_main(FILE *out, const struct Config *config) +static void write_main(FILE* out, const struct Config* config) { (void) fputs(main_source(config), out); } /* fill flags with the shared warning + debug flags and return the count. * every generator reuses these so all four build systems compile alike. */ -static size_t base_flags(const struct Config *config, const char *flags[]) +static size_t base_warnings(const struct Config* config, const char* flags[]) { size_t count = 0; flags[count++] = "-Wall"; flags[count++] = "-Wextra"; + flags[count++] = "-Wshadow"; flags[count++] = "-Wpedantic"; flags[count++] = "-Wconversion"; - flags[count++] = "-Wsign-conversion"; - flags[count++] = "-Wshadow"; if (config->language != language_cpp) - { flags[count++] = "-Wstrict-prototypes"; + + flags[count++] = "-Wsign-conversion"; + + if (config->language != language_cpp) flags[count++] = "-Wmissing-prototypes"; - } + + return count; +} + +static size_t base_flags(const struct Config* config, const char* flags[]) +{ + size_t count = base_warnings(config, flags); flags[count++] = "-g"; flags[count++] = "-fno-omit-frame-pointer"; @@ -535,7 +538,7 @@ static size_t base_flags(const struct Config *config, const char *flags[]) return count; } -static const char *cmake_language(enum Language language) +static const char* cmake_language(enum Language language) { if (language == language_cpp) return "CXX"; @@ -546,37 +549,53 @@ static const char *cmake_language(enum Language language) return "C"; } -static void write_makefile(FILE *out, const struct Config *config) +static void write_makefile(FILE* out, const struct Config* config) { - const struct Language_Info *lang = &languages[config->language]; - const char *ext = lang->extension; - const char *obj_dir = - config->use_intermediate ? config->bin_int_dir : config->bin_dir; + const struct Language_Info* lang = &languages[config->language]; + const char* ext = lang->extension; + const char* obj_dir = config->use_intermediate ? config->bin_int_dir : config->bin_dir; char clean[2 * PATH_MAX + 16]; if (config->use_intermediate) - (void) snprintf(clean, sizeof clean, "rm -rf %s %s", - config->bin_dir, config->bin_int_dir); + (void) snprintf(clean, sizeof clean, "rm -rf %s %s", config->bin_dir, config->bin_int_dir); else (void) snprintf(clean, sizeof clean, "rm -rf %s", config->bin_dir); - const char *flags[10]; - size_t count = base_flags(config, flags); + const char* flags[16]; + size_t count = 0; - (void) fprintf(out, "CC := %s\n\nSANITIZE ?= 1\n\nCFLAGS := ", lang->compiler); + flags[count++] = "-std=$(STD)"; + count += base_warnings(config, flags + count); + flags[count++] = "-Isrc"; + + int width = 0; for (size_t i = 0; i < count; i++) - (void) fprintf(out, "%s \\\n ", flags[i]); + if ((int) strlen(flags[i]) > width) + width = (int) strlen(flags[i]); - (void) fprintf(out, "-std=%s \\\n -Isrc\n", config->standard); + (void) fprintf(out, "CC := %s\nSTD := %s\n\nSANITIZE ?= 1\n\nCFLAGS := ", lang->compiler, config->standard); + + for (size_t i = 0; i < count; i++) + { + if (i > 0) + (void) fprintf(out, " "); + + if (i < count - 1) + (void) fprintf(out, "%-*s \\\n", width, flags[i]); + else + (void) fprintf(out, "%s\n", flags[i]); + } (void) fprintf( out, "\n" "ifeq ($(SANITIZE),1)\n" - "CFLAGS += -fsanitize=address,undefined\n" + "CFLAGS += -g -fno-omit-frame-pointer -fsanitize=address,undefined\n" "LDFLAGS += -fsanitize=address,undefined\n" + "else\n" + "CFLAGS += -O2\n" "endif\n" "\n" "TARGET := %s/%s\n" @@ -586,33 +605,33 @@ static void write_makefile(FILE *out, const struct Config *config) "all: $(TARGET)\n" "\n" "$(TARGET): $(OBJ)\n" - "\t@mkdir -p $(@D)\n" - "\t$(CC) $^ -o $@ $(LDFLAGS)\n" + "\t@mkdir -p $(@D)\n" + "\t$(CC) $^ -o $@ $(LDFLAGS)\n" "\n" "%s/%%.%s.o: src/%%.%s\n" - "\t@mkdir -p $(@D)\n" - "\t$(CC) $(CFLAGS) -c $< -o $@\n" + "\t@mkdir -p $(@D)\n" + "\t$(CC) $(CFLAGS) -c $< -o $@\n" "\n" "check:\n" - "\tbear -- make clean all\n" - "\tcppcheck \\\n" - "\t\t--project=compile_commands.json \\\n" - "\t\t--enable=warning,style,performance,portability \\\n" - "\t\t--error-exitcode=1\n" + "\tbear -- make clean all\n" + "\tcppcheck --enable=warning,style,performance,portability \\\n" + "\t\t --project=compile_commands.json \\\n" + "\t\t --error-exitcode=1\n" "\n" "clean:\n" - "\t%s\n" + "\t%s\n" "\n" ".PHONY: all check clean\n", + config->bin_dir, config->name, ext, obj_dir, obj_dir, ext, ext, clean); } -static void write_cmake(FILE *out, const struct Config *config) +static void write_cmake(FILE* out, const struct Config* config) { - const char *name = config->name; - const char *ext = languages[config->language].extension; - const char *flags[10]; + const char* name = config->name; + const char* ext = languages[config->language].extension; + const char* flags[10]; size_t count = base_flags(config, flags); (void) fprintf( @@ -655,7 +674,7 @@ static void write_cmake(FILE *out, const struct Config *config) name, name); } -static const char *meson_language(enum Language language) +static const char* meson_language(enum Language language) { if (language == language_cpp) return "cpp"; @@ -666,12 +685,12 @@ static const char *meson_language(enum Language language) return "c"; } -static void write_meson(FILE *out, const struct Config *config) +static void write_meson(FILE* out, const struct Config* config) { - const char *name = config->name; - const char *ext = languages[config->language].extension; - const char *lang = meson_language(config->language); - const char *flags[10]; + const char* name = config->name; + const char* ext = languages[config->language].extension; + const char* lang = meson_language(config->language); + const char* flags[10]; size_t count = base_flags(config, flags); (void) fprintf( @@ -718,7 +737,7 @@ static void write_meson(FILE *out, const struct Config *config) name); } -static const char *premake_language(enum Language language) +static const char* premake_language(enum Language language) { if (language == language_cpp) return "C++"; @@ -726,13 +745,12 @@ static const char *premake_language(enum Language language) return "C"; } -static void write_premake(FILE *out, const struct Config *config) +static void write_premake(FILE* out, const struct Config* config) { - const char *name = config->name; - const char *ext = languages[config->language].extension; - const char *obj_dir = - config->use_intermediate ? config->bin_int_dir : config->bin_dir; - const char *flags[10]; + const char* name = config->name; + const char* ext = languages[config->language].extension; + const char* obj_dir = config->use_intermediate ? config->bin_int_dir : config->bin_dir; + const char* flags[10]; size_t count = base_flags(config, flags); (void) fprintf( @@ -775,32 +793,31 @@ static void write_premake(FILE *out, const struct Config *config) out); } -static void write_gitignore(FILE *out, const struct Config *config) +static void write_gitignore(FILE* out, const struct Config* config) { (void) fprintf(out, "%s/\n", config->bin_dir); - if (config->use_intermediate - && (config->build == build_make || config->build == build_premake) - && strcmp(config->bin_int_dir, config->bin_dir) != 0) + if (config->use_intermediate && + (config->build == build_make || + config->build == build_premake) && + strcmp(config->bin_int_dir, config->bin_dir) != 0) (void) fprintf(out, "%s/\n", config->bin_int_dir); if (config->build == build_premake) (void) fputs("Makefile\n*.make\n", out); if (config->use_clangd_ignore) - (void) fputs( - "\n" - ".clangd\n" - "compile_flags.txt\n" - "compile_commands.json\n", - out); + (void) fputs("\n" + ".clangd\n" + "compile_flags.txt\n" + "compile_commands.json\n", + out); } /* open path, hand the stream to writer, close. returns 0 on success. */ -static int emit(const char *path, const struct Config *config, - void (*writer)(FILE *, const struct Config *)) +static int emit(const char* path, const struct Config* config, void (*writer)(FILE*, const struct Config*)) { - FILE *file = fopen(path, "w"); + FILE* file = fopen(path, "w"); if (file == NULL) { @@ -819,7 +836,7 @@ static int emit(const char *path, const struct Config *config, return 0; } -static int make_dir(const char *path) +static int make_dir(const char* path) { if (mkdir(path, 0755) == 0) return 0; @@ -832,12 +849,12 @@ static int make_dir(const char *path) return -1; } -static void print_next_steps(const struct Config *config) +static void print_next_steps(const struct Config* config) { - (void) printf("\ncreated %s (%s, %s, %s)\n\n", - config->name, - languages[config->language].name, - config->standard, + (void) printf("\ncreated %s (%s, %s, %s)\n\n", + config->name, + languages[config->language].name, + config->standard, build_systems[config->build].name); (void) printf(" cd %s\n", config->name); @@ -871,15 +888,15 @@ static void print_next_steps(const struct Config *config) (void) printf("\n"); } -static int generate_project(const struct Config *config) +static int generate_project(const struct Config* config) { char path[PATH_MAX]; - const char *build_file; - void (*write_build)(FILE *, const struct Config *); + const char* build_file; + void (*write_build)(FILE*, const struct Config*); switch (config->build) { - case build_make: build_file = "Makefile"; write_build = write_makefile; break; + case build_make: build_file = "Makefile"; write_build = write_makefile; break; case build_cmake: build_file = "CMakeLists.txt"; write_build = write_cmake; break; case build_meson: build_file = "meson.build"; write_build = write_meson; break; case build_premake: build_file = "premake5.lua"; write_build = write_premake; break; @@ -911,15 +928,12 @@ static int generate_project(const struct Config *config) return -1; if (config->use_git && git_init(config->name) != 0) - (void) fprintf(stderr, "%s: warning: git is not installed\n", - mkproj_program); + (void) fprintf(stderr, "%s: warning: git is not installed\n", mkproj_program); print_next_steps(config); { - char *const argv[] = - { "tree", "-a", "--dirsfirst", "-I", ".git", - (char *) config->name, NULL }; + char* const argv[] = { "tree", "-a", "--dirsfirst", "-I", ".git", (char*) config->name, NULL }; if (run(argv, 0) == 127) (void) puts(" (tree is not installed)"); @@ -928,7 +942,7 @@ static int generate_project(const struct Config *config) return 0; } -int main(int argc, char **argv) +int main(int argc, char** argv) { struct Config config = { |
