diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2021-06-19 09:18:26 +0200 | 
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2021-06-19 09:18:26 +0200 | 
| commit | a2be8eba3aaf11a9a73092793d27d6d46b4270cd (patch) | |
| tree | ec8d463fe0537785337b4632e0c59bc1185b68dc | |
| parent | 80290e7d65dc498e9ea5e64aa6cbc65282072deb (diff) | |
Add .so target. Fix ready state checks.
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | Makefile.dg | 4 | ||||
| -rw-r--r-- | cppbuild.cc | 77 | ||||
| -rw-r--r-- | libcppbuild.cc | 76 | ||||
| -rw-r--r-- | task.cc | 16 | ||||
| -rw-r--r-- | task.h | 13 | ||||
| -rw-r--r-- | task_cc.cc | 7 | ||||
| -rw-r--r-- | task_ld.cc | 11 | ||||
| -rw-r--r-- | task_so.cc | 198 | ||||
| -rw-r--r-- | task_so.h | 42 | 
10 files changed, 397 insertions, 49 deletions
@@ -10,7 +10,7 @@ SRC = \  OBJ = $(patsubst %.cc,%.o,$(SRC)) -CXXFLAGS = -s -O3 -std=c++17 +CXXFLAGS = -g -O3 -std=c++17 -I.  %.o: %.cc  	g++ $(CXXFLAGS) -c $< -o $@ diff --git a/Makefile.dg b/Makefile.dg index 548c0cb..9d8cf09 100644 --- a/Makefile.dg +++ b/Makefile.dg @@ -111,8 +111,8 @@ SRC = \  OBJ = $(patsubst %.c,%.o,$(patsubst %.cc,%.o,$(patsubst %.cpp,%.o,$(SRC)))) -CXXFLAGS = -DUI_X11 -g -Wall -Werror -std=c++11 -Idrumgizmo/getoptpp -Idrumgizmo/ -Idrumgizmo/hugin -Idrumgizmo/plugingui/ -Idrumgizmo/src/ -Idrumgizmo/zita-resampler/libs -Idrumgizmo/pugixml/src -CFLAGS = -g -Wall -Werror +CXXFLAGS = -DUI_X11 -O3 -g -Wall -Werror -std=c++11 -Idrumgizmo/getoptpp -Idrumgizmo/ -Idrumgizmo/hugin -Idrumgizmo/plugingui/ -Idrumgizmo/src/ -Idrumgizmo/zita-resampler/libs -Idrumgizmo/pugixml/src +CFLAGS = -O3 -g -Wall -Werror  LDFLAGS = -lm -lX11 -lXext -pthread -lsndfile  %.o: %.c diff --git a/cppbuild.cc b/cppbuild.cc index 737ba83..882fe63 100644 --- a/cppbuild.cc +++ b/cppbuild.cc @@ -25,6 +25,49 @@ std::vector<BuildConfiguration> configs()  		{  			.target = "plugingui",  			.sources = { +				"drumgizmo/zita-resampler/libs/cresampler.cc", +				"drumgizmo/zita-resampler/libs/resampler-table.cc", +				"drumgizmo/zita-resampler/libs/resampler.cc", +				"drumgizmo/zita-resampler/libs/vresampler.cc", +				"drumgizmo/hugin/hugin.c", +				"drumgizmo/pugixml/src/pugixml.cpp", +			}, +			.depends = { +				"libplugingui.so", +			}, +			.cxxflags = { +				"-DUI_X11", +				"-O3", +				"-g", +				"-Wall", +				"-Werror", +				"-std=c++11", +				"-Idrumgizmo/getoptpp", +				"-Idrumgizmo/", +				"-Idrumgizmo/hugin", +				"-Idrumgizmo/plugingui/", +				"-Idrumgizmo/src/", +				"-Idrumgizmo/zita-resampler/libs", +				"-Idrumgizmo/pugixml/src", +			}, +			.cflags = { +				"-g", +				//"-O3", +				"-Wall", +				"-Werror", +			}, +			.ldflags = { +				"-lm", +				"-lX11", +				"-lXext", +				"-lsndfile", +				"-pthread", +			} +		}, + +		{ +			.target = "src.a", +			.sources = {  				"drumgizmo/src/audiocache.cc",  				"drumgizmo/src/audiocacheeventhandler.cc",  				"drumgizmo/src/audiocachefile.cc", @@ -66,18 +109,10 @@ std::vector<BuildConfiguration> configs()  				"drumgizmo/src/velocityfilter.cc",  				"drumgizmo/src/versionstr.cc",  				"drumgizmo/src/zrwrapper.cc", -				"drumgizmo/zita-resampler/libs/cresampler.cc", -				"drumgizmo/zita-resampler/libs/resampler-table.cc", -				"drumgizmo/zita-resampler/libs/resampler.cc", -				"drumgizmo/zita-resampler/libs/vresampler.cc", -				"drumgizmo/hugin/hugin.c", -				"drumgizmo/pugixml/src/pugixml.cpp", -				"drumgizmo/plugingui/lodepng/lodepng.cpp", -			}, -			.depends = { -				"plugingui.a",  			}, +			.depends = {},  			.cxxflags = { +				"-fPIC",  				"-DUI_X11",  				"-O3",  				"-g", @@ -92,23 +127,12 @@ std::vector<BuildConfiguration> configs()  				"-Idrumgizmo/zita-resampler/libs",  				"-Idrumgizmo/pugixml/src",  			}, -			.cflags = { -				"-g", -				//"-O3", -				"-Wall", -				"-Werror", -			}, -			.ldflags = { -				"-lm", -				"-lX11", -				"-lXext", -				"-lsndfile", -				"-pthread", -			} +			.cflags = {}, +			.ldflags = {}  		},  		{ -			.target = "plugingui.a", +			.target = "libplugingui.so",  			.sources = {  				"drumgizmo/plugingui/abouttab.cc",  				"drumgizmo/plugingui/bleedcontrolframecontent.cc", @@ -171,8 +195,11 @@ std::vector<BuildConfiguration> configs()  				"drumgizmo/plugingui/voicelimitframecontent.cc",  				"drumgizmo/plugingui/widget.cc",  				"drumgizmo/plugingui/window.cc", +				"drumgizmo/plugingui/lodepng/lodepng.cpp", +			}, +			.depends = { +				"src.a",  			}, -			.depends = {},  			.cxxflags = {  				"-DUI_X11",  				"-O3", diff --git a/libcppbuild.cc b/libcppbuild.cc index 7f0a355..69d23ba 100644 --- a/libcppbuild.cc +++ b/libcppbuild.cc @@ -10,10 +10,13 @@  #include <algorithm>  #include <list> +#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 <unistd.h> @@ -23,6 +26,8 @@ using namespace std::chrono_literals;  std::list<std::shared_ptr<Task>> taskFactory(const BuildConfiguration& config,                                               const Settings& settings)  { +	std::filesystem::path targetFile(config.target); +  	std::vector<std::string> objects;  	std::list<std::shared_ptr<Task>> tasks;  	for(const auto& file : config.sources) @@ -31,19 +36,28 @@ std::list<std::shared_ptr<Task>> taskFactory(const BuildConfiguration& config,  		objects.push_back(tasks.back()->target());  	} -	std::filesystem::path targetFile(config.target);  	if(targetFile.extension() == ".a")  	{  		// static lib  		tasks.emplace_back(std::make_shared<TaskAR>(config, settings, config.target,  		                                            objects));  	} +	else if(targetFile.extension() == ".so") +	{ +		if(targetFile.stem().string().substr(0, 3) != "lib") +		{ +			std::cerr << "Dynamic library target must have 'lib' prefix\n"; +			exit(1); +		} +		// dynamic lib +		tasks.emplace_back(std::make_shared<TaskSO>(config, settings, config.target, +		                                            objects)); +	}  	else  	{ -		// binary +		// executable  		tasks.emplace_back(std::make_shared<TaskLD>(config, settings, config.target,  		                                            objects)); -  	}  	return tasks; @@ -68,10 +82,9 @@ std::shared_ptr<Task> getNextTask(const std::list<std::shared_ptr<Task>>& allTas  	return nullptr;  } -int main(int argc, const char* argv[]) +int main(int argc, char* argv[])  {  	Settings settings; -  	// TODO: Set from commandline  	settings.builddir = "build/foo"; @@ -80,6 +93,40 @@ int main(int argc, const char* argv[])  	settings.verbose = 0; +	dg::Options opt; + +	opt.add("jobs", required_argument, 'j', +	        "Number of parallel jobs.", +	        [&]() { +		        try +		        { +			        settings.parallel_processes = std::stoi(optarg); +		        } +		        catch(...) +		        { +			        std::cerr << "Not a number\n"; +			        return 1; +		        } +		        return 0; +	        }); + +	opt.add("verbose", no_argument, 'v', +	        "Be verbose.", +	        [&]() { +		        settings.verbose++; +		        return 0; +	        }); + +	opt.add("help", no_argument, 'h', +	        "Print this help text.", +	        [&]() { +		        std::cout << "usage stuff\n"; +		        opt.help(); +		        return 0; +	        }); + +	opt.process(argc, argv); +  	std::filesystem::path builddir(settings.builddir);  	std::filesystem::create_directories(builddir); @@ -106,19 +153,22 @@ int main(int argc, const char* argv[])  		}  	} -	if(argc == 2 && std::string(argv[1]) == "clean") +	for(auto const &arg : opt.arguments())  	{ -		std::cout << "Cleaning\n"; -		//std::filesystem::remove_all(builddir); -		for(auto& task : tasks) +		if(arg == "clean")  		{ -			if(task->clean() != 0) +			std::cout << "Cleaning\n"; +			//std::filesystem::remove_all(builddir); +			for(auto& task : tasks)  			{ -				return 1; +				if(task->clean() != 0) +				{ +					return 1; +				}  			} -		} -		return 0; +			return 0; +		}  	}  	std::cout << "Building\n"; @@ -39,32 +39,38 @@ bool Task::ready()  {  	for(const auto& task : dependsTasks)  	{ -		if(task->dirty() && !task->done()) +		if(task->dirty() || task->state() == State::Running)  		{  			return false;  		}  	} +	task_state.store(State::Ready);  	return true;  }  int Task::run()  { -	if(is_done.load()) +	if(task_state.load() == State::Done)  	{  		return 0;  	} +	task_state.store(State::Running);  	auto ret = runInner();  	if(ret == 0)  	{ -		is_done.store(true); +		task_state.store(State::Done); +	} +	else +	{ +		task_state.store(State::Error);  	}  	return ret;  } -bool Task::done() const +State Task::state() const  { -	return is_done.load(); +	return task_state.load();  } @@ -7,6 +7,15 @@  #include <list>  #include <memory> +enum class State +{ +	Unknown, +	Ready, +	Running, +	Done, +	Error, +}; +  class Task  {  public: @@ -17,13 +26,13 @@ public:  	bool dirty();  	bool ready();  	int run(); -	bool done() const; +	State state() const;  	virtual int clean() = 0 ;  	virtual std::vector<std::string> depends() const = 0;  	virtual std::string target() const = 0;  protected: -	std::atomic<bool> is_done{false}; +	std::atomic<State> task_state{State::Unknown};  	virtual int runInner() { return 0; };  	virtual bool dirtyInner() { return false; } @@ -178,6 +178,13 @@ int TaskCC::runInner()  	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"); @@ -117,7 +117,16 @@ int TaskLD::runInner()  	for(const auto& depFile : depFiles)  	{ -		args.push_back(depFile.string()); +		if(depFile.extension() == ".so") +		{ +			args.push_back(std::string("-L") + settings.builddir); +			auto lib = depFile.stem().string().substr(3); // strip 'lib' prefix +			args.push_back(std::string("-l") + lib); +		} +		else if(depFile.extension() == ".a") +		{ +			args.push_back(depFile.string()); +		}  	}  	for(const auto& flag : config.ldflags) diff --git a/task_so.cc b/task_so.cc new file mode 100644 index 0000000..afe5c32 --- /dev/null +++ b/task_so.cc @@ -0,0 +1,198 @@ +#include "task_so.h" + +#include <iostream> +#include <fstream> + +#include "libcppbuild.h" +#include "settings.h" +#include "execute.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> addPrefix(const std::vector<std::string>& lst, +                                   const Settings& settings) +{ +	std::vector<std::string> out; +	for(const auto& item : lst) +	{ +		std::filesystem::path file = settings.builddir; +		file /= item; +		out.push_back(file.string()); +	} +	return out; +} +} // namespace :: + +TaskSO::TaskSO(const BuildConfiguration& config, +               const Settings& settings, +               const std::string& target, +               const std::vector<std::string>& objects) +	: Task(addPrefix(config.depends, settings)) +	, config(config) +	, settings(settings) +{ +	targetFile = settings.builddir; +	targetFile /= target; +	for(const auto& object : objects) +	{ +		std::filesystem::path objectFile = object; +		objectFiles.push_back(objectFile); +		dependsStr.push_back(objectFile); +	} + +	for(const auto& dep : config.depends) +	{ +		std::filesystem::path depFile = settings.builddir; +		depFile /= dep; +		depFiles.push_back(depFile); +	} + +	flagsFile = settings.builddir / targetFile.stem(); +	flagsFile += ".flags"; +} + +bool TaskSO::dirtyInner() +{ +	if(!std::filesystem::exists(targetFile)) +	{ +		return true; +	} + +	if(!std::filesystem::exists(flagsFile)) +	{ +		return true; +	} + +	for(const auto& objectFile : objectFiles) +	{ +		if(std::filesystem::last_write_time(targetFile) <= +		   std::filesystem::last_write_time(objectFile)) +		{ +			return true; +		} +	} + +	{ +		auto lastFlags = readFile(flagsFile); +		if(flagsString() != lastFlags) +		{ +			//std::cout << "The compiler flags changed\n"; +			return true; +		} +	} + +	return false; +} + +int TaskSO::runInner() +{ +	std::string objectlist; +	for(const auto& objectFile : objectFiles) +	{ +		if(!objectlist.empty()) +		{ +			objectlist += " "; +		} +		objectlist += std::string(objectFile); +	} + +	std::vector<std::string> args; + +	args.push_back("-fPIC"); +	args.push_back("-shared"); + +	args.push_back("-o"); +	args.push_back(std::string(targetFile)); + +	for(const auto& objectFile : objectFiles) +	{ +		args.push_back(std::string(objectFile)); +	} + +	for(const auto& depFile : depFiles) +	{ +		args.push_back(depFile.string()); +	} + +	for(const auto& flag : config.ldflags) +	{ +		args.push_back(flag); +	} + +	{ // Write flags to file. +		std::ofstream flagsStream(flagsFile); +		flagsStream << flagsString(); +	} + +	if(settings.verbose == 0) +	{ +		std::cout << "LD => " << targetFile.string() << "\n"; +	} + +	return execute("/usr/bin/g++", args, settings.verbose > 0); +} + +int TaskSO::clean() +{ +	if(std::filesystem::exists(targetFile)) +	{ +		std::cout << "Removing " << std::string(targetFile) << "\n"; +		std::filesystem::remove(targetFile); +	} + +	if(std::filesystem::exists(flagsFile)) +	{ +		std::cout << "Removing " << std::string(flagsFile) << "\n"; +		std::filesystem::remove(flagsFile); +	} + +	return 0; +} + +std::vector<std::string> TaskSO::depends() const +{ +	std::vector<std::string> deps; +	for(const auto& objectFile : objectFiles) +	{ +		deps.push_back(objectFile.string()); +	} + +	for(const auto& depFile : depFiles) +	{ +		deps.push_back(depFile.string()); +	} + +	return deps; +} + +std::string TaskSO::target() const +{ +	return std::string(targetFile); +} + +std::string TaskSO::flagsString() const +{ +	std::string flagsStr; +	for(const auto& flag : config.ldflags) +	{ +		if(!flagsStr.empty()) +		{ +			flagsStr += " "; +		} +		flagsStr += flag; +	} +	return flagsStr; +} diff --git a/task_so.h b/task_so.h new file mode 100644 index 0000000..864d108 --- /dev/null +++ b/task_so.h @@ -0,0 +1,42 @@ +// -*- c++ -*- +#pragma once + +#include "task.h" + +#include <vector> +#include <string> +#include <future> +#include <filesystem> + +struct BuildConfiguration; +struct Settings; + +class TaskSO +	: public Task +{ +public: +	TaskSO(const BuildConfiguration& config, +	       const Settings& settings, +	       const std::string& target, +	       const std::vector<std::string>& objects); + +	bool dirtyInner() override; + +	int runInner() override; +	int clean() override; + +	std::vector<std::string> depends() const override; + +	std::string target() const override; + +private: +	std::string flagsString() const; + +	std::vector<std::filesystem::path> objectFiles; +	std::vector<std::filesystem::path> depFiles; +	std::filesystem::path targetFile; +	std::filesystem::path flagsFile; + +	const BuildConfiguration& config; +	const Settings& settings; +};  | 
