diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/bootstrap.cc | 2 | ||||
| -rw-r--r-- | src/ctor.h | 78 | ||||
| -rw-r--r-- | src/libctor.cc | 124 | ||||
| -rw-r--r-- | src/rebuild.cc | 1 |
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) { @@ -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); |
