diff options
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | Makefile | 3 | ||||
| -rw-r--r-- | configure.cc | 153 | ||||
| -rw-r--r-- | configure.h | 19 | ||||
| -rw-r--r-- | libcppbuild.cc | 401 | ||||
| -rw-r--r-- | rebuild.cc | 137 | ||||
| -rw-r--r-- | rebuild.h | 24 | ||||
| -rw-r--r-- | tasks.cc | 123 | ||||
| -rw-r--r-- | tasks.h | 18 | ||||
| -rw-r--r-- | toolchain.cc | 17 | ||||
| -rw-r--r-- | toolchain.h | 14 | 
11 files changed, 515 insertions, 397 deletions
@@ -3,3 +3,6 @@ build/  cppbuild  *.a  *.o +*.d +configuration.cc +config.h @@ -8,6 +8,9 @@ SRC = \  	task_so.cc \  	task.cc \  	execute.cc \ +	configure.cc \ +	rebuild.cc \ +	tasks.cc \  OBJ = $(patsubst %.cc,%.o,$(SRC)) diff --git a/configure.cc b/configure.cc new file mode 100644 index 0000000..e84f808 --- /dev/null +++ b/configure.cc @@ -0,0 +1,153 @@ +#include "configure.h" + +#include <iostream> +#include <filesystem> +#include <fstream> + +#include <getoptpp/getoptpp.hpp> + +#include "settings.h" +#include "execute.h" +#include "libcppbuild.h" +#include "tasks.h" + +std::filesystem::path configurationFile("configuration.cc"); +std::filesystem::path configHeaderFile("config.h"); + +const std::map<std::string, std::string> default_configuration{}; +const std::map<std::string, std::string>& __attribute__((weak)) configuration() +{ +	return default_configuration; +} + +bool hasConfiguration(const std::string& key) +{ +	const auto& c = configuration(); +	return c.find(key) != c.end(); +} + +const std::string& getConfiguration(const std::string& key, +                                    const std::string& defaultValue) +{ +	const auto& c = configuration(); +	if(hasConfiguration(key)) +	{ +		return c.at(key); +	} + +	return defaultValue; +} + +int configure(int argc, char* argv[]) +{ +	Settings settings; + +	settings.builddir = "build"; + +	std::string cmd_str; +	for(int i = 0; i < argc; ++i) +	{ +		if(i > 0) +		{ +			cmd_str += " "; +		} +		cmd_str += argv[i]; +	} + +	dg::Options opt; +	int key{256}; + +	std::string build_arch; +	std::string host_arch; + +	opt.add("build-dir", required_argument, 'b', +	        "Set output directory for build files (default: '" + +	        settings.builddir + "').", +	        [&]() { +		        settings.builddir = optarg; +		        return 0; +	        }); + +	opt.add("verbose", no_argument, 'v', +	        "Be verbose. Add multiple times for more verbosity.", +	        [&]() { +		        settings.verbose++; +		        return 0; +	        }); + +	opt.add("build", required_argument, key++, +	        "Configure for building on specified architecture.", +	        [&]() { +		        build_arch = optarg; +		        return 0; +	        }); + +	opt.add("host", required_argument, key++, +	        "Cross-compile to build programs to run on specified architecture.", +	        [&]() { +		        host_arch = optarg; +		        return 0; +	        }); + +	opt.add("help", no_argument, 'h', +	        "Print this help text.", +	        [&]() { +		        std::cout << "configure usage stuff\n"; +		        opt.help(); +		        exit(0); +		        return 0; +	        }); + +	opt.process(argc, argv); + +	if(host_arch.empty()) +	{ +		host_arch = build_arch; +	} + +	auto tasks = getTasks(settings); + +	bool needs_cpp{false}; +	bool needs_c{false}; +	bool needs_ar{false}; +	for(const auto& task :tasks) +	{ +		switch(task->sourceLanguage()) +		{ +		case Language::Auto: +			std::cerr << "TargetLanguage not deduced!\n"; +			exit(1); +			break; +		case Language::C: +			needs_cpp = false; +			break; +		case Language::Cpp: +			needs_c = true; +			break; +		} +	} + +	{ +		std::ofstream istr(configurationFile); +		istr << "#include \"libcppbuild.h\"\n\n"; +		istr << "const std::map<std::string, std::string>& configuration()\n"; +		istr << "{\n"; +		istr << "	static std::map<std::string, std::string> c =\n"; +		istr << "	{\n"; +		istr << "		{ \"cmd\", \"" << cmd_str << "\" },\n"; +		istr << "		{ \"" << cfg::builddir << "\", \"" << settings.builddir << "\" },\n"; +		istr << "		{ \"" << cfg::target_cc << "\", \"/usr/bin/gcc\" },\n"; +		istr << "		{ \"" << cfg::target_cpp << "\", \"/usr/bin/g++\" },\n"; +		istr << "		{ \"" << cfg::target_ar << "\", \"/usr/bin/ar\" },\n"; +		istr << "		{ \"" << cfg::target_ld << "\", \"/usr/bin/ld\" },\n"; +		istr << "		{ \"" << cfg::host_cc << "\", \"/usr/bin/gcc\" },\n"; +		istr << "		{ \"" << cfg::host_cpp << "\", \"/usr/bin/g++\" },\n"; +		istr << "		{ \"" << cfg::host_ar << "\", \"/usr/bin/ar\" },\n"; +		istr << "		{ \"" << cfg::host_ld << "\", \"/usr/bin/ld\" },\n"; +		istr << "	};\n"; +		istr << "	return c;\n"; +		istr << "}\n"; +	} + +	return 0; +} diff --git a/configure.h b/configure.h new file mode 100644 index 0000000..95b6765 --- /dev/null +++ b/configure.h @@ -0,0 +1,19 @@ +// -*- c++ -*- +#pragma once + +#include <filesystem> +#include <string> +#include <map> + +extern std::filesystem::path configurationFile;; +extern std::filesystem::path configHeaderFile; + +int configure(int argc, char* argv[]); + +bool hasConfiguration(const std::string& key); +const std::string& getConfiguration(const std::string& key, +                                    const std::string& defaultValue); + +const std::map<std::string, std::string>& configuration(); + +extern const std::map<std::string, std::string> default_configuration; diff --git a/libcppbuild.cc b/libcppbuild.cc index 2a2c40d..6d1d6e5 100644 --- a/libcppbuild.cc +++ b/libcppbuild.cc @@ -14,411 +14,18 @@  #include <fstream>  #include <cstdlib>  #include <set> +#include <future>  #include <getoptpp/getoptpp.hpp>  #include "libcppbuild.h" -#include "task_cc.h" -#include "task_ld.h" -#include "task_ar.h" -#include "task_so.h"  #include "settings.h" -#include "execute.h" - -#include <unistd.h> - - -namespace -{ -std::filesystem::path configurationFile("configuration.cc"); -const std::map<std::string, std::string> default_configuration{}; -} -const std::map<std::string, std::string>& __attribute__((weak)) configuration() -{ -	return default_configuration; -} - -bool hasConfiguration(const std::string& key) -{ -	const auto& c = configuration(); -	return c.find(key) != c.end(); -} - -const std::string& getConfiguration(const std::string& key, -                                    const std::string& defaultValue) -{ -	const auto& c = configuration(); -	if(hasConfiguration(key)) -	{ -		return c.at(key); -	} - -	return defaultValue; -} +#include "configure.h" +#include "rebuild.h" +#include "tasks.h"  using namespace std::chrono_literals; -std::list<std::shared_ptr<Task>> taskFactory(const BuildConfiguration& config, -                                             const Settings& settings, -                                             const std::string& sourceDir) -{ -	std::filesystem::path targetFile(config.target); - -	TargetType target_type{config.type}; -	if(target_type == TargetType::Auto) -	{ -		if(targetFile.extension() == ".a") -		{ -			target_type = TargetType::StaticLibrary; -		} -		else if(targetFile.extension() == ".so") -		{ -			target_type = TargetType::DynamicLibrary; -		} -		else if(targetFile.extension() == "") -		{ -			target_type = TargetType::Executable; -		} -		else -		{ -			std::cerr << "Could not deduce target type from target " << -				targetFile.string() << " please specify.\n"; -			exit(1); -		} -	} - -	std::vector<std::string> objects; -	std::list<std::shared_ptr<Task>> tasks; -	for(const auto& file : config.sources) -	{ -		tasks.emplace_back(std::make_shared<TaskCC>(config, settings, -		                                            sourceDir, file)); -		objects.push_back(tasks.back()->target()); -	} - -	switch(target_type) -	{ -	case TargetType::StaticLibrary: -		tasks.emplace_back(std::make_shared<TaskAR>(config, settings, config.target, -		                                            objects)); -		break; - -	case TargetType::DynamicLibrary: -		if(targetFile.stem().string().substr(0, 3) != "lib") -		{ -			std::cerr << "Dynamic library target must have 'lib' prefix\n"; -			exit(1); -		} -		tasks.emplace_back(std::make_shared<TaskSO>(config, settings, config.target, -		                                            objects)); -		break; - -	case TargetType::Executable: -		tasks.emplace_back(std::make_shared<TaskLD>(config, settings, config.target, -		                                            objects)); -		break; -	} - -	return tasks; -} - -std::shared_ptr<Task> getNextTask(const std::list<std::shared_ptr<Task>>& allTasks, -                                  std::list<std::shared_ptr<Task>>& dirtyTasks) -{ -	for(auto dirtyTask = dirtyTasks.begin(); -	    dirtyTask != dirtyTasks.end(); -	    ++dirtyTask) -	{ -		//std::cout << "Examining target " << (*dirtyTask)->target() << "\n"; -		if((*dirtyTask)->ready()) -		{ -			dirtyTasks.erase(dirtyTask); -			return *dirtyTask; -		} -	} - -	//std::cout << "No task ready ... \n"; -	return nullptr; -} - -namespace -{ -struct BuildConfigurationEntry -{ -	const char* file; -	std::vector<BuildConfiguration> (*cb)(); -}; -std::array<BuildConfigurationEntry, 1024> configFiles; -std::size_t numConfigFiles{0}; -} - -// TODO: Use c++20 when ready, somehing like this: -//int reg(const std::source_location location = std::source_location::current()) -int reg(const char* location, std::vector<BuildConfiguration> (*cb)()) -{ -	// NOTE: std::cout cannot be used here -	if(numConfigFiles >= configFiles.size()) -	{ -		fprintf(stderr, "Max %d build configurations currently supported.\n", -		        (int)configFiles.size()); -		exit(1); -	} - -	configFiles[numConfigFiles].file = location; -	configFiles[numConfigFiles].cb = cb; -	++numConfigFiles; - -	return 0; -} - -int unreg(const char* location) -{ -	std::size_t found{0}; -	for(std::size_t i = 0; i < numConfigFiles;) -	{ -		if(std::string(location) == configFiles[i].file) -		{ -			++found; -			for(std::size_t j = i; j < numConfigFiles; ++j) -			{ -				configFiles[j] = configFiles[j + 1]; -			} -			--numConfigFiles; -		} -		else -		{ -			++i; -		} -	} - -	return found; -} - -void recompileCheck(const Settings& settings, int argc, char* argv[], -                    bool force = false) -{ -	bool dirty{force}; - -	std::vector<std::string> args; -	args.push_back("-s"); -	args.push_back("-O3"); -	args.push_back("-std=c++17"); -	args.push_back("-pthread"); - -	std::filesystem::path binFile("cppbuild"); - -	if(std::filesystem::exists(configurationFile)) -	{ -		args.push_back(configurationFile.string()); - -		if(std::filesystem::last_write_time(binFile) <= -		   std::filesystem::last_write_time(configurationFile)) -		{ -			dirty = true; -		} - -		const auto& c = configuration(); -		if(&c == &default_configuration) -		{ -			// configuration.cc exists, but currently compiled with the default one. -			dirty = true; -		} -	} - -	if(settings.verbose > 1) -	{ -		std::cout << "Recompile check (" << numConfigFiles << "):\n"; -	} - -	for(std::size_t i = 0; i < numConfigFiles; ++i) -	{ -		std::string location = configFiles[i].file; -		if(settings.verbose > 1) -		{ -			std::cout << " - " << location << "\n"; -		} -		std::filesystem::path configFile(location); -		if(std::filesystem::last_write_time(binFile) <= -		   std::filesystem::last_write_time(configFile)) -		{ -			dirty = true; -		} - -		// Support adding multiple config functions from the same file -		if(std::find(args.begin(), args.end(), location) == std::end(args)) -		{ -			args.push_back(location); -		} -	} -	args.push_back("libcppbuild.a"); -	args.push_back("-o"); -	args.push_back(binFile.string()); - -	if(dirty) -	{ -		std::cout << "Rebuilding config\n"; -		auto tool = getConfiguration(cfg::host_cpp, "/usr/bin/g++"); -		auto ret = execute(tool, args, settings.verbose > 0); -		if(ret != 0) -		{ -			std::cerr << "Failed: ." << ret << "\n"; -			exit(1); -		} -		else -		{ -			std::cout << "Re-launch\n"; -			std::vector<std::string> args; -			for(int i = 1; i < argc; ++i) -			{ -				args.push_back(argv[i]); -			} -			exit(execute(argv[0], args, settings.verbose > 0)); -		} -	} -} - -std::list<std::shared_ptr<Task>> getTasks(const Settings& settings) -{ -	static std::deque<BuildConfiguration> build_configs; -	std::list<std::shared_ptr<Task>> tasks; -	for(std::size_t i = 0; i < numConfigFiles; ++i) -	{ -		std::string path = -			std::filesystem::path(configFiles[i].file).parent_path(); -		if(settings.verbose > 1) -		{ -			std::cout << configFiles[i].file << " in path " << path << "\n"; -		} -		auto configs = configFiles[i].cb(); -		for(const auto& config : configs) -		{ -			build_configs.push_back(config); -			const auto& build_config = build_configs.back(); -			std::vector<std::string> objects; -			auto t = taskFactory(build_config, settings, path); -			tasks.insert(tasks.end(), t.begin(), t.end()); -		} -	} - -	return tasks; -} - -/* -int configure(int argc, char* argv[]) -{ -	Settings settings; - -	settings.builddir = "build"; - -	std::string cmd_str; -	for(int i = 0; i < argc; ++i) -	{ -		if(i > 0) -		{ -			cmd_str += " "; -		} -		cmd_str += argv[i]; -	} - -	dg::Options opt; -	int key{256}; - -	std::string build_arch; -	std::string host_arch; - -	opt.add("build-dir", required_argument, 'b', -	        "Set output directory for build files (default: '" + -	        settings.builddir + "').", -	        [&]() { -		        settings.builddir = optarg; -		        return 0; -	        }); - -	opt.add("verbose", no_argument, 'v', -	        "Be verbose. Add multiple times for more verbosity.", -	        [&]() { -		        settings.verbose++; -		        return 0; -	        }); - -	opt.add("build", required_argument, key++, -	        "Configure for building on specified architecture.", -	        [&]() { -		        build_arch = optarg; -		        return 0; -	        }); - -	opt.add("host", required_argument, key++, -	        "Cross-compile to build programs to run on specified architecture.", -	        [&]() { -		        host_arch = optarg; -		        return 0; -	        }); - -	opt.add("help", no_argument, 'h', -	        "Print this help text.", -	        [&]() { -		        std::cout << "configure usage stuff\n"; -		        opt.help(); -		        exit(0); -		        return 0; -	        }); - -	opt.process(argc, argv); - -	if(host_arch.empty()) -	{ -		host_arch = build_arch; -	} - -	auto tasks = getTasks(settings); - -	bool needs_cpp{false}; -	bool needs_c{false}; -	bool needs_ar{false}; -	for(const auto& task :tasks) -	{ -		switch(task->sourceLanguage()) -		{ -		case Language::Auto: -			std::cerr << "TargetLanguage not deduced!\n"; -			exit(1); -			break; -		case Language::C: -			needs_cpp = false; -			break; -		case Language::Cpp: -			needs_c = true; -			break; -		} -	} - -	{ -		std::ofstream istr(configurationFile); -		istr << "#include \"libcppbuild.h\"\n\n"; -		istr << "const std::map<std::string, std::string>& configuration()\n"; -		istr << "{\n"; -		istr << "	static std::map<std::string, std::string> c =\n"; -		istr << "	{\n"; -		istr << "		{ \"cmd\", \"" << cmd_str << "\" },\n"; -		istr << "		{ \"" << cfg::builddir << "\", \"" << settings.builddir << "\" },\n"; -		istr << "		{ \"" << cfg::target_cc << "\", \"/usr/bin/gcc\" },\n"; -		istr << "		{ \"" << cfg::target_cpp << "\", \"/usr/bin/g++\" },\n"; -		istr << "		{ \"" << cfg::target_ar << "\", \"/usr/bin/ar\" },\n"; -		istr << "		{ \"" << cfg::target_ld << "\", \"/usr/bin/ld\" },\n"; -		istr << "		{ \"" << cfg::host_cc << "\", \"/usr/bin/gcc\" },\n"; -		istr << "		{ \"" << cfg::host_cpp << "\", \"/usr/bin/g++\" },\n"; -		istr << "		{ \"" << cfg::host_ar << "\", \"/usr/bin/ar\" },\n"; -		istr << "		{ \"" << cfg::host_ld << "\", \"/usr/bin/ld\" },\n"; -		istr << "	};\n"; -		istr << "	return c;\n"; -		istr << "}\n"; -	} - - -	return 0; -} -  int main(int argc, char* argv[])  {  	if(argc > 1 && std::string(argv[1]) == "configure") diff --git a/rebuild.cc b/rebuild.cc new file mode 100644 index 0000000..0978eb1 --- /dev/null +++ b/rebuild.cc @@ -0,0 +1,137 @@ +#include "rebuild.h" + +#include <iostream> +#include <filesystem> +#include <algorithm> + +#include "execute.h" +#include "configure.h" +#include "settings.h" +#include "libcppbuild.h" + +std::array<BuildConfigurationEntry, 1024> configFiles; +std::size_t numConfigFiles{0}; + +// TODO: Use c++20 when ready, somehing like this: +//int reg(const std::source_location location = std::source_location::current()) +int reg(const char* location, std::vector<BuildConfiguration> (*cb)()) +{ +	// NOTE: std::cout cannot be used here +	if(numConfigFiles >= configFiles.size()) +	{ +		fprintf(stderr, "Max %d build configurations currently supported.\n", +		        (int)configFiles.size()); +		exit(1); +	} + +	configFiles[numConfigFiles].file = location; +	configFiles[numConfigFiles].cb = cb; +	++numConfigFiles; + +	return 0; +} + +int unreg(const char* location) +{ +	std::size_t found{0}; +	for(std::size_t i = 0; i < numConfigFiles;) +	{ +		if(std::string(location) == configFiles[i].file) +		{ +			++found; +			for(std::size_t j = i; j < numConfigFiles; ++j) +			{ +				configFiles[j] = configFiles[j + 1]; +			} +			--numConfigFiles; +		} +		else +		{ +			++i; +		} +	} + +	return found; +} + +void recompileCheck(const Settings& settings, int argc, char* argv[], bool force) +{ +	bool dirty{force}; + +	std::vector<std::string> args; +	args.push_back("-s"); +	args.push_back("-O3"); +	args.push_back("-std=c++17"); +	args.push_back("-pthread"); + +	std::filesystem::path binFile("cppbuild"); + +	if(std::filesystem::exists(configurationFile)) +	{ +		args.push_back(configurationFile.string()); + +		if(std::filesystem::last_write_time(binFile) <= +		   std::filesystem::last_write_time(configurationFile)) +		{ +			dirty = true; +		} + +		const auto& c = configuration(); +		if(&c == &default_configuration) +		{ +			// configuration.cc exists, but currently compiled with the default one. +			dirty = true; +		} +	} + +	if(settings.verbose > 1) +	{ +		std::cout << "Recompile check (" << numConfigFiles << "):\n"; +	} + +	for(std::size_t i = 0; i < numConfigFiles; ++i) +	{ +		std::string location = configFiles[i].file; +		if(settings.verbose > 1) +		{ +			std::cout << " - " << location << "\n"; +		} +		std::filesystem::path configFile(location); +		if(std::filesystem::last_write_time(binFile) <= +		   std::filesystem::last_write_time(configFile)) +		{ +			dirty = true; +		} + +		// Support adding multiple config functions from the same file +		if(std::find(args.begin(), args.end(), location) == std::end(args)) +		{ +			args.push_back(location); +		} +	} +	args.push_back("libcppbuild.a"); +	args.push_back("-o"); +	args.push_back(binFile.string()); + +	if(dirty) +	{ +		std::cout << "Rebuilding config\n"; +		auto tool = getConfiguration(cfg::host_cpp, "/usr/bin/g++"); +		auto ret = execute(tool, args, settings.verbose > 0); +		if(ret != 0) +		{ +			std::cerr << "Failed: ." << ret << "\n"; +			exit(1); +		} +		else +		{ +			std::cout << "Re-launch\n"; +			std::vector<std::string> args; +			for(int i = 1; i < argc; ++i) +			{ +				args.push_back(argv[i]); +			} +			exit(execute(argv[0], args, settings.verbose > 0)); +		} +	} +} diff --git a/rebuild.h b/rebuild.h new file mode 100644 index 0000000..d7720c9 --- /dev/null +++ b/rebuild.h @@ -0,0 +1,24 @@ +// -*- c++ -*- +#pragma once + +#include <vector> +#include <array> + +#include "libcppbuild.h" + +class Settings; + +struct BuildConfigurationEntry +{ +	const char* file; +	std::vector<BuildConfiguration> (*cb)(); +}; + +extern std::array<BuildConfigurationEntry, 1024> configFiles; +extern std::size_t numConfigFiles; + +//int reg(const char* location, std::vector<BuildConfiguration> (*cb)()); +int unreg(const char* location); + +void recompileCheck(const Settings& settings, int argc, char* argv[], +                    bool force = false); diff --git a/tasks.cc b/tasks.cc new file mode 100644 index 0000000..641e05b --- /dev/null +++ b/tasks.cc @@ -0,0 +1,123 @@ +#include "tasks.h" + +#include <filesystem> +#include <deque> +#include <iostream> + +#include "settings.h" +#include "libcppbuild.h" +#include "task.h" +#include "task_cc.h" +#include "task_ld.h" +#include "task_ar.h" +#include "task_so.h" +#include "rebuild.h" + +std::list<std::shared_ptr<Task>> taskFactory(const BuildConfiguration& config, +                                             const Settings& settings, +                                             const std::string& sourceDir) +{ +	std::filesystem::path targetFile(config.target); + +	TargetType target_type{config.type}; +	if(target_type == TargetType::Auto) +	{ +		if(targetFile.extension() == ".a") +		{ +			target_type = TargetType::StaticLibrary; +		} +		else if(targetFile.extension() == ".so") +		{ +			target_type = TargetType::DynamicLibrary; +		} +		else if(targetFile.extension() == "") +		{ +			target_type = TargetType::Executable; +		} +		else +		{ +			std::cerr << "Could not deduce target type from target " << +				targetFile.string() << " please specify.\n"; +			exit(1); +		} +	} + +	std::vector<std::string> objects; +	std::list<std::shared_ptr<Task>> tasks; +	for(const auto& file : config.sources) +	{ +		tasks.emplace_back(std::make_shared<TaskCC>(config, settings, +		                                            sourceDir, file)); +		objects.push_back(tasks.back()->target()); +	} + +	switch(target_type) +	{ +	case TargetType::StaticLibrary: +		tasks.emplace_back(std::make_shared<TaskAR>(config, settings, config.target, +		                                            objects)); +		break; + +	case TargetType::DynamicLibrary: +		if(targetFile.stem().string().substr(0, 3) != "lib") +		{ +			std::cerr << "Dynamic library target must have 'lib' prefix\n"; +			exit(1); +		} +		tasks.emplace_back(std::make_shared<TaskSO>(config, settings, config.target, +		                                            objects)); +		break; + +	case TargetType::Executable: +		tasks.emplace_back(std::make_shared<TaskLD>(config, settings, config.target, +		                                            objects)); +		break; +	} + +	return tasks; +} + +std::shared_ptr<Task> getNextTask(const std::list<std::shared_ptr<Task>>& allTasks, +                                  std::list<std::shared_ptr<Task>>& dirtyTasks) +{ +	for(auto dirtyTask = dirtyTasks.begin(); +	    dirtyTask != dirtyTasks.end(); +	    ++dirtyTask) +	{ +		//std::cout << "Examining target " << (*dirtyTask)->target() << "\n"; +		if((*dirtyTask)->ready()) +		{ +			dirtyTasks.erase(dirtyTask); +			return *dirtyTask; +		} +	} + +	//std::cout << "No task ready ... \n"; +	return nullptr; +} + +std::list<std::shared_ptr<Task>> getTasks(const Settings& settings) +{ +	static std::deque<BuildConfiguration> build_configs; +	std::list<std::shared_ptr<Task>> tasks; +	for(std::size_t i = 0; i < numConfigFiles; ++i) +	{ +		std::string path = +			std::filesystem::path(configFiles[i].file).parent_path(); +		if(settings.verbose > 1) +		{ +			std::cout << configFiles[i].file << " in path " << path << "\n"; +		} +		auto configs = configFiles[i].cb(); +		for(const auto& config : configs) +		{ +			build_configs.push_back(config); +			const auto& build_config = build_configs.back(); +			std::vector<std::string> objects; +			auto t = taskFactory(build_config, settings, path); +			tasks.insert(tasks.end(), t.begin(), t.end()); +		} +	} + +	return tasks; +} @@ -0,0 +1,18 @@ +// -*- c++ -*- +#pragma once + +#include <string> +#include <list> +#include <memory> + +#include "task.h" + +class BuildConfiguration; +class Settings; + +std::list<std::shared_ptr<Task>> taskFactory(const BuildConfiguration& config, +                                             const Settings& settings, +                                             const std::string& sourceDir); +std::shared_ptr<Task> getNextTask(const std::list<std::shared_ptr<Task>>& allTasks, +                                  std::list<std::shared_ptr<Task>>& dirtyTasks); +std::list<std::shared_ptr<Task>> getTasks(const Settings& settings); diff --git a/toolchain.cc b/toolchain.cc new file mode 100644 index 0000000..0a8ea98 --- /dev/null +++ b/toolchain.cc @@ -0,0 +1,17 @@ +#include "toolchain.h" + +#include "libcppbuild.h" + +std::string getTool(Tool tool) +{ +	auto prefix = getConfiguration("prefix"); + +	switch(tool) +	{ +	case Tool::CCompiler: +	case Tool::CppCompiler: +	case Tool::Archiver: +	case Tool::Linker: +		break; +	} +} diff --git a/toolchain.h b/toolchain.h new file mode 100644 index 0000000..d3de9a1 --- /dev/null +++ b/toolchain.h @@ -0,0 +1,14 @@ +// -*- c++ -*- +#pragma once + +#include <string> + +enum class Tool +{ +	CCompiler, +	CppCompiler, +	Archiver, +	Linker, +} + +std::string getTool(Tool tool);  | 
