summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore3
-rw-r--r--Makefile9
-rw-r--r--libcppbuild.cc176
-rw-r--r--libcppbuild.h3
-rw-r--r--settings.h7
-rw-r--r--src/bar.obin2848 -> 0 bytes
-rw-r--r--task.cc199
-rw-r--r--task.h32
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
diff --git a/Makefile b/Makefile
index d5beb15..2462d3e 100644
--- a/Makefile
+++ b/Makefile
@@ -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.o
deleted file mode 100644
index 37903db..0000000
--- a/src/bar.o
+++ /dev/null
Binary files differ
diff --git a/task.cc b/task.cc
new file mode 100644
index 0000000..0b4240f
--- /dev/null
+++ b/task.cc
@@ -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 {};
+}
diff --git a/task.h b/task.h
new file mode 100644
index 0000000..d788645
--- /dev/null
+++ b/task.h
@@ -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;
+};