From 794335cf16b3c522b09b10dc5fb02c9554084f8a Mon Sep 17 00:00:00 2001
From: Bent Bisballe Nyeng <deva@aasimon.org>
Date: Tue, 4 Feb 2025 19:04:18 +0100
Subject: Add support for custom flags through env: CFLAGS, CXXFLAGS and
 LDFLAGS

---
 src/bootstrap.cc | 17 +++++++++++++++++
 src/configure.cc | 35 +++++++++++++++++++++++++++++++++++
 src/ctor.h       |  2 ++
 src/task_cc.cc   | 26 ++++++++++++++++++++++++++
 src/task_ld.cc   |  9 +++++++--
 src/task_so.cc   |  5 +++++
 6 files changed, 92 insertions(+), 2 deletions(-)

(limited to 'src')

diff --git a/src/bootstrap.cc b/src/bootstrap.cc
index be1b5ed..836504e 100644
--- a/src/bootstrap.cc
+++ b/src/bootstrap.cc
@@ -82,6 +82,23 @@ std::string ctor::configuration::get(const std::string& key, const std::string&
 	return default_value;
 }
 
+std::string ctor::configuration::getenv(const std::string& key) const
+{
+	auto envit = env.find(key);
+	if(envit != env.end())
+	{
+		return envit->second;
+	}
+
+	auto env = std::getenv(key.data());
+	if(env)
+	{
+		return env;
+	}
+
+	return {};
+}
+
 std::vector<std::string> readDeps(const std::string& depFile,
                                   ctor::toolchain toolchain)
 {
diff --git a/src/configure.cc b/src/configure.cc
index 7a68f03..ff4f24d 100644
--- a/src/configure.cc
+++ b/src/configure.cc
@@ -99,6 +99,23 @@ std::string ctor::configuration::get(const std::string& key, const std::string&
 	return default_value;
 }
 
+std::string ctor::configuration::getenv(const std::string& key) const
+{
+	auto envit = env.find(key);
+	if(envit != env.end())
+	{
+		return envit->second;
+	}
+
+	auto sysenv = std::getenv(key.data());
+	if(sysenv)
+	{
+		return sysenv;
+	}
+
+	return {};
+}
+
 class Args
 	: public std::vector<char*>
 {
@@ -838,12 +855,24 @@ int configure(const ctor::settings& global_settings, int argc, char* argv[])
 		env["CC"] = cc_env;
 	}
 
+	auto cflags_env = getenv("CFLAGS");
+	if(cflags_env)
+	{
+		env["CFLAGS"] = cflags_env;
+	}
+
 	auto cxx_env = getenv("CXX");
 	if(cxx_env)
 	{
 		env["CXX"] = cxx_env;
 	}
 
+	auto cxxflags_env = getenv("CXXFLAGS");
+	if(cxxflags_env)
+	{
+		env["CXXFLAGS"] = cxxflags_env;
+	}
+
 	auto ar_env = getenv("AR");
 	if(ar_env)
 	{
@@ -856,6 +885,12 @@ int configure(const ctor::settings& global_settings, int argc, char* argv[])
 		env["LD"] = ld_env;
 	}
 
+	auto ldflags_env = getenv("LDFLAGS");
+	if(ldflags_env)
+	{
+		env["LDFLAGS"] = ldflags_env;
+	}
+
 	auto path_env = getenv("PATH");
 	if(path_env)
 	{
diff --git a/src/ctor.h b/src/ctor.h
index 191fed1..6afb51e 100644
--- a/src/ctor.h
+++ b/src/ctor.h
@@ -292,6 +292,8 @@ struct configuration
 	ctor::arch build_arch{ctor::arch::unknown};
 
 	std::vector<std::string> args; // vector of arguments used when last calling configure
+
+	std::string getenv(const std::string& key) const;
 	std::map<std::string, std::string> env; // env used when last calling configure
 
 	std::map<std::string, std::string> tools; // tools
diff --git a/src/task_cc.cc b/src/task_cc.cc
index b9edcf7..97e99af 100644
--- a/src/task_cc.cc
+++ b/src/task_cc.cc
@@ -191,7 +191,33 @@ int TaskCC::runInner()
 		std::cout << output << std::flush;
 	}
 
+	auto toolchain = getToolChain(config.system);
 	const auto& cfg = ctor::get_configuration();
+	switch(sourceLanguage())
+	{
+	case ctor::language::c:
+		{
+			auto cflags = cfg.getenv("CFLAGS");
+			if(!cflags.empty())
+			{
+				append(args, c_option(toolchain, ctor::c_opt::custom, cflags));
+			}
+		}
+		break;
+	case ctor::language::cpp:
+		{
+			auto cxxflags = cfg.getenv("CXXFLAGS");
+			if(!cxxflags.empty())
+			{
+				append(args, cxx_option(toolchain, ctor::cxx_opt::custom, cxxflags));
+			}
+		}
+		break;
+	case ctor::language::automatic:
+	case ctor::language::assembler:
+		// Only c/c++ handled by this task type.
+		break;
+	}
 	auto res = execute(settings, compiler(), args, cfg.env);
 	if(res != 0)
 	{
diff --git a/src/task_ld.cc b/src/task_ld.cc
index 69c3a8a..03745be 100644
--- a/src/task_ld.cc
+++ b/src/task_ld.cc
@@ -128,8 +128,13 @@ int TaskLD::runInner()
 	}
 
 	auto tool = compiler();
-	const auto& c = ctor::get_configuration();
-	auto res = execute(settings, tool, args, c.env, is_self);
+	const auto& cfg = ctor::get_configuration();
+	auto ldflags = cfg.getenv("LDFLAGS");
+	if(!ldflags.empty())
+	{
+		append(args, ld_option(toolchain, ctor::ld_opt::custom, ldflags));
+	}
+	auto res = execute(settings, tool, args, cfg.env, is_self);
 	if(res != 0)
 	{
 		std::filesystem::remove(targetFile());
diff --git a/src/task_so.cc b/src/task_so.cc
index c98e4a7..92aeefe 100644
--- a/src/task_so.cc
+++ b/src/task_so.cc
@@ -116,6 +116,11 @@ int TaskSO::runInner()
 
 	auto tool = compiler();
 	const auto& cfg = ctor::get_configuration();
+	auto ldflags = cfg.getenv("LDFLAGS");
+	if(!ldflags.empty())
+	{
+		append(args, ld_option(toolchain, ctor::ld_opt::custom, ldflags));
+	}
 	auto res = execute(settings, tool, args, cfg.env);
 	if(res != 0)
 	{
-- 
cgit v1.2.3