aboutsummaryrefslogtreecommitdiff
path: root/bpkg/system-package-manager-debian.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'bpkg/system-package-manager-debian.cxx')
-rw-r--r--bpkg/system-package-manager-debian.cxx219
1 files changed, 188 insertions, 31 deletions
diff --git a/bpkg/system-package-manager-debian.cxx b/bpkg/system-package-manager-debian.cxx
index 15825ef..a3f2721 100644
--- a/bpkg/system-package-manager-debian.cxx
+++ b/bpkg/system-package-manager-debian.cxx
@@ -1845,7 +1845,11 @@ namespace bpkg
// Specifially, we can override the install target to invoke the build
// system and install all the packages directly from their bpkg locations.
//
- void system_package_manager_debian::
+ // Note that the -dbgsym packages are generated by default and all we need
+ // to do from our side is to compile with debug information (-g), failed
+ // which we get a warning from debhelper.
+ //
+ paths system_package_manager_debian::
generate (const packages& pkgs,
const packages& deps,
const strings& vars,
@@ -1855,6 +1859,8 @@ namespace bpkg
const dir_path& out,
optional<recursive_mode> recur)
{
+ tracer trace ("system_package_manager_debian::generate");
+
assert (!langs.empty ()); // Should be effective.
const shared_ptr<selected_package>& sp (pkgs.front ().selected);
@@ -1935,6 +1941,7 @@ namespace bpkg
sdeps.push_back (move (s));
}
+ if (verb >= 3)
{
auto print_status = [] (diag_record& dr, const package_status& s)
{
@@ -1946,16 +1953,24 @@ namespace bpkg
<< ' ' << s.system_version;
};
- diag_record dr (text);
- print_status (dr, st);
+ {
+ diag_record dr (trace);
+ dr << "package: ";
+ print_status (dr, st);
+ }
for (const package_status& st: sdeps)
{
- dr << "\n ";
+ diag_record dr (trace);
+ dr << "dependency: ";
print_status (dr, st);
}
}
+ if (!st.dbg.empty ())
+ fail << "generation of obsolete manual -dbg packages not supported" <<
+ info << "use automatic -dbgsym packages instead";
+
// We override every config.install.* variable in order not to pick
// anything configured. Note that we add some more in the rules file
// below.
@@ -2023,12 +2038,13 @@ namespace bpkg
for (const string& v: vars)
config.push_back (v);
- // Note that we have to use global install scope for the auto recursive
- // mode since things can be spread over multiple linked configurations.
+ // Note that we can use weak install scope for the auto recursive mode
+ // since we know dependencies cannot be spread over multiple linked
+ // configurations.
//
string scope (!recur || *recur == recursive_mode::full
? "project"
- : "global");
+ : "weak");
// Get the map of files that will end up in the binary packages.
//
@@ -2040,10 +2056,19 @@ namespace bpkg
if (ies.empty ())
fail << "specified package(s) do not install any files";
-#if 0
- for (const auto& p: ies)
- text << p.first;
-#endif
+ if (verb >= 4)
+ {
+ for (const auto& p: ies)
+ {
+ diag_record dr (trace);
+ dr << "installed entry: " << p.first;
+
+ if (p.second.target != nullptr)
+ dr << " -> " << p.second.target->first; // Symlink.
+ else
+ dr << " " << p.second.mode;
+ }
+ }
// Start assembling the package "source" directory.
//
@@ -2080,7 +2105,7 @@ namespace bpkg
// Note that we try to do a reasonably thorough job (e.g., filling in
// sections, etc) with the view that this can be used as a starting point
// for manual packaging (and perhaps we could add a mode for this in the
- // future).
+ // future, call it "starting point" mode).
//
// Also note that this file supports variable substitutions (for example,
// ${binary:Version}) as described in deb-substvars(5). While we could do
@@ -2209,6 +2234,12 @@ namespace bpkg
if (!depends.empty ())
depends += ", ";
+ // Note that the constraints will include build metadata (e.g.,
+ // ~debian10). While it may be tempting to strip it, we cannot since
+ // the order is inverse. We could just make it empty `~`, though
+ // that will look a bit strange. But keeping it shouldn't cause any
+ // issues.
+ //
depends += st.main + " (>= " + st.system_version + ')';
}
@@ -2314,6 +2345,8 @@ namespace bpkg
<< " This package contains the documentation." << '\n';
}
+ // Keep this in case we want to support it in the "starting point" mode.
+ //
if (!st.dbg.empty ())
{
string depends (st.main + " (= ${binary:Version})");
@@ -2410,8 +2443,6 @@ namespace bpkg
//
// <day-of-week>, <dd> <month> <yyyy> <hh>:<mm>:<ss> +<zzzz>
//
- // @@ We may need to "complete" the maintainer if it's just an email.
- //
timestamp now (system_clock::now ());
os << " -- " << maintainer << " ";
std::locale l (os.imbue (std::locale ("C")));
@@ -2441,7 +2472,7 @@ namespace bpkg
// Note also that there is currently no way for us to get accurate
// copyright information.
//
- // @@ Also, strictly speaking, in the recursive mode, we should collect
+ // @@ TODO: Strictly speaking, in the recursive mode, we should collect
// licenses of all the dependencies we are bundling.
//
path copyr (deb / "copyright");
@@ -2542,6 +2573,10 @@ namespace bpkg
path rules (deb / "rules");
try
{
+ bool lang_c (lang ("c"));
+ bool lang_cxx (lang ("c++"));
+ bool lang_cc (lang ("cc"));
+
// See fdopen() for details (umask, etc).
//
permissions ps (permissions::ru | permissions::wu | permissions::xu |
@@ -2557,6 +2592,11 @@ namespace bpkg
// See debhelper(7) for details on these.
//
+ // Note that there is also the DEB_BUILD_OPTIONS=terse option. Perhaps
+ // for the "starting point" mode we should base DH_* values as well as
+ // the build system verbosity below on that value. See debian/rules in
+ // upstream mariadb for what looks like a sensible setup.
+ //
if (verb == 0)
os << "export DH_QUIET := 1\n"
<< '\n';
@@ -2568,15 +2608,32 @@ namespace bpkg
os << "export DH_VERBOSE := 1\n"
<< '\n';
- // We could have instead included architecture.mk but let's avoid an
- // extra dependency (most packages that we sampled do it directly).
+ // We could have instead called dpkg-architecture directly but seeing
+ // that we are also include buildflags.mk below, might as well use
+ // architecture.mk (in the packages that we sampled you see both
+ // approaches).
//
- // @@ Add --debian-no-multiarch? Will get quite messy (see .install
- // files).
- //
- os << "export DEB_HOST_MULTIARCH ?= $(shell dpkg-architecture -qDEB_HOST_MULTIARCH)\n"
+ os << "# DEB_HOST_* (DEB_HOST_MULTIARCH, etc)"
+ << "#" << '\n'
+ << "include /usr/share/dpkg/architecture.mk" << '\n'
<< '\n';
+ if (ops_->debian_buildflags () != "ignore")
+ {
+ // While we could have called dpkg-buildflags directly, including
+ // buildflags.mk instead appears to be the standard practice.
+ //
+ // Note that theses flags are not limited to C-based languages (for
+ // example, they also cover Assembler, Fortran, and potentially others
+ // in the future).
+ //
+ os << "# *FLAGS (CFLAGS, CXXFLAGS, etc)"
+ << "#" << '\n'
+ << "export DEB_BUILD_MAINT_OPTIONS := hardening=+all" << '\n'
+ << "include /usr/share/dpkg/buildflags.mk" << '\n'
+ << '\n';
+ }
+
// The debian/tmp/ subdirectory appears to be the canonical destination
// directory (see dh_auto_install(1) for details).
//
@@ -2589,14 +2646,14 @@ namespace bpkg
// See --jobs documentation in dpkg-buildpackage(1) for details on
// parallel=N.
//
- // @@ Need to map verbosity! Also looks like progress is disabled
- // (probably because stderr redirected to pipe). @@ No, there is
- // progress. Maybe just keep, doesn't seem harmful. Or pass ours.
- //
// Note: should be consistent with the invocation in installed_entries()
// above.
//
+ cstrings verb_args; string verb_arg;
+ map_verb_b (*ops_, verb_b::normal, verb_args, verb_arg);
+
os << "b := " << search_b (*ops_).effect_string ();
+ for (const char* o: verb_args) os << ' ' << o;
for (const string& o: ops_->build_option ()) os << ' ' << o;
os << '\n'
<< '\n'
@@ -2622,10 +2679,63 @@ namespace bpkg
// If this is a C-based language, add rpath for private installation.
//
- if (priv && (lang ("c") || lang ("c++") || lang ("cc")))
+ if (priv && (lang_c || lang_cxx || lang_cc))
os << "config += config.bin.rpath='/usr/lib/$(DEB_HOST_MULTIARCH)/"
<< pn << "/'" << '\n';
+ // Add build flags.
+ //
+ if (ops_->debian_buildflags () != "ignore")
+ {
+ const string& m (ops_->debian_buildflags ());
+
+ string o (m == "assign" ? "=" :
+ m == "append" ? "+=" :
+ m == "prepend" ? "=+" : "");
+
+ if (o.empty ())
+ fail << "unknown --debian-buildflags option value '" << m << "'";
+
+ // Note that config.cc.* doesn't play well with the append/prepend
+ // modes because the orders are:
+ //
+ // x.poptions cc.poptions
+ // cc.coptions x.coptions
+ // cc.loptions x.loptions
+ //
+ // Oh, well, hopefully it will be close enough for most cases.
+ //
+ // Note also that there are compiler mode options that are not
+ // overridden.
+ //
+ if (o == "=" && (lang_c || lang_cxx || lang_cc))
+ {
+ os << "config += config.cc.poptions='[null]'" << '\n'
+ << "config += config.cc.coptions='[null]'" << '\n'
+ << "config += config.cc.loptions='[null]'" << '\n';
+ }
+
+ if (lang_c || lang_cc)
+ {
+ // @@ TODO: OBJCFLAGS (we currently don't have separate options).
+
+ os << "config += config.c.poptions" << o << "'$(CPPFLAGS)'" << '\n'
+ << "config += config.c.coptions" << o << "'$(CFLAGS)'" << '\n'
+ << "config += config.c.loptions" << o << "'$(LDFLAGS)'" << '\n';
+ }
+
+ if (lang_cxx || lang_cc)
+ {
+ // @@ TODO: OBJCXXFLAGS (we currently don't have separate options).
+
+ os << "config += config.cxx.poptions" << o << "'$(CPPFLAGS)'" << '\n'
+ << "config += config.cxx.coptions" << o << "'$(CXXFLAGS)'" << '\n'
+ << "config += config.cxx.loptions" << o << "'$(LDFLAGS)'" << '\n';
+ }
+
+ // @@ TODO: ASFLAGS (when we have assembler support).
+ }
+
// Keep last to allow user-specified configuration variables to override
// anything.
//
@@ -2987,11 +3097,9 @@ namespace bpkg
// Note that there doesn't seem to be any way to control its verbosity or
// progress.
//
- // @@ Buildinfo stuff is fuzzy. There is also debug symbols warnings.
- //
- // @@ Why does stuff keep recompiling on every run (e.g., byacc)? Running
- // the same commands from the command line does not trigger rebuild.
- // Could dpkg-buildpackage somehow forcing rebuild? Via environment?
+ // Note also that dpkg-buildpackage causes recompilation on every run by
+ // changing the SOURCE_DATE_EPOCH environment variable (which we track for
+ // changes since it affects GCC).
//
cstrings args {
"dpkg-buildpackage",
@@ -3011,6 +3119,21 @@ namespace bpkg
args.push_back (nullptr);
+ if (ops_->debian_prepare_only ())
+ {
+ if (verb >= 1)
+ {
+ diag_record dr (text);
+
+ dr << "prepared " << src <<
+ text << "command line: ";
+
+ print_process (dr, args);
+ }
+
+ return paths {};
+ }
+
try
{
process_path pp (process::path_search (args[0]));
@@ -3060,5 +3183,39 @@ namespace bpkg
{
rm_r (src);
}
+
+ // Collect and return the binary package paths.
+ //
+ paths r;
+ auto add = [&out, &r] (const string& n, bool opt = false)
+ {
+ path p (out / n);
+
+ if (exists (p))
+ r.push_back (move (p));
+ else if (!opt)
+ fail << "expected output file " << p << " does not exist";
+ };
+
+ // The resulting .deb file names have the <name>_<version>_<arch>.deb
+ // form. If the package is architecture-independent, then <arch> is the
+ // special `all` value.
+ //
+ const string& ver (st.system_version);
+
+ add (st.main + '_' + ver + '_' + arch + ".deb");
+ add (st.main + "-dbgsym_" + ver + '_' + arch + ".deb", true);
+ if (!st.dev.empty ()) add (st.dev + '_' + ver + '_' + arch + ".deb");
+ if (!st.doc.empty ()) add (st.doc + '_' + ver + "_all.deb");
+ if (!st.common.empty ()) add (st.common + '_' + ver + "_all.deb");
+
+ // Besides the binary packages (.deb) we also get the .buildinfo and
+ // .changes files, which could be useful. Note that their names are based
+ // on the source package name.
+ //
+ add (pn.string () + '_' + ver + '_' + arch + ".buildinfo");
+ add (pn.string () + '_' + ver + '_' + arch + ".changes");
+
+ return r;
}
}