Set Makefile variables for compile flags of binaries
This allows to remove the finish_* functions and makes manual
adjustments to the generated Makefile easier.
diff --git a/src/Charmonizer/Core/Make.c b/src/Charmonizer/Core/Make.c
index 2bd286c..255c711 100644
--- a/src/Charmonizer/Core/Make.c
+++ b/src/Charmonizer/Core/Make.c
@@ -40,22 +40,22 @@
};
struct chaz_MakeBinary {
- int type;
- char *target_dir;
- char *basename;
- char *version;
- char *major_version;
+ chaz_MakeRule *rule; /* Owned by MakeBinary. */
+
+ chaz_MakeVar *obj_var;
+ char *obj_dollar_var;
char **sources; /* List of all sources. */
size_t num_sources;
char **single_sources; /* Only sources from add_src_file. */
size_t num_single_sources;
char **dirs;
size_t num_dirs;
- chaz_MakeVar *obj_var; /* Owned by MakeFile. */
- char *dollar_var;
- chaz_MakeRule *rule; /* Not added to MakeFile, owned by MakeBinary. */
- chaz_CFlags *compile_flags;
- chaz_CFlags *link_flags;
+
+ chaz_MakeVar *cflags_var;
+ chaz_CFlags *cflags;
+
+ chaz_MakeVar *ldflags_var;
+ chaz_CFlags *ldflags;
};
struct chaz_MakeFile {
@@ -102,24 +102,12 @@
static int
S_chaz_Make_audition(const char *make);
-static void
-S_chaz_MakeFile_finish_exe(chaz_MakeFile *self, chaz_MakeBinary *binary);
-
-static void
-S_chaz_MakeFile_finish_shared_lib(chaz_MakeFile *self,
- chaz_MakeBinary *binary);
-
-static void
-S_chaz_MakeFile_finish_static_lib(chaz_MakeFile *self,
- chaz_MakeBinary *binary);
-
static chaz_MakeBinary*
-S_chaz_MakeFile_add_binary(chaz_MakeFile *self, int type, const char *dir,
- const char *basename, const char *target);
+S_chaz_MakeFile_add_binary(chaz_MakeFile *self, int type, const char *basename,
+ const char *target);
static void
-S_chaz_MakeFile_write_binary_rules(chaz_MakeFile *self,
- chaz_MakeBinary *binary, FILE *out);
+S_chaz_MakeFile_write_binary_rules(chaz_MakeBinary *binary, FILE *out);
static void
S_chaz_MakeFile_write_object_rules(char **sources, const char *command,
@@ -374,7 +362,9 @@
const char *basename) {
const char *exe_ext = chaz_CC_exe_ext();
char *target;
+ char *command;
chaz_MakeBinary *binary;
+ chaz_CFlags *ldflags;
if (dir == NULL || strcmp(dir, ".") == 0) {
target = chaz_Util_join("", basename, exe_ext, NULL);
@@ -384,179 +374,149 @@
target = chaz_Util_join("", dir, dir_sep, basename, exe_ext, NULL);
}
- binary = S_chaz_MakeFile_add_binary(self, CHAZ_MAKEBINARY_EXE, dir,
- basename, target);
+ binary = S_chaz_MakeFile_add_binary(self, CHAZ_MAKEBINARY_EXE, basename,
+ target);
+ ldflags = chaz_CC_new_cflags();
+ if (chaz_CC_is_msvc()) {
+ chaz_CFlags_append(ldflags, "/nologo");
+ }
+ chaz_CFlags_set_link_output(ldflags, "$@");
+
+ /* Objects must come before flags since flags may contain libraries. */
+ command = chaz_Util_join("", "$(LINK) ", chaz_CFlags_get_string(ldflags),
+ " ", binary->obj_dollar_var,
+ " $(", binary->ldflags_var->name, ") ", NULL);
+ chaz_MakeRule_add_command(binary->rule, command);
+
+ chaz_CFlags_destroy(ldflags);
+ free(command);
free(target);
return binary;
}
-void
-S_chaz_MakeFile_finish_exe(chaz_MakeFile *self, chaz_MakeBinary *binary) {
- const char *link_flags_string;
- char *command;
-
- (void)self;
-
- /* This is destructive but shouldn't be a problem since a Makefile
- * is only written once.
- */
- chaz_CFlags_set_link_output(binary->link_flags, "$@");
- link_flags_string = chaz_CFlags_get_string(binary->link_flags);
-
- /* Objects in dollar var must come before flags since flags may
- * contain libraries.
- */
- command = chaz_Util_join(" ", "$(LINK)", binary->dollar_var,
- link_flags_string, NULL);
- chaz_MakeRule_add_command(binary->rule, command);
- free(command);
-}
-
chaz_MakeBinary*
chaz_MakeFile_add_shared_lib(chaz_MakeFile *self, const char *dir,
const char *basename, const char *version,
const char *major_version) {
- int binary_format = chaz_CC_binary_format();
- char *target;
+ int binfmt = chaz_CC_binary_format();
+ char *path, *vpath, *mpath;
+ char *command;
chaz_MakeBinary *binary;
+ chaz_CFlags *ldflags;
- if (binary_format == CHAZ_CC_BINFMT_PE) {
- target = chaz_CC_shared_lib_filename(dir, basename, major_version);
+ path = chaz_CC_shared_lib_filename(dir, basename, NULL);
+ if (binfmt == CHAZ_CC_BINFMT_PE) {
+ vpath = chaz_CC_shared_lib_filename(dir, basename, major_version);
+ mpath = NULL;
}
else {
- target = chaz_CC_shared_lib_filename(dir, basename, version);
+ vpath = chaz_CC_shared_lib_filename(dir, basename, version);
+ mpath = chaz_CC_shared_lib_filename(dir, basename, major_version);
}
- binary = S_chaz_MakeFile_add_binary(self, CHAZ_MAKEBINARY_SHARED_LIB, dir,
- basename, target);
- binary->version = chaz_Util_strdup(version);
- binary->major_version = chaz_Util_strdup(major_version);
+ binary = S_chaz_MakeFile_add_binary(self, CHAZ_MAKEBINARY_SHARED_LIB,
+ basename, vpath);
- chaz_CFlags_compile_shared_library(binary->compile_flags);
- chaz_CFlags_link_shared_library(binary->link_flags, basename, version,
- major_version);
+ chaz_CFlags_compile_shared_library(binary->cflags);
- free(target);
- return binary;
-}
-
-void
-S_chaz_MakeFile_finish_shared_lib(chaz_MakeFile *self,
- chaz_MakeBinary *binary) {
- const char *link_flags_string;
- int binfmt = chaz_CC_binary_format();
- char *no_v_name
- = chaz_CC_shared_lib_filename(binary->target_dir, binary->basename,
- NULL);
- char *major_v_name
- = chaz_CC_shared_lib_filename(binary->target_dir, binary->basename,
- binary->major_version);
- char *command;
-
+ ldflags = chaz_CC_new_cflags();
+ if (chaz_CC_is_msvc()) {
+ chaz_CFlags_append(ldflags, "/nologo");
+ }
+ chaz_CFlags_set_link_output(ldflags, "$@");
+ chaz_CFlags_link_shared_library(ldflags, basename, version, major_version);
if (binfmt == CHAZ_CC_BINFMT_MACHO) {
- const char *dir_sep = chaz_OS_dir_sep();
- char *install_name;
-
/* Set temporary install name with full path on Darwin. */
- install_name = chaz_Util_join("", "-install_name $(CURDIR)", dir_sep,
- major_v_name, NULL);
- chaz_CFlags_append(binary->link_flags, install_name);
+ char *install_name = chaz_Util_join("", "-install_name \"$(CURDIR)/",
+ mpath, "\"", NULL);
+ chaz_CFlags_append(ldflags, install_name);
free(install_name);
}
- chaz_CFlags_set_link_output(binary->link_flags, "$@");
- link_flags_string = chaz_CFlags_get_string(binary->link_flags);
-
- command = chaz_Util_join(" ", "$(LINK)", binary->dollar_var,
- link_flags_string, NULL);
+ command = chaz_Util_join("", "$(LINK) ", chaz_CFlags_get_string(ldflags),
+ " ", binary->obj_dollar_var,
+ " $(", binary->ldflags_var->name, ")", NULL);
chaz_MakeRule_add_command(binary->rule, command);
free(command);
/* Add symlinks. */
if (binfmt == CHAZ_CC_BINFMT_ELF || binfmt == CHAZ_CC_BINFMT_MACHO) {
- command = chaz_Util_join(" ", "ln -sf", binary->rule->targets,
- major_v_name, NULL);
+ char *vname = chaz_CC_shared_lib_filename(NULL, basename, version);
+ char *mname = chaz_CC_shared_lib_filename(NULL, basename,
+ major_version);
+
+ command = chaz_Util_join(" ", "ln -sf", vname, mpath, NULL);
chaz_MakeRule_add_command(binary->rule, command);
free(command);
if (binfmt == CHAZ_CC_BINFMT_MACHO) {
- command = chaz_Util_join(" ", "ln -sf", binary->rule->targets,
- no_v_name, NULL);
+ command = chaz_Util_join(" ", "ln -sf", vname, path, NULL);
}
else {
- command = chaz_Util_join(" ", "ln -sf", major_v_name, no_v_name,
- NULL);
+ command = chaz_Util_join(" ", "ln -sf", mname, path, NULL);
}
chaz_MakeRule_add_command(binary->rule, command);
free(command);
- chaz_MakeRule_add_rm_command(self->clean, major_v_name);
- chaz_MakeRule_add_rm_command(self->clean, no_v_name);
+ chaz_MakeRule_add_rm_command(self->clean, mpath);
+ chaz_MakeRule_add_rm_command(self->clean, path);
+
+ free(mname);
+ free(vname);
}
if (binfmt == CHAZ_CC_BINFMT_PE) {
/* Remove import library. */
- char *filename
- = chaz_CC_import_lib_filename(binary->target_dir, binary->basename,
- binary->major_version);
+ char *filename = chaz_CC_import_lib_filename(dir, basename,
+ major_version);
chaz_MakeRule_add_rm_command(self->clean, filename);
free(filename);
}
if (chaz_CC_is_msvc()) {
/* Remove export file. */
- char *filename
- = chaz_CC_export_filename(binary->target_dir, binary->basename,
- binary->major_version);
+ char *filename = chaz_CC_export_filename(dir, basename, major_version);
chaz_MakeRule_add_rm_command(self->clean, filename);
free(filename);
}
- free(major_v_name);
- free(no_v_name);
+ chaz_CFlags_destroy(ldflags);
+ free(mpath);
+ free(vpath);
+ free(path);
+ return binary;
}
chaz_MakeBinary*
chaz_MakeFile_add_static_lib(chaz_MakeFile *self, const char *dir,
const char *basename) {
char *target = chaz_CC_static_lib_filename(dir, basename);
+ char *command;
chaz_MakeBinary *binary
- = S_chaz_MakeFile_add_binary(self, CHAZ_MAKEBINARY_STATIC_LIB, dir,
+ = S_chaz_MakeFile_add_binary(self, CHAZ_MAKEBINARY_STATIC_LIB,
basename, target);
+ command = chaz_CC_format_archiver_command("$@", binary->obj_dollar_var);
+ chaz_MakeRule_add_command(binary->rule, command);
+
+ free(command);
free(target);
return binary;
}
-static void
-S_chaz_MakeFile_finish_static_lib(chaz_MakeFile *self,
- chaz_MakeBinary *binary) {
- char *command;
-
- (void)self;
-
- command = chaz_CC_format_archiver_command("$@", binary->dollar_var);
- chaz_MakeRule_add_command(binary->rule, command);
- free(command);
-
- command = chaz_CC_format_ranlib_command("$@");
- if (command) {
- chaz_MakeRule_add_command(binary->rule, command);
- free(command);
- }
-}
-
static chaz_MakeBinary*
-S_chaz_MakeFile_add_binary(chaz_MakeFile *self, int type, const char *dir,
- const char *basename, const char *target) {
+S_chaz_MakeFile_add_binary(chaz_MakeFile *self, int type, const char *basename,
+ const char *target) {
chaz_MakeBinary *binary
= (chaz_MakeBinary*)calloc(1, sizeof(chaz_MakeBinary));
const char *suffix;
- char *uc_basename = chaz_Util_strdup(basename);
+ char *uc_base = chaz_Util_strdup(basename);
char *binary_var_name;
char *obj_var_name;
- char *dollar_var;
+ char *cflags_var_name;
+ char *ldflags_var_name;
+ char *obj_dollar_var;
size_t i;
size_t num_binaries;
size_t alloc_size;
@@ -571,27 +531,32 @@
return NULL;
}
- for (i = 0; uc_basename[i] != '\0'; i++) {
- uc_basename[i] = toupper((unsigned char)uc_basename[i]);
+ for (i = 0; uc_base[i] != '\0'; i++) {
+ uc_base[i] = toupper((unsigned char)uc_base[i]);
}
- binary_var_name = chaz_Util_join("_", uc_basename, suffix, NULL);
- obj_var_name = chaz_Util_join("_", uc_basename, suffix, "OBJS", NULL);
- dollar_var = chaz_Util_join("", "$(", obj_var_name, ")", NULL);
+ binary_var_name = chaz_Util_join("_", uc_base, suffix, NULL);
+ obj_var_name = chaz_Util_join("_", uc_base, suffix, "OBJS", NULL);
+ cflags_var_name = chaz_Util_join("_", uc_base, suffix, "CFLAGS", NULL);
+ ldflags_var_name = chaz_Util_join("_", uc_base, suffix, "LDFLAGS", NULL);
+ obj_dollar_var = chaz_Util_join("", "$(", obj_var_name, ")", NULL);
chaz_MakeFile_add_var(self, binary_var_name, target);
- binary->type = type;
- binary->target_dir = dir ? chaz_Util_strdup(dir) : NULL;
- binary->basename = chaz_Util_strdup(basename);
+ binary->rule = S_chaz_MakeRule_new(target, obj_dollar_var);
binary->obj_var = chaz_MakeFile_add_var(self, obj_var_name, NULL);
- binary->dollar_var = dollar_var;
- binary->rule = S_chaz_MakeRule_new(target, dollar_var);
+ binary->obj_dollar_var = obj_dollar_var;
binary->sources = (char**)calloc(1, sizeof(char*));
binary->single_sources = (char**)calloc(1, sizeof(char*));
binary->dirs = (char**)calloc(1, sizeof(char*));
- binary->compile_flags = chaz_CC_new_cflags();
- binary->link_flags = chaz_CC_new_cflags();
+
+ binary->cflags_var = chaz_MakeFile_add_var(self, cflags_var_name, NULL);
+ binary->cflags = chaz_CC_new_cflags();
+ binary->ldflags_var = chaz_MakeFile_add_var(self, ldflags_var_name, NULL);
+ binary->ldflags = chaz_CC_new_cflags();
+
+ chaz_MakeRule_add_rm_command(self->clean, obj_dollar_var);
+ chaz_MakeRule_add_rm_command(self->clean, target);
num_binaries = self->num_binaries;
alloc_size = (num_binaries + 2) * sizeof(chaz_MakeBinary*);
@@ -601,9 +566,11 @@
self->binaries = binaries;
self->num_binaries = num_binaries + 1;
- free(uc_basename);
+ free(ldflags_var_name);
+ free(cflags_var_name);
free(obj_var_name);
free(binary_var_name);
+ free(uc_base);
return binary;
}
@@ -656,6 +623,17 @@
fprintf(out, "CC = %s\n", chaz_CC_get_cc());
fprintf(out, "LINK = %s\n", chaz_CC_link_command());
+ /* Finalize binary vars. */
+ for (i = 0; self->binaries[i]; i++) {
+ chaz_MakeBinary *binary = self->binaries[i];
+ const char *flags;
+
+ flags = chaz_CFlags_get_string(binary->cflags);
+ chaz_MakeVar_append(binary->cflags_var, flags);
+ flags = chaz_CFlags_get_string(binary->ldflags);
+ chaz_MakeVar_append(binary->ldflags_var, flags);
+ }
+
for (i = 0; self->vars[i]; i++) {
chaz_MakeVar *var = self->vars[i];
fprintf(out, "%s = %s\n", var->name, var->value);
@@ -667,7 +645,7 @@
}
for (i = 0; self->binaries[i]; i++) {
- S_chaz_MakeFile_write_binary_rules(self, self->binaries[i], out);
+ S_chaz_MakeFile_write_binary_rules(self->binaries[i], out);
}
S_chaz_MakeRule_write(self->clean, out);
@@ -687,39 +665,18 @@
}
static void
-S_chaz_MakeFile_write_binary_rules(chaz_MakeFile *self,
- chaz_MakeBinary *binary, FILE *out) {
- const char *cflags;
-
- if (chaz_CC_is_msvc()) {
- chaz_CFlags_append(binary->compile_flags, "/nologo");
- chaz_CFlags_append(binary->link_flags, "/nologo");
- }
-
- switch (binary->type) {
- case CHAZ_MAKEBINARY_EXE:
- S_chaz_MakeFile_finish_exe(self, binary);
- break;
- case CHAZ_MAKEBINARY_STATIC_LIB:
- S_chaz_MakeFile_finish_static_lib(self, binary);
- break;
- case CHAZ_MAKEBINARY_SHARED_LIB:
- S_chaz_MakeFile_finish_shared_lib(self, binary);
- break;
- default:
- chaz_Util_die("Invalid binary type: %d", binary->type);
- return;
- }
-
- chaz_MakeRule_add_rm_command(self->clean, binary->rule->targets);
- chaz_MakeRule_add_rm_command(self->clean, binary->dollar_var);
+S_chaz_MakeFile_write_binary_rules(chaz_MakeBinary *binary, FILE *out) {
+ const char *cflags_string;
S_chaz_MakeRule_write(binary->rule, out);
- cflags = chaz_CFlags_get_string(binary->compile_flags);
+ cflags_string = chaz_CFlags_get_string(binary->cflags);
/* Write rules to compile with custom flags. */
- if (cflags[0] != '\0') {
+ if (cflags_string[0] != '\0') {
+ char *dollar_var = chaz_Util_join("", "$(", binary->cflags_var->name,
+ ")", NULL);
+
if (!chaz_Make.supports_pattern_rules
|| chaz_Make.shell_type == CHAZ_OS_CMD_EXE) {
/* Write a rule for each object file. This is needed for make
@@ -727,21 +684,25 @@
* mingw32-make which has problems with pattern rules and
* backslash directory separators.
*/
- S_chaz_MakeFile_write_object_rules(binary->sources, cflags, out);
+ S_chaz_MakeFile_write_object_rules(binary->sources, dollar_var,
+ out);
}
else {
/* Write a pattern rule for each directory. */
- S_chaz_MakeFile_write_pattern_rules(binary->dirs, cflags, out);
+ S_chaz_MakeFile_write_pattern_rules(binary->dirs, dollar_var, out);
/* Write a rule for each object added with add_src_file. */
- S_chaz_MakeFile_write_object_rules(binary->single_sources, cflags,
- out);
+ S_chaz_MakeFile_write_object_rules(binary->single_sources,
+ dollar_var, out);
}
+
+ free(dollar_var);
}
}
static void
S_chaz_MakeFile_write_object_rules(char **sources, const char *cflags,
FILE *out) {
+ const char *cc = chaz_CC_is_msvc() ? "$(CC) /nologo" : "$(CC)";
chaz_CFlags *output_cflags = chaz_CC_new_cflags();
const char *output_cflags_string;
size_t i;
@@ -758,7 +719,7 @@
if (obj_path == NULL) { continue; }
rule = S_chaz_MakeRule_new(obj_path, source);
- command = chaz_Util_join(" ", "$(CC) $(CFLAGS)", cflags, source,
+ command = chaz_Util_join(" ", cc, "$(CFLAGS)", cflags, source,
output_cflags_string, NULL);
chaz_MakeRule_add_command(rule, command);
S_chaz_MakeRule_write(rule, out);
@@ -774,6 +735,7 @@
static void
S_chaz_MakeFile_write_pattern_rules(char **dirs, const char *cflags,
FILE *out) {
+ const char *cc = chaz_CC_is_msvc() ? "$(CC) /nologo" : "$(CC)";
const char *obj_ext = chaz_CC_obj_ext();
const char *dir_sep = chaz_OS_dir_sep();
chaz_CFlags *output_cflags = chaz_CC_new_cflags();
@@ -783,7 +745,7 @@
chaz_CFlags_set_output_obj(output_cflags, "$@");
output_cflags_string = chaz_CFlags_get_string(output_cflags);
- command = chaz_Util_join(" ", "$(CC) $(CFLAGS)", cflags, "$<",
+ command = chaz_Util_join(" ", cc, "$(CFLAGS)", cflags, "$<",
output_cflags_string, NULL);
for (i = 0; dirs[i]; i++) {
@@ -987,11 +949,7 @@
S_chaz_MakeBinary_destroy(chaz_MakeBinary *self) {
size_t i;
- free(self->target_dir);
- free(self->basename);
- free(self->version);
- free(self->major_version);
- free(self->dollar_var);
+ free(self->obj_dollar_var);
S_chaz_MakeRule_destroy(self->rule);
for (i = 0; i < self->num_sources; i++) {
@@ -1007,8 +965,8 @@
}
free(self->dirs);
- chaz_CFlags_destroy(self->compile_flags);
- chaz_CFlags_destroy(self->link_flags);
+ chaz_CFlags_destroy(self->cflags);
+ chaz_CFlags_destroy(self->ldflags);
free(self);
}
@@ -1158,12 +1116,12 @@
chaz_CFlags*
chaz_MakeBinary_get_compile_flags(chaz_MakeBinary *self) {
- return self->compile_flags;
+ return self->cflags;
}
chaz_CFlags*
chaz_MakeBinary_get_link_flags(chaz_MakeBinary *self) {
- return self->link_flags;
+ return self->ldflags;
}
void