hachem.wtf
aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhachem <im@hachem.wtf>2026-09-08 00:52:52 +0200
committerhachem <im@hachem.wtf>2026-09-08 00:52:52 +0200
commit051fe9e5ac7369827639fc4b59fd20228b053efa (patch)
tree5c99ad5608d58e9441c0dad1799a7fcd21049e4f
parent11863e3b26124f96595e416952f4d676ccbe62fe (diff)
refactor: cleanup Makefile
-rw-r--r--Makefile4
-rw-r--r--mkproj.c254
2 files changed, 136 insertions, 122 deletions
diff --git a/Makefile b/Makefile
index 4ccb778..eca30ff 100644
--- a/Makefile
+++ b/Makefile
@@ -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)
diff --git a/mkproj.c b/mkproj.c
index 791a626..5a5f45d 100644
--- a/mkproj.c
+++ b/mkproj.c
@@ -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 =
{