Browse Source

Add `ODIN_BUILD_PROJECT_NAME` and `//+build-project-name`

This allows for condition inclusion of files, similar to `+build` or `ODIN_BUILD`, but relies on the directory name of the project to be the same as specified

Example:

    odin build foo/bar/baz

    ODIN_BUILD_PROJECT_NAME == "baz"

    //+build_project_name baz
gingerBill 2 years ago
parent
commit
81e3b64ecd
3 changed files with 58 additions and 1 deletions
  1. 7 0
      src/build_settings.cpp
  2. 1 0
      src/checker.cpp
  3. 50 1
      src/parser.cpp

+ 7 - 0
src/build_settings.cpp

@@ -225,6 +225,7 @@ struct BuildContext {
 	String ODIN_VENDOR;  // compiler vendor
 	String ODIN_VENDOR;  // compiler vendor
 	String ODIN_VERSION; // compiler version
 	String ODIN_VERSION; // compiler version
 	String ODIN_ROOT;    // Odin ROOT
 	String ODIN_ROOT;    // Odin ROOT
+	String ODIN_BUILD_PROJECT_NAME; // Odin main/initial package's directory name
 	bool   ODIN_DEBUG;   // Odin in debug mode
 	bool   ODIN_DEBUG;   // Odin in debug mode
 	bool   ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not
 	bool   ODIN_DISABLE_ASSERT; // Whether the default 'assert' et al is disabled in code or not
 	bool   ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing)
 	bool   ODIN_DEFAULT_TO_NIL_ALLOCATOR; // Whether the default allocator is a "nil" allocator or not (i.e. it does nothing)
@@ -1537,6 +1538,12 @@ bool init_build_paths(String init_filename) {
 		enable_target_feature({}, bc->target_features_string);
 		enable_target_feature({}, bc->target_features_string);
 	}
 	}
 
 
+	{
+		String build_project_name  = last_path_element(bc->build_paths[BuildPath_Main_Package].basename);
+		GB_ASSERT(build_project_name.len > 0);
+		bc->ODIN_BUILD_PROJECT_NAME = build_project_name;
+	}
+
 	return true;
 	return true;
 }
 }
 
 

+ 1 - 0
src/checker.cpp

@@ -938,6 +938,7 @@ void init_universal(void) {
 	add_global_string_constant("ODIN_VENDOR",  bc->ODIN_VENDOR);
 	add_global_string_constant("ODIN_VENDOR",  bc->ODIN_VENDOR);
 	add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION);
 	add_global_string_constant("ODIN_VERSION", bc->ODIN_VERSION);
 	add_global_string_constant("ODIN_ROOT",    bc->ODIN_ROOT);
 	add_global_string_constant("ODIN_ROOT",    bc->ODIN_ROOT);
+	add_global_string_constant("ODIN_BUILD_PROJECT_NAME", bc->ODIN_BUILD_PROJECT_NAME);
 
 
 	{
 	{
 		GlobalEnumValue values[TargetOs_COUNT] = {
 		GlobalEnumValue values[TargetOs_COUNT] = {

+ 50 - 1
src/parser.cpp

@@ -5506,6 +5506,51 @@ isize calc_decl_count(Ast *decl) {
 	return count;
 	return count;
 }
 }
 
 
+bool parse_build_project_directory_tag(Token token_for_pos, String s) {
+	String const prefix = str_lit("+build-project-name");
+	GB_ASSERT(string_starts_with(s, prefix));
+	s = string_trim_whitespace(substring(s, prefix.len, s.len));
+	if (s.len == 0) {
+		return true;
+	}
+
+	bool any_correct = false;
+
+	while (s.len > 0) {
+		bool this_kind_correct = true;
+
+		do {
+			String p = string_trim_whitespace(build_tag_get_token(s, &s));
+			if (p.len == 0) break;
+			if (p == ",") break;
+
+			bool is_notted = false;
+			if (p[0] == '!') {
+				is_notted = true;
+				p = substring(p, 1, p.len);
+				if (p.len == 0) {
+					syntax_error(token_for_pos, "Expected a build-project-name after '!'");
+					break;
+				}
+			}
+
+			if (p.len == 0) {
+				continue;
+			}
+
+			if (is_notted) {
+				this_kind_correct = this_kind_correct && (p != build_context.ODIN_BUILD_PROJECT_NAME);
+			} else {
+				this_kind_correct = this_kind_correct && (p == build_context.ODIN_BUILD_PROJECT_NAME);
+			}
+		} while (s.len > 0);
+
+		any_correct = any_correct || this_kind_correct;
+	}
+
+	return any_correct;
+}
+
 bool parse_file(Parser *p, AstFile *f) {
 bool parse_file(Parser *p, AstFile *f) {
 	if (f->tokens.count == 0) {
 	if (f->tokens.count == 0) {
 		return true;
 		return true;
@@ -5561,7 +5606,11 @@ bool parse_file(Parser *p, AstFile *f) {
 			if (string_starts_with(str, str_lit("//"))) {
 			if (string_starts_with(str, str_lit("//"))) {
 				String lc = string_trim_whitespace(substring(str, 2, str.len));
 				String lc = string_trim_whitespace(substring(str, 2, str.len));
 				if (lc.len > 0 && lc[0] == '+') {
 				if (lc.len > 0 && lc[0] == '+') {
-					if (string_starts_with(lc, str_lit("+build"))) {
+					 if (string_starts_with(lc, str_lit("+build-project-name"))) {
+						if (!parse_build_project_directory_tag(tok, lc)) {
+							return false;
+						}
+					} else if (string_starts_with(lc, str_lit("+build"))) {
 						if (!parse_build_tag(tok, lc)) {
 						if (!parse_build_tag(tok, lc)) {
 							return false;
 							return false;
 						}
 						}