diff options
| -rw-r--r-- | Makefile | 11 | ||||
| -rw-r--r-- | cppbuild.cc | 19 | ||||
| -rw-r--r-- | libcppbuild.cc | 204 | ||||
| -rw-r--r-- | libcppbuild.h | 12 | ||||
| -rw-r--r-- | src/bar.cc | 9 | ||||
| -rw-r--r-- | src/bar.o | bin | 0 -> 2848 bytes | |||
| -rw-r--r-- | src/bas.h | 2 | ||||
| -rw-r--r-- | src/foo.cc | 6 | ||||
| -rw-r--r-- | src/foo.h | 5 | 
9 files changed, 268 insertions, 0 deletions
diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7cad9bd --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +all: libcppbuild.a cppbuild + +libcppbuild.a: libcppbuild.cc +	g++ -g -std=c++17  libcppbuild.cc -c -o libcppbuild.o +	ar rcs libcppbuild.a libcppbuild.o + +cppbuild: cppbuild.cc libcppbuild.a +	g++ -g -std=c++17 cppbuild.cc libcppbuild.a -o cppbuild + +clean: +	rm -f cppbuild libcppbuild.o libcppbuild.a diff --git a/cppbuild.cc b/cppbuild.cc new file mode 100644 index 0000000..b06b082 --- /dev/null +++ b/cppbuild.cc @@ -0,0 +1,19 @@ +#include <vector> +#include <string> +#include <utility> + +#include "libcppbuild.h" + +BuildConfiguration configs() +{ +	return +	{ +		// target +		"bas", +		{ +			// source files +			"src/foo.cc", +			"src/bar.cc", +		} +	}; +} diff --git a/libcppbuild.cc b/libcppbuild.cc new file mode 100644 index 0000000..ff208b3 --- /dev/null +++ b/libcppbuild.cc @@ -0,0 +1,204 @@ +#include <vector> +#include <string> +#include <filesystem> +#include <iostream> +#include <fstream> +#include <regex> +#include <utility> + +#include "libcppbuild.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 :: + + + +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::cout << "Building\n"; +	for(const auto& file : files) +	{ +		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)) +		{ +			std::string compiler = "g++ -MMD -c " + file + " -o " + object; +			std::cout << compiler << "\n"; +			if(system(compiler.data())) +			{ +				return 1; +			} +		} +	} + +	std::cout << "Linking\n"; +	bool dolink{false}; +	if(!std::filesystem::exists(output)) +	{ +		dolink = true; +	} +	else +	{ +		for(const auto& object : objects) +		{ +			if(std::filesystem::last_write_time(output) <= +			   std::filesystem::last_write_time(object)) +			{ +				dolink = true; +				break; +			} +		} +	} + +	if(!dolink) +	{ +		std::cout << "No linking needed\n"; +		return 0; +	} + +	std::string objectlist; +	for(const auto& object : objects) +	{ +		objectlist += object + " "; +	} +	std::string compiler = "g++ " + objectlist + " -o " + output; +	std::cout << compiler << "\n"; +	if(system(compiler.data())) +	{ +		return 1; +	} + +	return 0; +} diff --git a/libcppbuild.h b/libcppbuild.h new file mode 100644 index 0000000..11a8eb7 --- /dev/null +++ b/libcppbuild.h @@ -0,0 +1,12 @@ +#pragma once + +#include <string> +#include <vector> + +struct BuildConfiguration +{ +	std::string target; +	std::vector<std::string> sources; +}; + +BuildConfiguration configs(); diff --git a/src/bar.cc b/src/bar.cc new file mode 100644 index 0000000..2486a0a --- /dev/null +++ b/src/bar.cc @@ -0,0 +1,9 @@ +#include <iostream> + +#include "foo.h" + +int main() +{ +	foo(); +	std::cout << __FILE__ << "\n"; +} diff --git a/src/bar.o b/src/bar.o Binary files differnew file mode 100644 index 0000000..37903db --- /dev/null +++ b/src/bar.o diff --git a/src/bas.h b/src/bas.h new file mode 100644 index 0000000..3f59c93 --- /dev/null +++ b/src/bas.h @@ -0,0 +1,2 @@ +#pragma once + diff --git a/src/foo.cc b/src/foo.cc new file mode 100644 index 0000000..b2c478c --- /dev/null +++ b/src/foo.cc @@ -0,0 +1,6 @@ +#include <iostream> + +void foo() +{ +	std::cout << __FILE__ << "\n"; +} diff --git a/src/foo.h b/src/foo.h new file mode 100644 index 0000000..9620fc7 --- /dev/null +++ b/src/foo.h @@ -0,0 +1,5 @@ +#pragma once + +#include "bas.h" + +void foo();  | 
