summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--Makefile.dg4
-rw-r--r--cppbuild.cc77
-rw-r--r--libcppbuild.cc76
-rw-r--r--task.cc16
-rw-r--r--task.h13
-rw-r--r--task_cc.cc7
-rw-r--r--task_ld.cc11
-rw-r--r--task_so.cc198
-rw-r--r--task_so.h42
10 files changed, 397 insertions, 49 deletions
diff --git a/Makefile b/Makefile
index 335e5aa..af29818 100644
--- a/Makefile
+++ b/Makefile
@@ -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";
diff --git a/task.cc b/task.cc
index d539b50..10e9368 100644
--- a/task.cc
+++ b/task.cc
@@ -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();
}
diff --git a/task.h b/task.h
index 2dd05e3..00b01d2 100644
--- a/task.h
+++ b/task.h
@@ -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; }
diff --git a/task_cc.cc b/task_cc.cc
index 74654aa..4340f7b 100644
--- a/task_cc.cc
+++ b/task_cc.cc
@@ -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");
diff --git a/task_ld.cc b/task_ld.cc
index fcde6d4..db0f955 100644
--- a/task_ld.cc
+++ b/task_ld.cc
@@ -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;
+};