Add --deploy-deps-only

This commit is contained in:
TheAssassin
2020-07-15 03:17:37 +02:00
parent 590a746882
commit 557bad2241
3 changed files with 92 additions and 0 deletions

View File

@@ -57,6 +57,11 @@ namespace linuxdeploy {
// deploy executable
bool deployExecutable(const boost::filesystem::path& path, const boost::filesystem::path& destination = "");
// deploy dependencies for ELF file in AppDir, without copying it into the library dir
//
// the dependencies end up in the regular location
bool deployDependenciesOnlyForElfFile(const boost::filesystem::path& elfFilePath, bool failSilentForNonElfFile = false);
// deploy desktop file
bool deployDesktopFile(const desktopfile::DesktopFile& desktopFile);

View File

@@ -830,6 +830,61 @@ namespace linuxdeploy {
return true;
}
// TODO: quite similar to deployDependenciesForExistingFiles... maybe they should be merged or use each other
bool AppDir::deployDependenciesOnlyForElfFile(const boost::filesystem::path& elfFilePath, bool failSilentForNonElfFile) {
// preconditions: file must be an ELF one, and file must be contained in the AppDir
const auto absoluteElfFilePath = bf::absolute(elfFilePath);
// can't bundle directories
if (!bf::is_regular_file(absoluteElfFilePath)) {
ldLog() << LD_DEBUG << "Skipping non-file directory entry:" << absoluteElfFilePath << std::endl;
return false;
}
// to do a proper prefix check, we need a proper absolute path for the AppDir
const auto absoluteAppDirPath = bf::absolute(this->path());
ldLog() << LD_DEBUG << "absolute AppDir path:" << absoluteAppDirPath << std::endl;
// a fancy way to check STL strings for prefixes is to "ab"use rfind
if (absoluteElfFilePath.string().rfind(absoluteAppDirPath.string()) != 0) {
ldLog() << LD_ERROR << "File" << absoluteElfFilePath << "is not contained in AppDir, its dependencies cannot be deployed into the AppDir" << std::endl;
return false;
}
// make sure we have an ELF file
try {
elf::ElfFile(absoluteElfFilePath.string());
} catch (const elf::ElfFileParseError& e) {
auto level = LD_ERROR;
if (failSilentForNonElfFile) {
level = LD_WARNING;
}
ldLog() << level << "Not an ELF file:" << absoluteElfFilePath << std::endl;
return failSilentForNonElfFile;
}
// relative path makes for a nicer and more consistent log
ldLog() << "Deploying dependencies for ELF file in AppDir:" << elfFilePath << std::endl;
// bundle dependencies
if (!d->deployElfDependencies(absoluteElfFilePath))
return false;
// set rpath correctly
const auto rpathDestination = this->path() / "usr/lib";
ldLog() << LD_DEBUG << "rpath destination:" << rpathDestination << std::endl;
const auto rpath = PrivateData::calculateRelativeRPath(elfFilePath.parent_path(), rpathDestination);
ldLog() << LD_DEBUG << "Calculated rpath:" << rpath << std::endl;
d->setElfRPathOperations[absoluteElfFilePath] = rpath;
return true;
}
void AppDir::setDisableCopyrightFilesDeployment(bool disable) {
d->disableCopyrightFilesDeployment = disable;
}

View File

@@ -36,6 +36,8 @@ int main(int argc, char** argv) {
args::ValueFlagList<std::string> executablePaths(parser, "executable", "Executable to deploy", {'e', "executable"});
args::ValueFlagList<std::string> deployDepsOnlyPaths(parser, "path", "Path to ELF file or directory containing such files (libraries or executables) in the AppDir whose dependencies shall be deployed by linuxdeploy without copying them into the AppDir", {"deploy-deps-only"});
args::ValueFlagList<std::string> desktopFilePaths(parser, "desktop file", "Desktop file to deploy", {'d', "desktop-file"});
args::Flag createDesktopFile(parser, "", "Create basic desktop file that is good enough for some tests", {"create-desktop-file"});
@@ -147,6 +149,36 @@ int main(int argc, char** argv) {
}
}
// deploy executables to usr/bin, and deploy their dependencies to usr/lib
if (deployDepsOnlyPaths) {
ldLog() << std::endl << "-- Deploying dependencies only for ELF files --" << std::endl;
for (const auto& path : deployDepsOnlyPaths.Get()) {
if (bf::is_directory(path)) {
ldLog() << "Deploying files in directory" << path << std::endl;
for (auto it = bf::directory_iterator{path}; it != bf::directory_iterator{}; ++it) {
if (!bf::is_regular_file(*it)) {
continue;
}
if (!appDir.deployDependenciesOnlyForElfFile(*it, true)) {
ldLog() << LD_WARNING << "Failed to deploy dependencies for ELF file" << *it << LD_NO_SPACE << ", skipping" << std::endl;
return 1;
}
}
} else if (bf::is_regular_file(path)) {
if (!appDir.deployDependenciesOnlyForElfFile(path)) {
ldLog() << LD_ERROR << "Failed to deploy dependencies for ELF file: " << path << std::endl;
return 1;
}
} else {
ldLog() << LD_ERROR << "No such file or directory: " << path << std::endl;
return 1;
}
}
}
// perform deferred copy operations before running input plugins to make sure all files the plugins might expect
// are in place
ldLog() << std::endl << "-- Copying files into AppDir --" << std::endl;