From: Mikko Rasa Date: Thu, 30 Aug 2018 11:01:33 +0000 (+0300) Subject: Use -rpath (or -rpath-link) when linking X-Git-Url: http://git.tdb.fi/?p=builder.git;a=commitdiff_plain;h=fe305f49aae7b7dff4c6be6f7bb8d403ccf53768 Use -rpath (or -rpath-link) when linking It avoids the need to use LD_LIBRARY_PATH when running programs linked against custom libraries. The default build types have been amended so that debug builds use an absolute rpath. This allows them to be run from the source tree. Release builds use a relative rpath to make them more easily relocatable in the filesystem. --- diff --git a/builderrc b/builderrc index d84a15b..207c2d6 100644 --- a/builderrc +++ b/builderrc @@ -21,6 +21,7 @@ build_type "debug" define "DEBUG" "1"; warning_level 3; fatal_warnings true; + runtime_path_mode ABSOLUTE; }; }; @@ -33,6 +34,7 @@ build_type "optimized_debug" optimize 2; warning_level 3; fatal_warnings true; + runtime_path_mode ABSOLUTE; }; }; @@ -43,6 +45,7 @@ build_type "release" optimize 3; strip true; warning_level 1; + runtime_path_mode RELATIVE; }; }; diff --git a/source/buildinfo.cpp b/source/buildinfo.cpp index 114a368..e2df34c 100644 --- a/source/buildinfo.cpp +++ b/source/buildinfo.cpp @@ -28,6 +28,7 @@ void unique(list &l) BuildInfo::BuildInfo(): libmode(DYNAMIC), + rpath_mode(NO_RPATH), threads(false), debug(false), optimize(0), @@ -64,6 +65,7 @@ void BuildInfo::update_from(const BuildInfo &bi, UpdateLevel level) sysroot = bi.sysroot; local_incpath.insert(local_incpath.begin(), bi.local_incpath.begin(), bi.local_incpath.end()); libmode = bi.libmode; + rpath_mode = bi.rpath_mode; for(LibModeMap::const_iterator i=bi.libmodes.begin(); i!=bi.libmodes.end(); ++i) libmodes[i->first] = i->second; keep_symbols.insert(keep_symbols.end(), bi.keep_symbols.begin(), bi.keep_symbols.end()); @@ -95,6 +97,7 @@ BuildInfo::Loader::Loader(BuildInfo &bi): add("libmode", &Loader::libmode_for_lib); add("local_incpath", &Loader::local_incpath); add("optimize", &BuildInfo::optimize); + add("runtime_path_mode", &BuildInfo::rpath_mode); add("standard", &Loader::standard); add("strip", &BuildInfo::strip); add("sysroot", &Loader::sysroot); @@ -162,3 +165,16 @@ void operator>>(const LexicalConverter &conv, BuildInfo::LibraryMode &libmode) else throw lexical_error(format("Conversion of '%s' to LibraryMode", conv.get())); } + + +void operator>>(const LexicalConverter &conv, BuildInfo::RuntimePathMode &rpath_mode) +{ + if(conv.get()=="NONE") + rpath_mode = BuildInfo::NO_RPATH; + else if(conv.get()=="RELATIVE") + rpath_mode = BuildInfo::RELATIVE; + else if(conv.get()=="ABSOLUTE") + rpath_mode = BuildInfo::ABSOLUTE; + else + throw lexical_error(format("Conversion of '%s' to RuntimePathMode", conv.get())); +} diff --git a/source/buildinfo.h b/source/buildinfo.h index 5528748..ccfa2b6 100644 --- a/source/buildinfo.h +++ b/source/buildinfo.h @@ -21,6 +21,13 @@ public: FORCE_DYNAMIC //< Only accept dynamic libraries }; + enum RuntimePathMode + { + NO_RPATH, //< Do not record rpath in binaries + RELATIVE, //< Record relative rpath in binaries + ABSOLUTE //< Record absolute rpath in binaries + }; + class Loader: public Msp::DataFile::ObjectLoader { public: @@ -83,6 +90,7 @@ public: PathList libpath; WordList libs; Tracked libmode; + Tracked rpath_mode; LibModeMap libmodes; WordList keep_symbols; StandardMap standards; diff --git a/source/gnulinker.cpp b/source/gnulinker.cpp index faa6202..a132ace 100644 --- a/source/gnulinker.cpp +++ b/source/gnulinker.cpp @@ -271,6 +271,16 @@ Task *GnuLinker::Linker::run(const Target &target) const if(!sysroot.empty()) argv.push_back("--sysroot="+sysroot.str()); + FS::Path lib_dir = builder.get_prefix()/"lib"; + if(binfo.rpath_mode==BuildInfo::ABSOLUTE) + argv.push_back("-Wl,-rpath,"+lib_dir.str()); + else + { + if(binfo.rpath_mode==BuildInfo::RELATIVE) + argv.push_back("-Wl,-rpath,$ORIGIN/../lib"); + argv.push_back("-Wl,-rpath-link,"+lib_dir.str()); + } + for(BuildInfo::PathList::const_iterator i=binfo.libpath.begin(); i!=binfo.libpath.end(); ++i) argv.push_back("-L"+i->str()); if(binfo.strip)