diff options
| author | Bent Bisballe Nyeng <deva@aasimon.org> | 2026-02-23 21:03:11 +0100 |
|---|---|---|
| committer | Bent Bisballe Nyeng <deva@aasimon.org> | 2026-02-25 17:09:10 +0100 |
| commit | 5a3e0931e0e4ccd252c527b512ec1634d57489d8 (patch) | |
| tree | 6df26db1090d6edfe4430fb6dd9871465b56e32a | |
| parent | 2855b6e1172d5b544b150bf617b216691801f574 (diff) | |
WIP
| -rwxr-xr-x | bootstrap.sh | 2 | ||||
| -rw-r--r-- | ctor.cc | 10 | ||||
| -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 | ||||
| -rw-r--r-- | test/ctor.cc | 27 |
7 files changed, 232 insertions, 12 deletions
diff --git a/bootstrap.sh b/bootstrap.sh index 4dd57ae..9c573f7 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -7,6 +7,6 @@ set -e echo "Bootstrapping..." $CXX $LDFLAGS $CXXFLAGS -std=c++20 -Wall -O3 -Isrc -pthread src/bootstrap.cc ctor.cc -o ctor ./ctor -$CXX $LDFLAGS $CXXFLAGS -std=c++20 -Wall -O3 -Isrc -pthread ctor.cc test/ctor.cc -L$BUILDDIR -lctor -o ctor +$CXX $LDFLAGS $CXXFLAGS -std=c++20 -Wall -O3 -Isrc -pthread ctor.cc test/ctor.cc -L$BUILDDIR -lctor -larchive -o ctor ./ctor configure --ctor-includedir=src --ctor-libdir=$BUILDDIR --build-dir=$BUILDDIR echo "Done. Now run ./ctor to (re)build." @@ -10,6 +10,7 @@ ctor::build_configurations ctorConfigs(const ctor::settings& settings) return { { + ctor::project{"libctor", {1,0,0, "rc1"}}, ctor::output_system::build, ctor::target("libctor.a"), ctor::sources{ @@ -66,6 +67,15 @@ ctor::build_configurations ctorConfigs(const ctor::settings& settings) "-Isrc", "-fexceptions", }, + ctor::ld_flags{ + "-larchive", + }, + ctor::extra_dist{ + "LICENSE", + "README.md", + "src/bootstrap.cc", + "bootstrap.sh", + } } }; } 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); diff --git a/test/ctor.cc b/test/ctor.cc index 6a86dc7..b18e3e7 100644 --- a/test/ctor.cc +++ b/test/ctor.cc @@ -31,7 +31,7 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) ctor::sources{ "generated_sources_test.cc", "testmain.cc", - "../configuration.cc", + {"../configuration.cc", ctor::nodist{}} }, ctor::depends({"libctor_nomain.a"}), ctor::cxx_flags{ @@ -90,6 +90,15 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) "-DOUTPUT=\"deps\"", "-fexceptions", }, + ctor::extra_dist{ + "deps_test_data/empty.d", + "deps_test_data/missing_colon.d", + "deps_test_data/multiline.d", + "deps_test_data/no_deps.d", + "deps_test_data/no_newline.d", + "deps_test_data/spaces.d", + "deps_test_data/trivial.d", + }, }, { ctor::target_type::unit_test, @@ -147,7 +156,7 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) ctor::sources{ "cycle_test.cc", "testmain.cc", - "../configuration.cc", + {"../configuration.cc", ctor::nodist{}} }, ctor::depends({"libctor_nomain.a"}), ctor::cxx_flags{ @@ -165,7 +174,7 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) ctor::sources{ "source_type_test.cc", "testmain.cc", - "../configuration.cc", + {"../configuration.cc", ctor::nodist{}} }, ctor::depends({"libctor_nomain.a"}), ctor::cxx_flags{ @@ -183,7 +192,7 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) ctor::sources{ "tools_test.cc", "testmain.cc", - "../configuration.cc", + {"../configuration.cc", ctor::nodist{}} }, ctor::depends({"libctor_nomain.a"}), ctor::cxx_flags{ @@ -218,6 +227,7 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) ctor::headers{ "paths.h", "tmpfile.h", + "uunit/uunit.h", }, ctor::cxx_flags{ "-std=c++20", "-O3", "-Wall", @@ -225,6 +235,15 @@ ctor::build_configurations ctorTestConfigs(const ctor::settings& settings) "-fexceptions", }, ctor::ld_flags{ "-pthread" }, + ctor::extra_dist{ + "uunit/README", + "uunit/CC0-1.0", + "uunit/uunit.cc", + "uunit/examples/ExampleTest.cc", + "uunit/examples/Makefile", + "uunit/examples/getbaud.cc", + "uunit/examples/getbaud.h", + }, }, }; } |
