summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ctor.cc3
-rw-r--r--src/argparser.h10
-rw-r--r--src/bootstrap.cc7
-rw-r--r--src/configure.cc113
-rw-r--r--src/ctor.h52
-rw-r--r--src/libctor.cc114
-rw-r--r--src/util.cc10
7 files changed, 292 insertions, 17 deletions
diff --git a/ctor.cc b/ctor.cc
index f485309..cab0484 100644
--- a/ctor.cc
+++ b/ctor.cc
@@ -13,6 +13,7 @@ ctor::build_configurations ctorConfigs(const ctor::settings& settings)
ctor::project{"libctor", {1,0,0, "rc1"}},
ctor::output_system::build,
ctor::target("libctor.a"),
+ ctor::install{},
ctor::sources{
"src/build.cc",
"src/configure.cc",
@@ -37,7 +38,7 @@ ctor::build_configurations ctorConfigs(const ctor::settings& settings)
"src/argparser.h",
"src/build.h",
"src/configure.h",
- "src/ctor.h",
+ {"src/ctor.h", ctor::install{}},
"src/deps.h",
"src/execute.h",
"src/externals.h",
diff --git a/src/argparser.h b/src/argparser.h
index c5337e0..8f1ef39 100644
--- a/src/argparser.h
+++ b/src/argparser.h
@@ -237,6 +237,11 @@ public:
options.emplace_back(Opt<noarg>{shortopt, longopt, cb, help});
}
+ void add(const std::string& caption)
+ {
+ options.emplace_back(Opt<noarg>{{}, {}, {}, caption});
+ }
+
void set_pos_cb(std::function<int(std::string_view)> cb)
{
pos_cb = cb;
@@ -270,6 +275,11 @@ public:
using T = std::decay_t<decltype(opt)>;
if constexpr (std::is_same_v<T, Opt<noarg>>)
{
+ if(opt.longopt.empty())
+ {
+ std::cout << "\n" << opt.help << ":\n";
+ return;
+ }
}
else if constexpr (std::is_same_v<T, Opt<int>>)
{
diff --git a/src/bootstrap.cc b/src/bootstrap.cc
index 1ab4f31..4174edc 100644
--- a/src/bootstrap.cc
+++ b/src/bootstrap.cc
@@ -116,12 +116,15 @@ int main(int argc, char* argv[])
}
ctor::settings settings{};
-
const auto& c = ctor::get_configuration();
settings.builddir = c.get(ctor::cfg::builddir, settings.builddir);
settings.parallel_processes =
std::max(1u, std::thread::hardware_concurrency() * 2 - 1);
- settings.verbose = 1;
+ auto V = std::getenv("V");
+ if(V && std::string(V) == "1")
+ {
+ settings.verbose = 1;
+ }
auto all_tasks = getTasks(settings, {}, false);
for(auto task : all_tasks)
{
diff --git a/src/configure.cc b/src/configure.cc
index 5ba87c3..3a4abd4 100644
--- a/src/configure.cc
+++ b/src/configure.cc
@@ -286,6 +286,39 @@ int regenerateCache(ctor::settings& settings,
std::string ctor_libdir;
std::string builddir;
+ // Installation directories:
+ std::string prefix = "/usr/local";
+ std::string exec_prefix;//install architecture-dependent files in EPREFIX
+
+ // Fine tuning of the installation directories:
+ std::string bindir;// user executables [EPREFIX/bin]
+ std::string sbindir;// system admin executables [EPREFIX/sbin]
+ std::string libexecdir;// program executables [EPREFIX/libexec]
+ std::string sysconfdir;// read-only single-machine data [PREFIX/etc]
+ std::string sharedstatedir;// modifiable architecture-independent data [PREFIX/com]
+ std::string localstatedir;// modifiable single-machine data [PREFIX/var]
+ std::string runstatedir;// modifiable per-process data [LOCALSTATEDIR/run]
+ // object code libraries [EPREFIX/lib]
+ std::string libdir;
+ // C header files [PREFIX/include]
+ std::string includedir;
+ std::string oldincludedir;//C header files for non-gcc [/usr/include]
+ std::string datarootdir;// read-only arch.-independent data root [PREFIX/share]
+ std::string datadir;// read-only architecture-independent data [DATAROOTDIR]
+ std::string infodir;// info documentation [DATAROOTDIR/info]
+ std::string localedir;// locale-dependent data [DATAROOTDIR/locale]
+ std::string mandir;// man documentation [DATAROOTDIR/man]
+ std::string docdir;// documentation root [DATAROOTDIR/doc/drumgizmo]
+ std::string htmldir;// html documentation [DOCDIR]
+ std::string dvidir;// dvi documentation [DOCDIR]
+ std::string pdfdir;// pdf documentation [DOCDIR]
+ std::string psdir;// ps documentation [DOCDIR]
+
+ //Program names:
+ std::string program_prefix;// prepend PREFIX to installed program names
+ std::string program_suffix;// append SUFFIX to installed program names
+ std::string program_transform_name;//run sed PROGRAM on installed program names
+
opt.add('b', "--build-dir",
std::function([&](std::string arg)
{
@@ -384,6 +417,75 @@ int regenerateCache(ctor::settings& settings,
}),
"Set path to ctor library file, used for re-compiling.");
+ opt.add('h', "--help",
+ std::function([&]() -> int
+ {
+ std::cout << "Configure how to build with " << name << "\n";
+ std::cout << "Usage: " << name << " configure [options]\n\n";
+ std::cout << "Options:\n";
+ opt.help();
+ exit(0);
+ }),
+ "Print this help text.");
+/*
+Installation directories:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [/usr/local]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [PREFIX]
+
+By default, `make install' will install all the files in
+`/usr/local/bin', `/usr/local/lib' etc. You can specify
+an installation prefix other than `/usr/local' using `--prefix',
+for instance `--prefix=$HOME'.
+
+For better control, use the options below.
+
+Fine tuning of the installation directories:
+ --bindir=DIR user executables [EPREFIX/bin]
+ --sbindir=DIR system admin executables [EPREFIX/sbin]
+ --libexecdir=DIR program executables [EPREFIX/libexec]
+ --sysconfdir=DIR read-only single-machine data [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data [PREFIX/var]
+ --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run]
+ --libdir=DIR object code libraries [EPREFIX/lib]
+ --includedir=DIR C header files [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc [/usr/include]
+ --datarootdir=DIR read-only arch.-independent data root [PREFIX/share]
+ --datadir=DIR read-only architecture-independent data [DATAROOTDIR]
+ --infodir=DIR info documentation [DATAROOTDIR/info]
+ --localedir=DIR locale-dependent data [DATAROOTDIR/locale]
+ --mandir=DIR man documentation [DATAROOTDIR/man]
+ --docdir=DIR documentation root [DATAROOTDIR/doc/drumgizmo]
+ --htmldir=DIR html documentation [DOCDIR]
+ --dvidir=DIR dvi documentation [DOCDIR]
+ --pdfdir=DIR pdf documentation [DOCDIR]
+ --psdir=DIR ps documentation [DOCDIR]
+
+Program names:
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM run sed PROGRAM on installed program names
+ */
+ opt.add("Installation directories");
+
+ opt.add({}, "--prefix",
+ std::function([&](std::string arg)
+ {
+ prefix = arg;
+ return 0;
+ }),
+ "Install architecture-independent files in <str> (" + prefix + ").");
+
+// opt.add({}, "--exec-prefix",
+// std::function([&](std::string arg)
+// {
+// exec_prefix = arg;
+// return 0;
+// }),
+// "Install architecture-dependent files in <str> (" + prefix + ").");
+
// Resolv externals
ctor::external_configurations externalConfigs;
const auto& externalConfigFiles = getExternalConfigFileList();
@@ -432,17 +534,6 @@ int regenerateCache(ctor::settings& settings,
}
- opt.add('h', "--help",
- std::function([&]() -> int
- {
- std::cout << "Configure how to build with " << name << "\n";
- std::cout << "Usage: " << name << " configure [options]\n\n";
- std::cout << "Options:\n";
- opt.help();
- exit(0);
- }),
- "Print this help text.");
-
opt.set_err_cb(
[&](arg::error err, std::string_view arg)
{
diff --git a/src/ctor.h b/src/ctor.h
index 665ab75..9c00225 100644
--- a/src/ctor.h
+++ b/src/ctor.h
@@ -80,6 +80,48 @@ struct nodist
bool value{true};
};
+enum class install_type
+{
+ automatic, // Deduced from target-type
+ program,
+ library,
+ header,
+ // man, ...
+};
+
+/// Indicate that this target should be part of install target
+struct install
+{
+ template <class ... Args>
+ requires ((
+ std::is_same_v<Args, bool> ||
+ std::is_same_v<Args, ctor::install_type> ||
+ std::is_convertible_v<Args, std::string_view>
+ ) && ...)
+ constexpr install(Args && ... arg)
+ {
+ do_install = true;
+ ([&]
+ {
+ if constexpr(std::is_same_v<Args, bool>)
+ {
+ do_install = arg;
+ }
+ else if constexpr(std::is_same_v<Args, ctor::install_type>)
+ {
+ type = arg;
+ }
+ else if constexpr(std::is_convertible_v<Args, std::string_view>)
+ {
+ path = arg;
+ }
+ }(), ...);
+ }
+ ctor::install_type type{ctor::install_type::automatic};
+ std::string path; // Default: Install dir for type (bin, lib, include, ...)
+ bool do_install{false};
+};
+
struct source
{
template <class ... Args>
@@ -137,7 +179,8 @@ struct header
template <class ... Args>
requires ((
std::is_convertible_v<Args, std::string_view> ||
- std::is_same_v<Args, ctor::nodist>
+ std::is_same_v<Args, ctor::nodist> ||
+ std::is_same_v<Args, ctor::install>
) && ...)
constexpr header(Args && ... arg)
{
@@ -156,6 +199,7 @@ struct header
std::string file;
bool nodist{false};
+ ctor::install install{false};
};
using headers = std::vector<ctor::header>;
@@ -448,6 +492,7 @@ struct build_configuration
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::install> ||
std::is_same_v<Args, ctor::externals> ||
std::is_convertible_v<Args, ctor::GeneratorOneToOne> ||
std::is_convertible_v<Args, ctor::GeneratorManyToOne> ||
@@ -497,6 +542,10 @@ struct build_configuration
{
depends = arg.depends;
}
+ else if constexpr(std::is_same_v<Args, ctor::install>)
+ {
+ install = arg;
+ }
else if constexpr(std::is_same_v<Args, ctor::externals>)
{
externals = arg.externals;
@@ -545,6 +594,7 @@ struct build_configuration
std::vector<std::string> externals; // externals used by this configuration
ctor::GeneratorOneToOne function_one_to_one;
ctor::GeneratorManyToOne function_many_to_one;
+ ctor::install install{false};
};
using build_configurations = std::vector<build_configuration>;
diff --git a/src/libctor.cc b/src/libctor.cc
index 6e6bcaf..230662a 100644
--- a/src/libctor.cc
+++ b/src/libctor.cc
@@ -66,6 +66,7 @@ int main(int argc, char* argv[])
bool list_targets{false};
bool no_relaunch{false}; // true means no re-launch after rebuild.
bool run_unittests{false};
+ bool install{false};
std::vector<std::string> arguments;
arg::Parser<int, std::string> opt(argc, argv);
opt.set_pos_cb(
@@ -504,7 +505,11 @@ Options:
archive_write_close(a); // Note 4
archive_write_free(a); // Note 5
}
- return 0;
+ }
+ else if(arg == "install")
+ {
+ install = true;
+ build_all = true;
}
else
{
@@ -562,7 +567,112 @@ Options:
if(run_unittests)
{
- return runUnitTests(all_tasks, settings);
+ auto ret = runUnitTests(all_tasks, settings);
+ if(ret != 0)
+ {
+ return ret;
+ }
+ }
+
+ if(install)
+ {
+ auto destdir_env = std::getenv("DESTDIR");
+ if(!destdir_env)
+ {
+ std::cerr << "No DESTDIR provided!\n";
+ return 1;
+ }
+ std::filesystem::path destdir = destdir_env;
+ if(!destdir.is_absolute())
+ {
+ std::cerr << "DESTDIR must be absolute!\n";
+ return 1;
+ }
+ std::cout << "Installing in DESTDIR: " << destdir.string() << "\n";
+ std::string prefix = "/usr";
+ for(const auto& task : all_tasks)
+ {
+ auto install_target = task->buildConfig().install;
+ if(!task->derived() && install_target.do_install)
+ {
+ std::string target_dir{};
+ if(!install_target.path.empty())
+ {
+ target_dir = install_target.path;
+ }
+ else
+ {
+ switch(task->targetType())
+ {
+ case ctor::target_type::unit_test:
+ case ctor::target_type::unit_test_library:
+ case ctor::target_type::object:
+ case ctor::target_type::function:
+ case ctor::target_type::automatic:
+ case ctor::target_type::unknown:
+ // Ignore
+ continue;
+ break;
+ case ctor::target_type::executable:
+ target_dir = "bin";
+ break;
+ case ctor::target_type::shared_library:
+ case ctor::target_type::static_library:
+ case ctor::target_type::module:
+ target_dir = "lib";
+ break;
+ }
+ }
+ std::filesystem::path target;
+ target = prefix;
+ target /= target_dir;
+ target /= task->target();
+ if(destdir_env)
+ {
+ if(target.is_absolute())
+ {
+ target = destdir / target.relative_path();
+ }
+ else
+ {
+ target = destdir / target;
+ }
+ }
+ std::cout << "Bin install " << task->target() <<
+ " -> " << target.string() << "\n";
+ }
+ }
+
+ auto& targets = getTargets(settings);
+ for(const auto& target : targets)
+ {
+ for(const auto& header : target.config.headers)
+ {
+ if(header.install.do_install)
+ {
+ std::filesystem::path target_file = prefix;
+ target_file /= "include";
+ if(!header.install.path.empty())
+ {
+ target_file /= header.install.path;
+ }
+ target_file /= std::filesystem::path(header.file).filename();
+ if(destdir_env)
+ {
+ if(target_file.is_absolute())
+ {
+ target_file = destdir / target_file.relative_path();
+ }
+ else
+ {
+ target_file = destdir / target_file;
+ }
+ }
+ std::cout << "Include/header install " << header.file <<
+ " -> " << target_file.string() << "\n";
+ }
+ }
+ }
}
return 0;
diff --git a/src/util.cc b/src/util.cc
index 7ca9c11..0655dfa 100644
--- a/src/util.cc
+++ b/src/util.cc
@@ -71,6 +71,16 @@ ctor::language languageFromExtension(const std::filesystem::path& file)
return ctor::language::assembler;
}
+// if(ext == ".h" ||
+// ext == ".hh" ||
+// ext == ".hpp" ||
+// ext == ".hxx" ||
+// ext == ".tpp" ||
+// ext == ".ipp")
+// {
+// return ctor::language::header;
+// }
+
std::cerr << "Could not deduce language from " << file.string() << "\n";
exit(1);
return {};