Thanks to visit codestin.com
Credit goes to github.com

Skip to content

AppRun hooks for plugins #87

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 15 commits into from
Aug 14, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions include/linuxdeploy/core/appdir.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ namespace linuxdeploy {
explicit AppDir(const std::string& path);

// creates basic directory structure of an AppDir in "FHS" mode
bool createBasicStructure();
bool createBasicStructure() const;

// deploy shared library
//
Expand All @@ -66,39 +66,42 @@ namespace linuxdeploy {
// deploy arbitrary file
boost::filesystem::path deployFile(const boost::filesystem::path& from, const boost::filesystem::path& to);

// copy arbitrary file (immediately)
bool copyFile(const boost::filesystem::path& from, const boost::filesystem::path& to, bool overwrite = false) const;

// create an <AppDir> relative symlink to <target> at <symlink>.
bool createRelativeSymlink(const boost::filesystem::path& target, const boost::filesystem::path& symlink);
bool createRelativeSymlink(const boost::filesystem::path& target, const boost::filesystem::path& symlink) const;

// execute deferred copy operations
bool executeDeferredOperations();

// return path to AppDir
boost::filesystem::path path();
boost::filesystem::path path() const;

// create a list of all icon paths in the AppDir
std::vector<boost::filesystem::path> deployedIconPaths();
std::vector<boost::filesystem::path> deployedIconPaths() const;

// create a list of all executable paths in the AppDir
std::vector<boost::filesystem::path> deployedExecutablePaths();
std::vector<boost::filesystem::path> deployedExecutablePaths() const;

// create a list of all desktop file paths in the AppDir
std::vector<desktopfile::DesktopFile> deployedDesktopFiles();
std::vector<desktopfile::DesktopFile> deployedDesktopFiles() const;

// create symlinks for AppRun, desktop file and icon in the AppDir root directory
bool createLinksInAppDirRoot(const desktopfile::DesktopFile& desktopFile, boost::filesystem::path customAppRunPath = "");
bool setUpAppDirRoot(const desktopfile::DesktopFile& desktopFile, boost::filesystem::path customAppRunPath = "");

// list all executables in <AppDir>/usr/bin
// this function does not perform a recursive search, but only searches the bin directory
std::vector<boost::filesystem::path> listExecutables();
std::vector<boost::filesystem::path> listExecutables() const;

// list all shared libraries in <AppDir>/usr/lib
// this function recursively searches the entire lib directory for shared libraries
std::vector<boost::filesystem::path> listSharedLibraries();
std::vector<boost::filesystem::path> listSharedLibraries() const;

// search for executables and libraries and deploy their dependencies
// calling this function can turn sure file trees created by make install commands into working
// AppDirs
bool deployDependenciesForExistingFiles();
bool deployDependenciesForExistingFiles() const;

// disable deployment of copyright files for this instance
void setDisableCopyrightFilesDeployment(bool disable);
Expand Down
4 changes: 2 additions & 2 deletions src/core.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ namespace linuxdeploy {

try {
desktopfile::DesktopFile desktopFile = getMainDesktopFile(desktopFilePaths, deployedDesktopFiles);
ldLog() << "Deploying desktop file:" << desktopFile.path() << std::endl;
return appDir.createLinksInAppDirRoot(desktopFile, customAppRunPath);
ldLog() << "Deploying files to AppDir root using desktop file:" << desktopFile.path() << std::endl;
return appDir.setUpAppDirRoot(desktopFile, customAppRunPath);
} catch (const DeployError& er) {
return false;
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ target_link_libraries(linuxdeploy_core_log PUBLIC ${BOOST_LIBS})

add_subdirectory(copyright)

add_library(linuxdeploy_core STATIC elf.cpp appdir.cpp ${HEADERS})
add_library(linuxdeploy_core STATIC elf.cpp appdir.cpp ${HEADERS} appdir_root_setup.cpp)
target_link_libraries(linuxdeploy_core PUBLIC
linuxdeploy_plugin linuxdeploy_core_log linuxdeploy_util linuxdeploy_desktopfile_static
${BOOST_LIBS} CImg ${CMAKE_THREAD_LIBS_INIT}
Expand Down
144 changes: 19 additions & 125 deletions src/core/appdir.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

// auto-generated headers
#include "excludelist.h"
#include "appdir_root_setup.h"

using namespace linuxdeploy::core;
using namespace linuxdeploy::desktopfile;
Expand Down Expand Up @@ -81,7 +82,7 @@ namespace linuxdeploy {

// actually copy file
// mimics cp command behavior
bool copyFile(const bf::path& from, bf::path to, bool overwrite = false) {
static bool copyFile(const bf::path& from, bf::path to, bool overwrite = false) {
ldLog() << "Copying file" << from << "to" << to << std::endl;

try {
Expand Down Expand Up @@ -559,7 +560,7 @@ namespace linuxdeploy {
return true;
}

bool isInDebugSymbolsLocation(const bf::path& path) {
static bool isInDebugSymbolsLocation(const bf::path& path) {
// TODO: check if there's more potential locations for debug symbol files
for (const std::string& dbgSymbolsPrefix : {".debug/"}) {
if (path.string().substr(0, dbgSymbolsPrefix.size()) == dbgSymbolsPrefix)
Expand All @@ -578,7 +579,7 @@ namespace linuxdeploy {

AppDir::AppDir(const std::string& path) : AppDir(bf::path(path)) {}

bool AppDir::createBasicStructure() {
bool AppDir::createBasicStructure() const {
std::vector<std::string> dirPaths = {
"usr/bin/",
"usr/lib/",
Expand Down Expand Up @@ -635,7 +636,7 @@ namespace linuxdeploy {
return d->executeDeferredOperations();
}

boost::filesystem::path AppDir::path() {
boost::filesystem::path AppDir::path() const {
return d->appDirPath;
}

Expand Down Expand Up @@ -665,19 +666,19 @@ namespace linuxdeploy {
return foundPaths;
}

std::vector<bf::path> AppDir::deployedIconPaths() {
std::vector<bf::path> AppDir::deployedIconPaths() const {
auto icons = listFilesInDirectory(path() / "usr/share/icons/");
auto pixmaps = listFilesInDirectory(path() / "usr/share/pixmaps/", false);
icons.reserve(pixmaps.size());
std::copy(pixmaps.begin(), pixmaps.end(), std::back_inserter(icons));
return icons;
}

std::vector<bf::path> AppDir::deployedExecutablePaths() {
std::vector<bf::path> AppDir::deployedExecutablePaths() const {
return listFilesInDirectory(path() / "usr/bin/", false);
}

std::vector<DesktopFile> AppDir::deployedDesktopFiles() {
std::vector<DesktopFile> AppDir::deployedDesktopFiles() const {
std::vector<DesktopFile> desktopFiles;

auto paths = listFilesInDirectory(path() / "usr/share/applications/", false);
Expand All @@ -692,131 +693,24 @@ namespace linuxdeploy {
return desktopFiles;
}

bool AppDir::createLinksInAppDirRoot(const DesktopFile& desktopFile, boost::filesystem::path customAppRunPath) {
ldLog() << "Deploying desktop file to AppDir root:" << desktopFile.path() << std::endl;

// copy desktop file to root directory
if (!d->symlinkFile(desktopFile.path(), path())) {
ldLog() << LD_ERROR << "Failed to create link to desktop file in AppDir root:" << desktopFile.path() << std::endl;
return false;
}

// look for suitable icon
DesktopFileEntry iconEntry;

if (!desktopFile.getEntry("Desktop Entry", "Icon", iconEntry)) {
ldLog() << LD_ERROR << "Icon entry missing in desktop file:" << desktopFile.path() << std::endl;
return false;
}

bool iconDeployed = false;

const auto foundIconPaths = deployedIconPaths();

if (foundIconPaths.empty()) {
ldLog() << LD_ERROR << "Could not find icon executable for Icon entry:" << iconEntry.value() << std::endl;
return false;
}

for (const auto& iconPath : foundIconPaths) {
ldLog() << LD_DEBUG << "Icon found:" << iconPath << std::endl;

const bool matchesFilenameWithExtension = iconPath.filename() == iconEntry.value();

if (iconPath.stem() == iconEntry.value() || matchesFilenameWithExtension) {
if (matchesFilenameWithExtension) {
ldLog() << LD_WARNING << "Icon= entry filename contains extension" << std::endl;
}

ldLog() << "Deploying icon to AppDir root:" << iconPath << std::endl;

if (!d->symlinkFile(iconPath, path())) {
ldLog() << LD_ERROR << "Failed to create symlink for icon in AppDir root:" << iconPath << std::endl;
return false;
}

iconDeployed = true;
break;
}
}

if (!iconDeployed) {
ldLog() << LD_ERROR << "Could not find suitable icon for Icon entry:" << iconEntry.value() << std::endl;
return false;
}

if (!customAppRunPath.empty()) {
// copy custom AppRun executable
// FIXME: make sure this file is executable
ldLog() << "Deploying custom AppRun:" << customAppRunPath;

if (!d->copyFile(customAppRunPath, path() / "AppRun"))
return false;
} else {
// check if there is a custom AppRun already
// in that case, skip deployment of symlink
if (bf::exists(path() / "AppRun")) {
ldLog() << LD_WARNING << "Custom AppRun detected, skipping deployment of symlink" << std::endl;
} else {
// look for suitable binary to create AppRun symlink
DesktopFileEntry executableEntry;

if (!desktopFile.getEntry("Desktop Entry", "Exec", executableEntry)) {
ldLog() << LD_ERROR << "Exec entry missing in desktop file:" << desktopFile.path()
<< std::endl;
return false;
}

auto executableName = util::split(executableEntry.value())[0];

const auto foundExecutablePaths = deployedExecutablePaths();

if (foundExecutablePaths.empty()) {
ldLog() << LD_ERROR << "Could not find suitable executable for Exec entry:" << executableName
<< std::endl;
return false;
}

bool deployedExecutable = false;

for (const auto& executablePath : foundExecutablePaths) {
ldLog() << LD_DEBUG << "Executable found:" << executablePath << std::endl;

if (executablePath.filename() == executableName) {
ldLog() << "Deploying AppRun symlink for executable in AppDir root:" << executablePath
<< std::endl;

if (!d->symlinkFile(executablePath, path() / "AppRun")) {
ldLog() << LD_ERROR
<< "Failed to create AppRun symlink for executable in AppDir root:"
<< executablePath << std::endl;
return false;
}

deployedExecutable = true;
break;
}
}

if (!deployedExecutable) {
ldLog() << LD_ERROR << "Could not deploy symlink for executable: could not find suitable executable for Exec entry:" << executableName << std::endl;
return false;
}
}
}

return true;
bool AppDir::setUpAppDirRoot(const DesktopFile& desktopFile, boost::filesystem::path customAppRunPath) {
AppDirRootSetup setup(*this);
setup.run(desktopFile, customAppRunPath);
}

bf::path AppDir::deployFile(const boost::filesystem::path& from, const boost::filesystem::path& to) {
return d->deployFile(from, to, true);
}

bool AppDir::createRelativeSymlink(const bf::path& target, const bf::path& symlink) {
bool AppDir::copyFile(const bf::path& from, const bf::path& to, bool overwrite) const {
return d->copyFile(from, to, overwrite);
}

bool AppDir::createRelativeSymlink(const bf::path& target, const bf::path& symlink) const {
return d->symlinkFile(target, symlink, true);
}

std::vector<bf::path> AppDir::listExecutables() {
std::vector<bf::path> AppDir::listExecutables() const {
std::vector<bf::path> executables;

for (const auto& file : listFilesInDirectory(path() / "usr" / "bin", false)) {
Expand All @@ -834,7 +728,7 @@ namespace linuxdeploy {
return executables;
}

std::vector<bf::path> AppDir::listSharedLibraries() {
std::vector<bf::path> AppDir::listSharedLibraries() const {
std::vector<bf::path> sharedLibraries;

for (const auto& file : listFilesInDirectory(path() / "usr" / "lib", true)) {
Expand All @@ -856,7 +750,7 @@ namespace linuxdeploy {
return sharedLibraries;
}

bool AppDir::deployDependenciesForExistingFiles() {
bool AppDir::deployDependenciesForExistingFiles() const {
for (const auto& executable : listExecutables()) {
if (bf::is_symlink(executable))
continue;
Expand Down
Loading