diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2021-06-19 18:00:48 +0200 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2021-06-19 18:19:44 +0200 | 
| commit | 69528ba012ac2238f63464fb84e7623f3088603a (patch) | |
| tree | c587fb15494d448a572e28ad6156aa9bb196ac17 | |
| parent | f1fda74cb76600b746cc3239f3ebf2f69ce2bf53 (diff) | |
Add compilation database generation.
| -rw-r--r-- | TODO | 3 | ||||
| -rw-r--r-- | libcppbuild.cc | 37 | ||||
| -rw-r--r-- | task.h | 2 | ||||
| -rw-r--r-- | task_cc.cc | 103 | ||||
| -rw-r--r-- | task_cc.h | 3 | 
5 files changed, 106 insertions, 42 deletions
@@ -1,9 +1,6 @@  Glob convenience methods  std::string glob = getFilesInDir(...); -Generate compilation database -https://clang.llvm.org/docs/JSONCompilationDatabase.html -  Add support for pre/post build hooks with conditions  Add shell script targets to be able to generate soucre files that can diff --git a/libcppbuild.cc b/libcppbuild.cc index 9fcc4d4..8d5231f 100644 --- a/libcppbuild.cc +++ b/libcppbuild.cc @@ -11,6 +11,7 @@  #include <list>  #include <array>  #include <deque> +#include <fstream>  #include <getoptpp/getoptpp.hpp> @@ -179,6 +180,9 @@ int main(int argc, char* argv[])  		std::max(1u, std::thread::hardware_concurrency() * 2 - 1);  	settings.verbose = 0; +	bool write_compilation_database{false}; +	std::string compilation_database; +  	dg::Options opt;  	opt.add("jobs", required_argument, 'j', @@ -210,6 +214,14 @@ int main(int argc, char* argv[])  		        return 0;  	        }); +	opt.add("database", required_argument, 'd', +	        "Write compilation database json file.", +	        [&]() { +		        write_compilation_database = true; +		        compilation_database = optarg; +		        return 0; +	        }); +  	opt.add("help", no_argument, 'h',  	        "Print this help text.",  	        [&]() { @@ -246,6 +258,31 @@ int main(int argc, char* argv[])  		}  	} +	if(write_compilation_database) +	{ +		std::ofstream istr(compilation_database); +		istr << "["; +		bool first{true}; +		for(auto task : tasks) +		{ +			auto s = task->toJSON(); +			if(!s.empty()) +			{ +				if(!first) +				{ +					istr << ",\n"; +				} +				else +				{ +					istr << "\n"; +				} +				first = false; +				istr << s; +			} +		} +		istr << "\n]\n"; +	} +  	for(auto task : tasks)  	{  		if(task->registerDepTasks(tasks)) @@ -31,6 +31,8 @@ public:  	virtual std::vector<std::string> depends() const = 0;  	virtual std::string target() const = 0; +	virtual std::string toJSON() const { return {}; }; +  protected:  	std::atomic<State> task_state{State::Unknown};  	virtual int runInner() { return 0; }; @@ -175,44 +175,7 @@ int TaskCC::runInner()  		return 1;  	} -	std::string comp = compiler(); -	auto compiler_flags = flags(); - -	std::vector<std::string> args; -	args.push_back("-MMD"); - -	if(std::filesystem::path(config.target).extension() == ".so") -	{ -		// Add -fPIC arg to all contained object files -		args.push_back("-fPIC"); -	} - -	args.push_back("-c"); -	args.push_back(std::string(sourceFile)); -	args.push_back("-o"); -	args.push_back(std::string(targetFile)); - -	for(const auto& flag : compiler_flags) -	{ -		// Is arg an added include path? -		if(flag.substr(0, 2) == "-I") -		{ -			std::string include_path = flag.substr(2); -			include_path.erase(0, include_path.find_first_not_of(' ')); -			std::filesystem::path path(include_path); - -			// Is it relative? -			if(path.is_relative()) -			{ -				path = (sourceDir / path).lexically_normal(); -				std::string new_include_path = "-I" + path.string(); -				args.push_back(new_include_path); -				continue; -			} -		} - -		args.push_back(flag); -	} +	auto args = getCompilerArgs();  	{ // Write flags to file.  		std::ofstream flagsStream(flagsFile); @@ -225,7 +188,8 @@ int TaskCC::runInner()  			sourceFile.lexically_normal().string() << " => " <<  			targetFile.lexically_normal().string() << "\n";  	} -	return execute(comp, args, settings.verbose > 0); + +	return execute(compiler(), args, settings.verbose > 0);  }  int TaskCC::clean() @@ -261,6 +225,24 @@ std::string TaskCC::target() const  	return targetFile;  } +std::string TaskCC::toJSON() const +{ +	std::string json; +	json += "\t{\n"; +	json += "\t\t\"directory\": \"" + sourceDir.string() + "\",\n"; +	json += "\t\t\"file\": \"" + sourceFile.lexically_normal().string() + "\",\n"; +	json += "\t\t\"output\": \"" + targetFile.string() + "\",\n"; +	json += "\t\t\"arguments\": [ \"" + compiler() + "\""; +	auto args = getCompilerArgs(); +	for(const auto& arg : args) +	{ +		json += ", \"" + arg + "\""; +	} +	json += " ]\n"; +	json += "\t}"; +	return json; +} +  std::vector<std::string> TaskCC::flags() const  {  	if(std::string(sourceFile.extension()) == ".c") @@ -292,3 +274,46 @@ std::string TaskCC::compiler() const  	}  	return "/usr/bin/g++";  } + +std::vector<std::string> TaskCC::getCompilerArgs() const +{ +	auto compiler_flags = flags(); + +	std::vector<std::string> args; +	args.push_back("-MMD"); + +	if(std::filesystem::path(config.target).extension() == ".so") +	{ +		// Add -fPIC arg to all contained object files +		args.push_back("-fPIC"); +	} + +	args.push_back("-c"); +	args.push_back(std::string(sourceFile)); +	args.push_back("-o"); +	args.push_back(std::string(targetFile)); + +	for(const auto& flag : compiler_flags) +	{ +		// Is arg an added include path? +		if(flag.substr(0, 2) == "-I") +		{ +			std::string include_path = flag.substr(2); +			include_path.erase(0, include_path.find_first_not_of(' ')); +			std::filesystem::path path(include_path); + +			// Is it relative? +			if(path.is_relative()) +			{ +				path = (sourceDir / path).lexically_normal(); +				std::string new_include_path = "-I" + path.string(); +				args.push_back(new_include_path); +				continue; +			} +		} + +		args.push_back(flag); +	} + +	return args; +} @@ -28,10 +28,13 @@ public:  	std::string target() const override; +	std::string toJSON() const override; +  private:  	std::vector<std::string> flags() const;  	std::string flagsString() const;  	std::string compiler() const; +	std::vector<std::string> getCompilerArgs() const;  	std::filesystem::path sourceFile;  	std::filesystem::path targetFile;  | 
