summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap.cc2
-rw-r--r--src/ctor.h78
-rw-r--r--src/libctor.cc124
-rw-r--r--src/rebuild.cc1
4 files changed, 198 insertions, 7 deletions
diff --git a/src/bootstrap.cc b/src/bootstrap.cc
index 836504e..1ab4f31 100644
--- a/src/bootstrap.cc
+++ b/src/bootstrap.cc
@@ -121,7 +121,7 @@ int main(int argc, char* argv[])
settings.builddir = c.get(ctor::cfg::builddir, settings.builddir);
settings.parallel_processes =
std::max(1u, std::thread::hardware_concurrency() * 2 - 1);
- settings.verbose = 0;
+ settings.verbose = 1;
auto all_tasks = getTasks(settings, {}, false);
for(auto task : all_tasks)
{
diff --git a/src/ctor.h b/src/ctor.h
index 9320c3d..665ab75 100644
--- a/src/ctor.h
+++ b/src/ctor.h
@@ -75,6 +75,11 @@ enum class source_type
generated,
};
+struct nodist
+{
+ bool value{true};
+};
+
struct source
{
template <class ... Args>
@@ -83,7 +88,8 @@ struct source
std::is_same_v<Args, ctor::toolchain> ||
std::is_same_v<Args, ctor::language> ||
std::is_same_v<Args, ctor::source_type> ||
- std::is_same_v<Args, ctor::output_file>
+ std::is_same_v<Args, ctor::output_file> ||
+ std::is_same_v<Args, ctor::nodist>
) && ...)
constexpr source(Args && ... arg)
{
@@ -109,6 +115,10 @@ struct source
{
source_type = arg;
}
+ else if constexpr(std::is_same_v<Args, ctor::nodist>)
+ {
+ nodist = arg.value;
+ }
}(), ...);
}
@@ -117,6 +127,7 @@ struct source
ctor::language language{ctor::language::automatic};
std::string output{};
ctor::source_type source_type{ctor::source_type::regular};
+ bool nodist{false};
};
using sources = std::vector<ctor::source>;
@@ -125,7 +136,8 @@ struct header
{
template <class ... Args>
requires ((
- std::is_convertible_v<Args, std::string_view>
+ std::is_convertible_v<Args, std::string_view> ||
+ std::is_same_v<Args, ctor::nodist>
) && ...)
constexpr header(Args && ... arg)
{
@@ -135,19 +147,47 @@ struct header
{
file = arg;
}
- else if constexpr(std::is_same_v<Args, ctor::install>)
+ else if constexpr(std::is_same_v<Args, ctor::nodist>)
{
- install = arg;
+ nodist = arg.value;
}
}(), ...);
}
std::string file;
- ctor::install install;
+ bool nodist{false};
};
using headers = std::vector<ctor::header>;
+struct extra_dist_file
+{
+ template <class ... Args>
+ requires ((
+ std::is_convertible_v<Args, std::string_view> ||
+ std::is_same_v<Args, ctor::nodist>
+ ) && ...)
+ constexpr extra_dist_file(Args && ... arg)
+ {
+ ([&]
+ {
+ if constexpr(std::is_convertible_v<Args, std::string_view>)
+ {
+ file = arg;
+ }
+ else if constexpr(std::is_same_v<Args, ctor::nodist>)
+ {
+ nodist = arg.value;
+ }
+ }(), ...);
+ }
+
+ std::string file;
+ bool nodist{false};
+};
+
+using extra_dist = std::vector<ctor::extra_dist_file>;
+
enum class cxx_opt
{
// gcc/clang
@@ -381,16 +421,32 @@ struct externals
std::vector<std::string> externals;
};
+struct version
+{
+ int major;
+ int minor;
+ int patch;
+ std::string tweak{};
+};
+
+struct project
+{
+ std::string name;
+ ctor::version version;
+};
+
struct build_configuration
{
template <class ... Args>
requires ((
+ std::is_same_v<Args, ctor::project> ||
std::is_same_v<Args, ctor::name> ||
std::is_same_v<Args, ctor::target_type> ||
std::is_same_v<Args, ctor::output_system> ||
std::is_same_v<Args, ctor::target> ||
std::is_same_v<Args, ctor::sources> ||
std::is_same_v<Args, ctor::headers> ||
+ std::is_same_v<Args, ctor::extra_dist> ||
std::is_same_v<Args, ctor::depends> ||
std::is_same_v<Args, ctor::externals> ||
std::is_convertible_v<Args, ctor::GeneratorOneToOne> ||
@@ -405,7 +461,11 @@ struct build_configuration
{
([&]
{
- if constexpr(std::is_same_v<Args, ctor::name>)
+ if constexpr(std::is_same_v<Args, ctor::project>)
+ {
+ project = arg;
+ }
+ else if constexpr(std::is_same_v<Args, ctor::name>)
{
name = arg.name;
}
@@ -429,6 +489,10 @@ struct build_configuration
{
headers = arg;
}
+ else if constexpr(std::is_same_v<Args, ctor::extra_dist>)
+ {
+ extra_dist = arg;
+ }
else if constexpr(std::is_same_v<Args, ctor::depends>)
{
depends = arg.depends;
@@ -468,12 +532,14 @@ struct build_configuration
}(), ...);
}
+ ctor::project project{};
std::string name; // Name - used for referring in other configurations.
ctor::target_type type{ctor::target_type::automatic};
ctor::output_system system{ctor::output_system::build};
std::string target; // Output target file for this configuration
ctor::sources sources; // source list
ctor::headers headers; // header list
+ ctor::extra_dist extra_dist; // extra files to be added to dist
std::vector<std::string> depends; // internal target dependencies
ctor::flags flags;
std::vector<std::string> externals; // externals used by this configuration
diff --git a/src/libctor.cc b/src/libctor.cc
index 2685ec0..6e6bcaf 100644
--- a/src/libctor.cc
+++ b/src/libctor.cc
@@ -16,6 +16,7 @@
#include <fstream>
#include <cstdlib>
#include <span>
+#include <set>
#include "ctor.h"
#include "configure.h"
@@ -26,6 +27,13 @@
#include "argparser.h"
#include "util.h"
+extern "C" {
+#include <archive.h>
+#include <archive_entry.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+}
+
int main(int argc, char* argv[])
{
auto args = std::span(argv, static_cast<std::size_t>(argc));
@@ -382,6 +390,122 @@ Options:
return ret;
}
}
+ else if(arg == "dist")
+ {
+ ctor::project project{};
+ std::set<std::string> dist_files;
+ auto& targets = getTargets(settings);
+ for(const auto& target : targets)
+ {
+ if(!target.config.project.name.empty())
+ {
+ project = target.config.project;
+ }
+
+ for(const auto& source : target.config.sources)
+ {
+ if(source.nodist)
+ {
+ continue;
+ }
+ std::filesystem::path p = target.path;
+ p /= source.file;
+ dist_files.insert(p.lexically_normal().string());
+ }
+ for(const auto& header : target.config.headers)
+ {
+ if(header.nodist)
+ {
+ continue;
+ }
+ std::filesystem::path p = target.path;
+ p /= header.file;
+ dist_files.insert(p.lexically_normal().string());
+ }
+ for(const auto& extra_dist_file : target.config.extra_dist)
+ {
+ if(extra_dist_file.nodist)
+ {
+ continue;
+ }
+ std::filesystem::path p = target.path;
+ p /= extra_dist_file.file;
+ dist_files.insert(p.lexically_normal().string());
+ }
+ }
+
+ const auto& configFiles = getConfigFileList();
+ for(const auto& configFile : configFiles)
+ {
+ std::filesystem::path p = configFile.file;
+ dist_files.insert(p.lexically_normal().string());
+ }
+
+ const auto& externalConfigFiles = getExternalConfigFileList();
+ for(const auto& externalConfigFile : externalConfigFiles)
+ {
+ std::filesystem::path p = externalConfigFile.file;
+ dist_files.insert(p.lexically_normal().string());
+ }
+
+ if(project.name.empty())
+ {
+ std::cerr << "Missing ctor::project description."
+ " Cannot create dist-file.\n";
+ return 1;
+ }
+ std::string outname = project.name + "-" +
+ std::to_string(project.version.major) + "." +
+ std::to_string(project.version.minor) + "." +
+ std::to_string(project.version.patch);
+ if(!project.version.tweak.empty())
+ {
+ outname += "-" + project.version.tweak;
+ }
+ outname += ".tar.gz";
+ {
+ struct archive *a;
+ struct archive_entry *entry;
+ struct stat st;
+ char buff[8192];
+ ssize_t len;
+ int fd;
+
+ a = archive_write_new();
+ // Filters: https://man.archlinux.org/man/archive_write_filter.3.en
+ archive_write_add_filter_gzip(a);
+ archive_write_set_format_pax_restricted(a); // Note 1
+ archive_write_open_filename(a, outname.data());
+
+ for(const auto& dist_file : dist_files)
+ {
+ const char*filename = dist_file.data();
+ stat(filename, &st);
+ auto mode = st.st_mode & 0xfff;//0644
+ std::cout << dist_file << std::oct << mode << '\n';
+ entry = archive_entry_new(); // Note 2
+ archive_entry_set_pathname(entry, filename);
+ archive_entry_set_size(entry, st.st_size); // Note 3
+ archive_entry_set_mtime(entry, st.st_mtime, 0);
+ archive_entry_set_filetype(entry, AE_IFREG);
+ archive_entry_set_perm(entry, mode);
+ archive_write_header(a, entry);
+ fd = open(filename, O_RDONLY);
+ len = read(fd, buff, sizeof(buff));
+ while ( len > 0 )
+ {
+ archive_write_data(a, buff, len);
+ len = read(fd, buff, sizeof(buff));
+ }
+ close(fd);
+ archive_entry_free(entry);
+ }
+
+ archive_write_close(a); // Note 4
+ archive_write_free(a); // Note 5
+ }
+ return 0;
+ }
else
{
build_all = false;
diff --git a/src/rebuild.cc b/src/rebuild.cc
index d62e998..30ca98e 100644
--- a/src/rebuild.cc
+++ b/src/rebuild.cc
@@ -156,6 +156,7 @@ bool recompileCheck(const ctor::settings& global_settings, int argc, char* argv[
config.flags.ldflags.emplace_back(ctor::ld_opt::library_path,
c.get(ctor::cfg::ctor_libdir));
}
+ config.flags.ldflags.emplace_back(ctor::ld_opt::link, "archive");
config.flags.ldflags.emplace_back(ctor::ld_opt::link, "ctor");
config.flags.ldflags.emplace_back(ctor::ld_opt::threads);