diff options
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | Makefile | 9 | ||||
| -rw-r--r-- | libcppbuild.cc | 176 | ||||
| -rw-r--r-- | libcppbuild.h | 3 | ||||
| -rw-r--r-- | settings.h | 7 | ||||
| -rw-r--r-- | src/bar.o | bin | 2848 -> 0 bytes | |||
| -rw-r--r-- | task.cc | 199 | ||||
| -rw-r--r-- | task.h | 32 | 
8 files changed, 276 insertions, 153 deletions
| diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e518938 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +cppbuild +*.a +*.o
\ No newline at end of file @@ -1,11 +1,12 @@  all: libcppbuild.a cppbuild -libcppbuild.a: libcppbuild.cc +libcppbuild.a: libcppbuild.cc task.cc libcppbuild.h  	g++ -g -std=c++17  libcppbuild.cc -c -o libcppbuild.o -	ar rcs libcppbuild.a libcppbuild.o +	g++ -g -std=c++17  task.cc -c -o task.o +	ar rcs libcppbuild.a libcppbuild.o task.o -cppbuild: cppbuild.cc libcppbuild.a +cppbuild: cppbuild.cc  libcppbuild.h libcppbuild.a  	g++ -g -std=c++17 cppbuild.cc libcppbuild.a -pthread -o cppbuild  clean: -	rm -f cppbuild libcppbuild.o libcppbuild.a +	rm -f cppbuild libcppbuild.o task.o libcppbuild.a diff --git a/libcppbuild.cc b/libcppbuild.cc index ddc0b66..46f1bfc 100644 --- a/libcppbuild.cc +++ b/libcppbuild.cc @@ -2,182 +2,60 @@  #include <string>  #include <filesystem>  #include <iostream> -#include <fstream> -#include <regex>  #include <utility> -//#include <thread> -#include <future>  #include "libcppbuild.h" +#include "task.h" +#include "settings.h" -namespace -{ -std::string readFile(const std::string &fileName) +int main(int argc, const char* argv[])  { -	std::ifstream ifs(fileName.c_str(), std::ios::in | std::ios::binary | std::ios::ate); - -	std::ifstream::pos_type fileSize = ifs.tellg(); -	ifs.seekg(0, std::ios::beg); +	Settings settings; +	settings.builddir = "build/foo"; +	std::filesystem::path builddir(settings.builddir); +	std::filesystem::create_directories(builddir); -	std::vector<char> bytes(fileSize); -	ifs.read(bytes.data(), fileSize); +	auto project = configs(); +	std::string output = builddir / project.target; +	const auto& files = project.sources; +	std::vector<std::string> objects; -	return std::string(bytes.data(), fileSize); -} +	std::vector<Task> tasks; -std::vector<std::string> readDeps(const std::string& depFile) -{ -	if(!std::filesystem::exists(depFile)) +	for(const auto& file : files)  	{ -		return {}; +		tasks.emplace_back(project, settings, file); +		objects.push_back(tasks.back().targetFile);  	} -	auto str = readFile(depFile); - -	std::vector<std::string> output; -	std::string tmp; -	bool start{false}; -	bool in_whitespace{false}; -	for(const auto& c : str) +	if(argc == 2 && std::string(argv[1]) == "clean")  	{ -		if(c == '\\' || c == '\n') -		{ -			continue; -		} - -		if(c == ':') -		{ -			start = true; -			continue; -		} - -		if(!start) +		std::cout << "Cleaning\n"; +		//std::filesystem::remove_all(builddir); +		for(auto& task : tasks)  		{ -			continue; -		} - -		if(c == ' ' || c == '\t') -		{ -			if(in_whitespace) -			{ -				continue; -			} - -			if(!tmp.empty()) +			if(task.clean() != 0)  			{ -				output.push_back(tmp); +				return 1;  			} -			tmp.clear(); -			in_whitespace = true; -		} -		else -		{ -			in_whitespace = false; -			tmp += c;  		} -	} - -	if(!tmp.empty()) -	{ -		output.push_back(tmp); -	} - -	return output; -} -} // namespace :: +		std::filesystem::remove(output); - -int main(int argc, const char* argv[]) -{ -	if(argc == 2 && std::string(argv[1]) == "clean") -	{ -		system("rm -Rf build");  		return 0;  	} -	std::filesystem::path builddir("build/"); -	std::filesystem::create_directory(builddir); - -	auto project = configs(); -	std::string output = "build/" + project.target; -	const auto& files = project.sources; -	std::vector<std::string> objects; - -	std::vector<std::future<int>> tasks; -  	std::cout << "Building\n"; -	for(const auto& file : files) +	// Start all tasks +	for(auto& task : tasks)  	{ -		auto path = std::filesystem::path(file); -		std::string object = builddir / path.stem(); -		object += ".o"; -		objects.push_back(object); - -		std::string deps = builddir / path.stem(); -		deps += ".d"; - -		if(!std::filesystem::exists(file)) -		{ -			std::cout << "Missing source file: " << file << "\n"; -			return 1; -		} - -		bool recompile{false}; - -		if(!std::filesystem::exists(object) || -		   !std::filesystem::exists(deps)) -		{ -			recompile = true; -		} - -		if(!recompile && -		   std::filesystem::last_write_time(file) > -		   std::filesystem::last_write_time(deps)) -		{ -			recompile = true; -		} - -		if(!recompile) -		{ -			auto depList = readDeps(deps); -			for(const auto& dep : depList) -			{ -				if(!std::filesystem::exists(dep) || -				   std::filesystem::last_write_time(object) < -				   std::filesystem::last_write_time(dep)) -				{ -					recompile = true; -					break; -				} -			} -		} - -		if(recompile || -		   !std::filesystem::exists(object) || -		   std::filesystem::last_write_time(file) > -		   std::filesystem::last_write_time(object)) -		{ - -			tasks.emplace_back( -				std::async(std::launch::async, -				           [file, object]() -				           { -					           std::string compiler = "g++ -MMD -c " + file + " -o " + object; -					           std::cout << compiler << "\n"; -					           if(system(compiler.data())) -					           { -						           return 1; -					           } -					           return 0; -				           })); -		} +		task.start();  	} +	// Wait for all tasks  	for(auto& task : tasks)  	{ -		task.wait(); -		if(task.get() != 0) +		if(task.wait() != 0)  		{  			return 1;  		} diff --git a/libcppbuild.h b/libcppbuild.h index 11a8eb7..e9599fc 100644 --- a/libcppbuild.h +++ b/libcppbuild.h @@ -7,6 +7,9 @@ struct BuildConfiguration  {  	std::string target;  	std::vector<std::string> sources; +	std::string cxxflags; +	std::string cflags; +	std::string ldflags;  };  BuildConfiguration configs(); diff --git a/settings.h b/settings.h new file mode 100644 index 0000000..302c6d7 --- /dev/null +++ b/settings.h @@ -0,0 +1,7 @@ +// -*- c++ -*- +#pragma once + +struct Settings +{ +	std::string builddir; +}; diff --git a/src/bar.o b/src/bar.oBinary files differ deleted file mode 100644 index 37903db..0000000 --- a/src/bar.o +++ /dev/null @@ -0,0 +1,199 @@ +#include "task.h" + +#include <iostream> +#include <fstream> + +#include "libcppbuild.h" +#include "settings.h" + +namespace +{ +std::string readFile(const std::string &fileName) +{ +	std::ifstream ifs(fileName.c_str(), std::ios::in | std::ios::binary | std::ios::ate); + +	std::ifstream::pos_type fileSize = ifs.tellg(); +	ifs.seekg(0, std::ios::beg); + +	std::vector<char> bytes(fileSize); +	ifs.read(bytes.data(), fileSize); + +	return std::string(bytes.data(), fileSize); +} + +std::vector<std::string> readDeps(const std::string& depFile) +{ +	if(!std::filesystem::exists(depFile)) +	{ +		return {}; +	} + +	auto str = readFile(depFile); + +	std::vector<std::string> output; +	std::string tmp; +	bool start{false}; +	bool in_whitespace{false}; +	for(const auto& c : str) +	{ +		if(c == '\\' || c == '\n') +		{ +			continue; +		} + +		if(c == ':') +		{ +			start = true; +			continue; +		} + +		if(!start) +		{ +			continue; +		} + +		if(c == ' ' || c == '\t') +		{ +			if(in_whitespace) +			{ +				continue; +			} + +			if(!tmp.empty()) +			{ +				output.push_back(tmp); +			} +			tmp.clear(); +			in_whitespace = true; +		} +		else +		{ +			in_whitespace = false; +			tmp += c; +		} +	} + +	if(!tmp.empty()) +	{ +		output.push_back(tmp); +	} + +	return output; +} +} // namespace :: + +Task::Task(const BuildConfiguration& config, const Settings& settings, +           const std::string& source) +{ +	sourceFile = source; +	targetFile = settings.builddir / sourceFile.stem(); +	targetFile += ".o"; +	depsFile = settings.builddir / sourceFile.stem(); +	depsFile += ".d"; +} + +void Task::start() +{ +	future = +		std::async(std::launch::async, +		 [&]() +		 { +			 if(!std::filesystem::exists(sourceFile)) +			 { +				 std::cout << "Missing source file: " << std::string(sourceFile) << "\n"; +				 return 1; +			 } + +			 bool recompile{false}; + +			 if(!recompile && +			    !std::filesystem::exists(targetFile)) +			 { +				 recompile = true; +				 std::cout << "Missing targetFile\n"; +			 } + +			 if(!recompile && +			    !std::filesystem::exists(depsFile)) +			 { +				 recompile = true; +				 std::cout << "Missing depsFile\n"; +			 } + +			 if(!recompile && +			    std::filesystem::last_write_time(sourceFile) > +			    std::filesystem::last_write_time(depsFile)) +			 { +				 recompile = true; +				 std::cout << "The sourceFile newer than depsFile\n"; +			 } + +			 if(!recompile) +			 { +				 auto depList = readDeps(depsFile); +				 for(const auto& dep : depList) +				 { +					 if(!std::filesystem::exists(dep) || +					    std::filesystem::last_write_time(targetFile) < +					    std::filesystem::last_write_time(dep)) +					 { +						 recompile = true; +						 std::cout << "The targetFile older than dep\n"; +						 break; +					 } +				 } +			 } + +			 if(!recompile && +			    std::filesystem::last_write_time(sourceFile) > +			    std::filesystem::last_write_time(targetFile)) +			 { +				 recompile = true; +				 std::cout << "The targetFile older than sourceFile\n"; +			 } + +			 if(recompile) +			 { +				 std::string cmd = +				 "g++ -MMD -c " + std::string(sourceFile) + +				 " -o " + std::string(targetFile); +				 std::cout << cmd << "\n"; + +				 if(system(cmd.data())) +				 { +					 return 1; +				 } +				 return 0; +			 } + +			 return 0; +		 }); +} + +int Task::wait() +{ +	future.wait(); +	return future.get(); +} + +int Task::clean() +{ +	if(std::filesystem::exists(targetFile)) +	{ +		std::cout << "Removing " << std::string(targetFile) << "\n"; +		std::filesystem::remove(targetFile); +	} + +	if(std::filesystem::exists(depsFile)) +	{ +		std::cout << "Removing " << std::string(depsFile) << "\n"; +		std::filesystem::remove(depsFile); +	} + +	return 0; +} + +std::vector<std::string> Task::depends() +{ +	return {}; +} @@ -0,0 +1,32 @@ +// -*- c++ -*- +#pragma once + +#include <vector> +#include <string> +#include <future> +#include <filesystem> + +struct BuildConfiguration; +struct Settings; + +class Task +{ +public: +	Task(const BuildConfiguration& config, +	     const Settings& settings, +	     const std::string& source); + +	void start(); + +	int wait(); + +	int clean(); + +	std::vector<std::string> depends(); + +	std::filesystem::path sourceFile; +	std::filesystem::path targetFile; +	std::filesystem::path depsFile; + +	std::future<int> future; +}; | 
