63 Commits

Author SHA1 Message Date
TheAssassin b7a2e39ba2 Try to build for arm64, mk. 4 2019-12-03 02:04:02 +01:00
TheAssassin d9acb6b244 Try to build for arm64, mk. 3 2019-12-03 01:50:59 +01:00
TheAssassin 891359edf4 Try to build for arm64, mk. 2 2019-12-03 01:47:18 +01:00
TheAssassin f68f8b94e0 Try to build for arm64, mk. 1 2019-12-03 01:38:28 +01:00
TheAssassin 1bd5453c61 Fix detection of copyright tools
CC #104
2019-11-18 23:13:44 +01:00
TheAssassin 9783db602e Quick fix unavailability of which command
CC #104
2019-11-18 20:44:53 +01:00
TheAssassin 6cfa741f40 Add missing newline (fixes #102) 2019-11-13 15:31:52 +01:00
TheAssassin 1be3327a11 Use own prebuilt CMake 2019-09-28 15:25:13 +02:00
TheAssassin cca5ad2e07 Merge pull request #96 from linuxdeploy/completely-switch-to-centos6
Build all binaries on CentOS 6
2019-09-28 04:22:40 +02:00
TheAssassin 058832615c Fix binaries upload 2019-09-28 04:02:00 +02:00
TheAssassin cf5927c521 Make sure old build script artifacts carry different name 2019-09-28 03:49:57 +02:00
TheAssassin 103b637944 Make CentOS 6 build script equivalent to old one 2019-09-28 03:49:15 +02:00
TheAssassin 58189efba6 Build binaries on CentOS 6 2019-09-28 03:48:53 +02:00
TheAssassin 019f902b17 Fix Docker build artifacts handling 2019-09-28 03:48:18 +02:00
TheAssassin f97d1e9a01 Improve shell use of Docker images 2019-09-28 03:47:24 +02:00
TheAssassin 543078c11e Clean up Dockerfile 2019-09-28 03:47:05 +02:00
TheAssassin 9ddb0d7650 Remove old debug code 2019-09-28 01:33:45 +02:00
TheAssassin 8252503d97 Merge pull request #95 from linuxdeploy/centos6-builds
Centos6 builds
2019-09-27 21:59:30 +02:00
TheAssassin d312ba07d0 No need to run install step for Docker builds 2019-09-27 21:34:06 +02:00
TheAssassin d3853e961b Clean up Dockerfile 2019-09-27 21:32:44 +02:00
TheAssassin ef7b397d4a Use devtoolset to compile dependencies in CentOS 6 builds 2019-09-27 21:32:27 +02:00
TheAssassin 330f8a393f Use devtoolset 7 for 64-bit CentOS builds 2019-09-27 21:32:09 +02:00
TheAssassin 77ad746c5d Build i386 CentOS 6 binaries on Travis 2019-09-27 21:15:52 +02:00
TheAssassin cd04cc260e 32-bit CentOS 6 builds 2019-09-27 21:09:10 +02:00
TheAssassin 3c4580a325 Allow bundling of additional binaries without moving them
Required to bundle e.g., applications' plugins together with their
dependencies without moving them out of position so they can still
be found by the original apps.
2019-09-22 19:06:00 +02:00
TheAssassin f20af7dc67 Refactor and improve relative directory calculation
Also makes variable names less ambiguous and adds some documenting
comments.
2019-09-22 18:58:21 +02:00
TheAssassin 0ba33879b0 Fix argument forwarding in generated AppRun script 2019-09-12 16:35:09 +02:00
TheAssassin f3b7c5ab73 Never ask to integrate linuxdeploy AppImages 2019-09-06 15:47:45 +02:00
TheAssassin 6bc354bacb Update linuxdeploy-desktopfile 2019-09-06 03:13:21 +02:00
TheAssassin d26947985d Add tests only if they are built and can therefore be run 2019-09-06 03:13:05 +02:00
TheAssassin 2cc962a344 Update README.md 2019-08-22 15:08:04 +02:00
TheAssassin 612bf962a3 Another missing return statement 2019-08-15 01:10:02 +02:00
TheAssassin 19d958d30f There should at least be debug messages for potential errors 2019-08-15 00:00:19 +02:00
TheAssassin fc82028af4 More forgotten return statements in bool methods 2019-08-14 23:57:50 +02:00
TheAssassin 2d45ef4c72 Fix missing return statement in static bool method
Looks like devtoolset compiler behaves differently on bool methods
without an explicit return statement. Kind of strange.

Undefined behavior?
2019-08-14 23:42:57 +02:00
TheAssassin 470caa3db1 Replace ln based subprocess symlinking with boost functionality 2019-08-14 23:25:21 +02:00
TheAssassin d24e6dac56 Clean up symlink helper 2019-08-14 22:47:59 +02:00
TheAssassin 913f5bc6cc Mirror package was hosted on disappeared 2019-08-14 16:12:19 +02:00
TheAssassin 4746fd0e87 Merge pull request #87 from linuxdeploy/apprun-hooks
AppRun hooks for plugins
2019-08-14 16:10:45 +02:00
TheAssassin de363bc90b Merge branch 'master' into apprun-hooks 2019-08-14 15:14:02 +02:00
TheAssassin 8e9114b7c5 Improve generated AppRun script 2019-08-14 14:36:06 +02:00
TheAssassin 72e4fb49e0 Don't try to move if there's no need to do so 2019-08-14 14:35:53 +02:00
TheAssassin abdefbc0ff Use a custom variable to support test runs from IDE better
When your IDE is running as an AppImage, the $APPRUN variable is
already set in the built-in terminal. Now of course you could just
calculate the path of $APPRUN yourself and force-overwrite it in that
script; however that's more effort and more likely to break.

Therefore it's easier to just introduce and use a custom variable.
2019-08-14 14:33:25 +02:00
TheAssassin 58845cee8f Support for AppRun hooks installed by plugins, mk. 1 2019-08-14 04:13:30 +02:00
TheAssassin 5bc8840003 Mark methods const where possible 2019-08-14 04:11:36 +02:00
TheAssassin 1cb5a742db Break up deployment algorithm into independent methods
That makes maintenance easier.
2019-08-14 02:28:21 +02:00
TheAssassin 142facd986 Improve method 2019-08-14 01:35:31 +02:00
TheAssassin aced62378a Move AppDir root deployment into separate class
Makes adding more features easier, as there's a clear defined interface
to the class and the mechanism can be split into more methods more
easily without bloating the AppDir class further.
2019-08-14 01:35:23 +02:00
TheAssassin 3fd595a63b Expose file copying helper in public interface 2019-08-14 01:33:09 +02:00
TheAssassin 9dc10fc0fc Method can be static 2019-08-14 01:08:20 +02:00
TheAssassin 3183ee2f4f Mark methods const where possible 2019-07-27 16:37:16 +02:00
TheAssassin 374e17b5e3 Merge pull request #85 from linuxdeploy/update_cpp_subprocess
Update cpp-subprocess to ensure that the bug in util::read_all() is fixed
2019-07-25 20:32:12 +02:00
TheAssassin d9681ccf5c Merge branch 'master' into update_cpp_subprocess 2019-07-25 20:10:35 +02:00
Alexis Lopez Zubieta 57dbdc6933 Update cpp-subprocess to ensure that the bug in util::read_all() is fixed 2019-07-25 13:08:21 -05:00
TheAssassin 3d766446d9 Improve log message 2019-07-25 17:47:34 +02:00
TheAssassin e24b46d291 Change method name to something more meaningful 2019-07-25 17:44:50 +02:00
TheAssassin 47b8370751 Method can be static 2019-07-25 17:43:45 +02:00
TheAssassin 0d055ebb81 Merge pull request #84 from darealshinji/patch-1
remove all comments
2019-07-07 16:06:52 +02:00
darealshinji ce5aecead5 remove all comments
Otherwise the generated header contains entries like this:
``` c
    "libxcb-dri2.so.0",
    "#",
    "https://github.com/probonopd/linuxdeployqt/issues/331#issuecomment-442276277",
    "libxcb-dri3.so.0",
    "#",
    "https://github.com/AppImage/AppImages/issues/348",
```
2019-07-06 20:21:16 +02:00
TheAssassin f01ae51f58 Merge pull request #79 from haampie/fix-deployment-of-dependencies
Fix an issue where dependencies are not deployed when calling deployLibrary only
2019-06-10 20:31:12 +02:00
Harmen Stoppels 0e95f19a75 Make deployLibrary deploy its dependencies by default, and avoid unnecessary recursion by making deployElfDependencies not deploy its deps of deps 2019-06-10 20:12:30 +02:00
TheAssassin 94bb814d69 Merge pull request #78 from haampie/fix-remove-recursion-elf-deployment
Remove recursion of ELF deployment since ldd already does that for us
2019-06-09 21:08:37 +02:00
Harmen Stoppels 159b082658 Remove recursion of ELF deployment since ldd already does that for us 2019-06-09 14:43:59 +02:00
21 changed files with 717 additions and 324 deletions
+79 -72
View File
@@ -3,87 +3,94 @@ sudo: required
matrix:
include:
- env: ARCH=x86_64
addons:
apt:
update: true
packages:
- libmagic-dev
- libjpeg-dev
- libpng-dev
- cimg-dev
- automake # required for patchelf
- env: ARCH=i386
addons:
apt:
update: true
packages:
- libmagic-dev:i386
- libjpeg-dev:i386
- libpng-dev:i386
- gcc-multilib
- g++-multilib
- automake # required for patchelf
- libfuse2:i386
- libcairo2:i386
- env: ARCH=x86_64 BUILD_TYPE=coverage
addons:
apt:
update: true
packages:
- libmagic-dev
- libjpeg-dev
- libpng-dev
- cimg-dev
before_script:
- sudo pip install gcovr
script: travis/test-coverage.sh
after_success: true # also, we don't intend to upload release binaries
- env: ARCH=i386 BUILD_TYPE=coverage
addons:
apt:
update: true
packages:
- libmagic-dev:i386
- libjpeg-dev:i386
- libpng-dev:i386
- gcc-multilib
- g++-multilib
- libfuse2:i386
- libcairo2:i386
before_script:
- sudo pip install gcovr
script: travis/test-coverage.sh
after_success: true # also, we don't intend to upload release binaries
- env: ARCH=x86_64 BUILD_TYPE=centos6
- name: CentOS 6 x86_64 build
env: ARCH=x86_64 BUILD_TYPE=centos6
install: true
services:
- docker
script: travis/build-centos6-docker.sh
after_success:
- if [ "$TRAVIS_BRANCH" != "$TRAVIS_TAG" ] && [ "$TRAVIS_BRANCH" != "master" ]; then export TRAVIS_EVENT_TYPE=pull_request; fi
- wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh
- bash upload.sh linuxdeploy-centos6-"$ARCH".AppImage*
- bash upload.sh linuxdeploy-"$ARCH".AppImage*
install:
- git clone https://github.com/NixOS/patchelf.git -b 0.8
- cd patchelf
- ./bootstrap.sh
- if [ "$ARCH" == "i386" ]; then ./configure --prefix=/usr --build=i686-pc-linux-gnu CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32; fi
- if [ "$ARCH" == "x86_64" ]; then ./configure --prefix=/usr; fi
- make -j$(nproc)
- sudo make install
- cd ..
- rm -rf patchelf
- name: CentOS 6 i386 build
env: ARCH=i386 BUILD_TYPE=centos6
install: true
services:
- docker
script: travis/build-centos6-docker.sh
after_success:
- if [ "$TRAVIS_BRANCH" != "$TRAVIS_TAG" ] && [ "$TRAVIS_BRANCH" != "master" ]; then export TRAVIS_EVENT_TYPE=pull_request; fi
- wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh
- bash upload.sh linuxdeploy-"$ARCH".AppImage*
script:
- travis/build.sh
- name: Ubuntu bionic arm64 build
env: ARCH=arm64 BUILD_TYPE=arm64-native
dist: bionic
arch: arm64
addons:
apt:
update: true
packages:
- libmagic-dev
- libjpeg-dev
- libpng-dev
- cimg-dev
- patchelf
before_script:
- git clone https://github.com/NixOS/patchelf.git && \
- pushd patchelf && \
- # cannot use -b since it's not supported in really old versions of git
- git checkout 0.8 && \
- ./bootstrap.sh && \
- ./configure --prefix=/usr && \
- make -j $(nproc) && \
- make install && \
- popd && \
- rm -r patchelf/
script: travis/build.sh
after_success:
- if [ "$TRAVIS_BRANCH" != "$TRAVIS_TAG" ] && [ "$TRAVIS_BRANCH" != "master" ]; then export TRAVIS_EVENT_TYPE=pull_request; fi
- wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh
- bash upload.sh linuxdeploy-"$ARCH".AppImage*
- name: Ubuntu xenial x86_64 coverage build (no binaries uploaded)
env: ARCH=x86_64 BUILD_TYPE=coverage
dist: xenial
addons:
apt:
update: true
packages:
- libmagic-dev
- libjpeg-dev
- libpng-dev
- cimg-dev
before_script:
- sudo pip install gcovr
script: travis/test-coverage.sh
after_success: true # also, we don't intend to upload release binaries
- name: Ubuntu xenial i386 coverage build (no binaries uploaded)
env: ARCH=i386 BUILD_TYPE=coverage
dist: xenial
addons:
apt:
update: true
packages:
- libmagic-dev:i386
- libjpeg-dev:i386
- libpng-dev:i386
- gcc-multilib
- g++-multilib
- libfuse2:i386
- libcairo2:i386
before_script:
- sudo pip install gcovr
script: travis/test-coverage.sh
after_success: true # also, we don't intend to upload release binaries
after_success:
- ls -lh
# make sure only pushes to rewrite create a new release, otherwise pretend PR and upload to transfer.sh
- if [ "$TRAVIS_BRANCH" != "$TRAVIS_TAG" ] && [ "$TRAVIS_BRANCH" != "master" ]; then export TRAVIS_EVENT_TYPE=pull_request; fi
- wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh
- bash upload.sh linuxdeploy-"$ARCH".AppImage*
branches:
except:
+1
View File
@@ -28,6 +28,7 @@ This is an incomplete list of projects using linuxdeploy. You might want to read
- [OpenRCT2](https://github.com/OpenRCT2/OpenRCT2)
- [AppImageUpdate](https://github.com/AppImage/AppImageUpdate)
- [appimaged](https://github.com/AppImage/appimaged)
- [MediaElch](https://github.com/Komet/MediaElch/)
## Plugins
+13 -10
View File
@@ -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
//
@@ -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);
+1
View File
@@ -6,3 +6,4 @@ NoDisplay=true
Exec=linuxdeploy
Icon=linuxdeploy
Categories=Development;
X-AppImage-Integrate=false
+2 -2
View File
@@ -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;
}
+1 -1
View File
@@ -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}
+126 -196
View File
File diff suppressed because it is too large Load Diff
+286
View File
@@ -0,0 +1,286 @@
// local headers
#include <linuxdeploy/util/util.h>
#include <linuxdeploy/core/log.h>
#include "appdir_root_setup.h"
namespace bf = boost::filesystem;
namespace linuxdeploy {
using namespace desktopfile;
namespace core {
using namespace appdir;
using namespace log;
class AppDirRootSetup::Private {
public:
static constexpr auto APPRUN_HOOKS_DIRNAME = "apprun-hooks";
public:
const AppDir& appDir;
public:
explicit Private(const AppDir& appDir) : appDir(appDir) {}
public:
bool deployDesktopFileAndIcon(const DesktopFile& desktopFile) const {
ldLog() << "Deploying desktop file to AppDir root:" << desktopFile.path() << std::endl;
// copy desktop file to root directory
if (!appDir.createRelativeSymlink(desktopFile.path(), appDir.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 = appDir.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 (!appDir.createRelativeSymlink(iconPath, appDir.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;
}
return true;
}
bool deployCustomAppRunFile(const bf::path& customAppRunPath) const {
// copy custom AppRun executable
// FIXME: make sure this file is executable
ldLog() << "Deploying custom AppRun:" << customAppRunPath;
if (!appDir.copyFile(customAppRunPath, appDir.path() / "AppRun"))
return false;
return true;
}
bool deployStandardAppRunFromDesktopFile(const DesktopFile& desktopFile, const bf::path& customAppRunPath) const {
// check if there is a custom AppRun already
// in that case, skip deployment of symlink
if (bf::exists(appDir.path() / "AppRun")) {
ldLog() << LD_WARNING << "Existing 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 = appDir.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 (!appDir.createRelativeSymlink(executablePath, appDir.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 deployAppRunWrapperIfNecessary() const {
const bf::path appRunPath(appDir.path() / "AppRun");
const bf::path wrappedAppRunPath(appRunPath.string() + ".wrapped");
const bf::path appRunHooksPath(appDir.path() / APPRUN_HOOKS_DIRNAME);
// first, we check whether there's that special directory containing hooks
if (!bf::is_directory(appRunHooksPath)) {
ldLog() << LD_DEBUG << "Could not find apprun-hooks dir, no need to deploy the AppRun wrapper" << std::endl;
return true;
}
// if there's no files in there we don't have to do anything
bf::directory_iterator firstRegularFile = std::find_if(
bf::directory_iterator(appRunHooksPath),
bf::directory_iterator{},
[](const bf::path& p) {
return bf::is_regular_file(p);
}
);
if (firstRegularFile == bf::directory_iterator{}) {
ldLog() << LD_WARNING << "Found an empty apprun-hooks directory, assuming there is no need to deploy the AppRun wrapper" << std::endl;
return true;
}
// any file within that directory is considered to be a script
// we can't perform any validity checks, that would be way too much complexity and even tools which
// claim they can, like e.g., shellcheck, aren't perfect, they only aid in avoiding bugs but cannot
// prevent them completely
// let's put together the wrapper script's contents
std::ostringstream oss;
oss << "#! /usr/bin/env bash" << std::endl
<< std::endl
<< "# autogenerated by linuxdeploy" << std::endl
<< std::endl
<< "# make sure errors in sourced scripts will cause this script to stop" << std::endl
<< "set -e" << std::endl
<< std::endl
<< "this_dir=$(readlink -f $(dirname \"$0\"))" << std::endl
<< std::endl;
std::for_each(bf::directory_iterator(appRunHooksPath), bf::directory_iterator{}, [&oss](const bf::path& p) {
if (!bf::is_regular_file(p))
return;
oss << "source \"$this_dir\"/" << APPRUN_HOOKS_DIRNAME << "/" << p.filename() << std::endl;
});
oss << std::endl
<< "exec \"$this_dir\"/AppRun.wrapped \"$@\"" << std::endl;
// first we need to make sure we're not running this more than once
// this might cause more harm than good
// we require the user to clean up the mess at first
// FIXME: try to find a way how to rewrap AppRun on subsequent runs or, even better, become idempotent
if (bf::exists(wrappedAppRunPath)) {
ldLog() << LD_WARNING << "Already found wrapped AppRun, using existing file/symlink" << std::endl;
} else {
// backup original AppRun
bf::rename(appRunPath, wrappedAppRunPath);
}
// in case the above check triggered a warning, it's possible that there is another AppRun in the AppDir
// this one has to be cleaned up in that case
if (bf::exists(appRunPath)) {
ldLog() << LD_WARNING << "Found an AppRun file/symlink, possibly due to re-run of linuxdeploy, "
"overwriting" << std::endl;
bf::remove(appRunPath);
}
// install new script
std::ofstream ofs(appRunPath.string());
ofs << oss.str();
// make sure data is written to disk
ofs.flush();
ofs.close();
// make new file executable
bf::permissions(appRunPath,
bf::perms::owner_all | bf::perms::group_read | bf::perms::others_read |
bf::perms::group_exe | bf::perms::others_exe
);
// we're done!
return true;
}
};
AppDirRootSetup::AppDirRootSetup(const AppDir& appDir) : d(new Private(appDir)) {}
bool AppDirRootSetup::run(const DesktopFile& desktopFile, const bf::path& customAppRunPath) const {
// first step that is always required is to deploy the desktop file and the corresponding icon
if (!d->deployDesktopFileAndIcon(desktopFile)) {
ldLog() << LD_DEBUG << "deployDesktopFileAndIcon returned false" << std::endl;
return false;
}
// the algorithm depends on whether the user wishes to deploy their own AppRun file
// in case they do, the algorithm shall deploy that file
// otherwise, the standard algorithm shall be run which takes information from the desktop file to
// deploy a symlink pointing to the AppImage's main binary
// this allows power users to define their own AppImage initialization steps or run different binaries
// based on parameters etc.
if (!customAppRunPath.empty()) {
if (!d->deployCustomAppRunFile(customAppRunPath)) {
ldLog() << LD_DEBUG << "deployCustomAppRunFile returned false" << std::endl;
return false;
}
} else {
if (!d->deployStandardAppRunFromDesktopFile(desktopFile, customAppRunPath)) {
ldLog() << LD_DEBUG << "deployStandardAppRunFromDesktopFile returned false" << std::endl;
return false;
}
}
// plugins might need to run some initializing code to make certain features work
// these involve setting environment variables because libraries or frameworks don't support any other
// way of pointing them to resources inside the AppDir instead of looking into config files in locations
// inside the AppImage, etc.
// the linuxdeploy plugin specification states that if plugins put files into a specified directory in
// the AppImage, linuxdeploy will make sure they're run before running the regular AppRun
if (!d->deployAppRunWrapperIfNecessary()) {
ldLog() << LD_DEBUG << "deployAppRunWrapperIfNecessary returned false" << std::endl;
return false;
}
return true;
}
}
}
+36
View File
@@ -0,0 +1,36 @@
#pragma once
// system headers
#include <memory>
// local headers
#include "linuxdeploy/core/appdir.h"
namespace linuxdeploy {
namespace core {
/**
* Wrapper for an AppDir that encapsulates all functionality to set up the AppDir root directory.
*/
class AppDirRootSetup {
private:
// PImpl
class Private;
std::shared_ptr<Private> d;
public:
explicit AppDirRootSetup(const appdir::AppDir& appdir);
/**
* Deploy files to the AppDir root directory using the provided desktop file and the information within it.
* Optionally, a custom AppRun path can be provided which is deployed instead of following the internal
* default mechanism, which usually just places a symlink to the main binary as AppRun.
*
* @param desktopFile
* @param customAppRunPath
* @return
*/
bool run(const desktopfile::DesktopFile& desktopFile, const boost::filesystem::path& customAppRunPath = "") const;
};
}
}
+27 -8
View File
@@ -11,17 +11,36 @@ namespace linuxdeploy {
using namespace log;
std::shared_ptr<ICopyrightFilesManager> ICopyrightFilesManager::getInstance() {
auto check_command = [](const std::string& command) {
auto p = subprocess::Popen(
command,
subprocess::output(subprocess::PIPE),
subprocess::error(subprocess::PIPE)
);
// very simple but for our purposes good enough which like algorithm to find binaries in $PATH
// TODO: move into separate function to be used in the entire code base
// FIXME: remove dependency on subprocess library
static const auto which = [](const std::string& name) -> bf::path {
const auto* path = getenv("PATH");
return p.wait();
if (path == nullptr)
return "";
for (const auto& binDir : subprocess::util::split(path, ":")) {
if (!bf::is_directory(binDir)) {
continue;
}
for (bf::directory_iterator it(binDir); it != bf::directory_iterator{}; ++it) {
const auto binary = it->path();
std::cout << binary << std::endl;
if (binary.filename() == name) {
// TODO: check if file is executable (skip otherwise)
return binary;
}
}
}
return {};
};
if (check_command("which dpkg-query") == 0) {
if (!which("dpkg-query").empty()) {
ldLog() << LD_DEBUG << "Using dpkg-query to search for copyright files" << std::endl;
return std::make_shared<DpkgQueryCopyrightFilesManager>();
}
+1 -1
View File
@@ -18,7 +18,7 @@ log_prefix="-- [$(basename $0)]"
echo "$log_prefix downloading excludelist from GitHub"
url="https://raw.githubusercontent.com/probonopd/AppImages/master/excludelist"
blacklisted=($(wget --quiet "$url" -O - | sort | uniq | grep -v "^#.*" | grep "[^-\s]"))
blacklisted=($(wget --quiet "$url" -O - | sed 's|#.*||g' | sort | uniq))
# sanity check
if [ "$blacklisted" == "" ]; then
+14
View File
@@ -1,5 +1,19 @@
set(TEST_DATA_DIR ${CMAKE_CURRENT_SOURCE_DIR}/data)
# common CMake macro for linuxdeploy, adding tests only if they are supposed to be built
# otherwise if you try to run CTest the tests aren't build and CTest can't find them
if(NOT COMMAND ld_add_test)
function(ld_add_test TARGET_NAME)
get_target_property(${TARGET_NAME}_EFA ${TARGET_NAME} EXCLUDE_FROM_ALL)
if(NOT ${${TARGET_NAME}_EXCLUDE_FROM_ALL})
message(STATUS "[${PROJECT_NAME}] Adding test ${TARGET_NAME}")
add_test(${TARGET_NAME} ${TARGET_NAME})
else()
message(STATUS "[${PROJECT_NAME}] Test ${TARGET_NAME} is excluded from ALL, not adding as test")
endif()
endfunction()
endif()
# first build dependencies for tests
add_subdirectory(simple_library)
add_subdirectory(simple_executable)
+2 -2
View File
@@ -12,7 +12,7 @@ target_compile_definitions(test_appdir PRIVATE
)
# register in CTest
add_test(test_appdir test_appdir)
ld_add_test(test_appdir)
# make sure library and executable are built before test_appdir
add_dependencies(test_appdir simple_library simple_executable)
@@ -33,7 +33,7 @@ target_compile_definitions(test_linuxdeploy PRIVATE
)
# register in CTest
add_test(test_linuxdeploy test_linuxdeploy)
ld_add_test(test_linuxdeploy)
# make sure library and executable are built before test_appdir
add_dependencies(test_linuxdeploy simple_library simple_executable)
+19 -5
View File
@@ -1,10 +1,24 @@
FROM centos:6
RUN yum install -y centos-release-scl-rh && \
yum install -y devtoolset-6 wget curl patchelf vim-common fuse libfuse2 libtool autoconf automake zlib-devel libjpeg-devel libpng-devel nano git && \
wget https://github.com/Kitware/CMake/releases/download/v3.13.4/cmake-3.13.4-Linux-x86_64.tar.gz -O- | tar xz --strip-components=1 -C/usr/local
yum install -y devtoolset-7 wget curl patchelf vim-common fuse libfuse2 libtool autoconf automake zlib-devel libjpeg-devel libpng-devel nano git && \
wget https://artifacts.assassinate-you.net/artifactory/cmake-centos6/cmake-v3.15.3-x86_64.tar.gz -O- | tar xz --strip-components=1 -C/usr/local
RUN wget http://springdale.math.ias.edu/data/puias/computational/6/x86_64//patchelf-0.8-2.sdl6.x86_64.rpm && \
echo "3d746306f5f7958b9487e6d08f53bb13 patchelf-0.8-2.sdl6.x86_64.rpm" || md5sum -c && \
rpm -i patchelf-0.8-2.sdl6.x86_64.rpm
ENV ARCH=x86_64
COPY entrypoint.sh /
SHELL ["/entrypoint.sh", "bash", "-x", "-c"]
ENTRYPOINT ["/entrypoint.sh"]
RUN yum install -y gcc-c++ && \
git clone https://github.com/NixOS/patchelf.git && \
pushd patchelf && \
# cannot use -b since it's not supported in really old versions of git
git checkout 0.8 && \
./bootstrap.sh && \
./configure --prefix=/usr/local && \
make -j $(nproc) && \
make install && \
popd && \
rm -r patchelf/
CMD ["bash"]
+35
View File
@@ -0,0 +1,35 @@
FROM i386/centos:6
SHELL ["/bin/bash", "-x", "-c"]
# during Docker build, yum doesn't detect it's an i386 environment on x86_64 machines, and tries to install x86_64 packages, which can't work
# this little command fixes this
RUN sed -i 's/$basearch/i386/g' /etc/yum.repos.d/CentOS-Base.repo
# thanks CloudLinux, you're really helping us poor AppImage creators seeking for maximum compatibility by providing devtoolset i386 builds
RUN yum install -y yum-utils && \
rpm --import https://repo.cloudlinux.com/cloudlinux/security/RPM-GPG-KEY-CloudLinux && \
yum-config-manager --add-repo https://www.repo.cloudlinux.com/cloudlinux/6/sclo/devtoolset-7/i386/ && \
yum install -y devtoolset-7 wget curl patchelf vim-common fuse libfuse2 libtool autoconf automake zlib-devel libjpeg-devel libpng-devel nano git
# the shell wrapper takes care of enabling devtoolset and running a shell properly
# unfortunately this is the easiest and most solid workaround to the limitations of the scl command
COPY entrypoint.sh /
ENV ARCH=i386
ENTRYPOINT ["/entrypoint.sh"]
SHELL ["/entrypoint.sh", "bash", "-x", "-c"]
RUN wget https://artifacts.assassinate-you.net/artifactory/cmake-centos6/cmake-v3.15.3-i386.tar.gz -O- | tar xz --strip-components=1 -C/usr/local
RUN git clone https://github.com/NixOS/patchelf.git && \
pushd patchelf && \
# cannot use -b since it's not supported in really old versions of git
git checkout 0.8 && \
./bootstrap.sh && \
./configure --prefix=/usr/local && \
make -j $(nproc) && \
make install && \
popd && \
rm -r patchelf/
CMD ["bash"]
+6 -1
View File
@@ -8,6 +8,11 @@ here=$(readlink -f $(dirname "$0"))
DOCKERFILE="$here"/Dockerfile.centos6
IMAGE=linuxdeploy-build-centos6
if [ "$ARCH" == "i386" ]; then
DOCKERFILE="$DOCKERFILE"-i386
IMAGE="$IMAGE"-i386
fi
(cd "$here" && docker build -f "$DOCKERFILE" -t "$IMAGE" .)
docker run --rm -i -v "$here"/..:/ws:ro -v "$old_cwd":/out -e OUTDIR_OWNER=$(id -u) "$IMAGE" /bin/bash -xe /ws/travis/build-centos6.sh
docker run --rm -it -v "$here"/..:/ws:ro -v "$old_cwd":/out -e CI=1 -e OUTDIR_OWNER=$(id -u) "$IMAGE" /bin/bash -xe -c "cd /out && /ws/travis/build-centos6.sh"
+52 -22
View File
@@ -1,19 +1,34 @@
#! /bin/bash
set -xe
set -e
set -x
# get a compiler that allows for using modern-ish C++ (>= 11) on a distro that doesn't normally support it
# before you ask: yes, the binaries will work on CentOS 6 even without devtoolset (they somehow partially link C++
# things statically while using others from the system...)
# so, basically, it's magic!
. /opt/rh/devtoolset-6/enable
# use RAM disk if possible
if [ "$CI" == "" ] && [ -d /dev/shm ]; then
TEMP_BASE=/dev/shm
else
TEMP_BASE=/tmp
fi
mkdir build
cd build
BUILD_DIR=$(mktemp -d -p "$TEMP_BASE" linuxdeploy-build-XXXXXX)
cmake /ws -DCMAKE_INSTALL_PREFIX=/usr -DUSE_SYSTEM_CIMG=Off
cleanup () {
if [ -d "$BUILD_DIR" ]; then
rm -rf "$BUILD_DIR"
fi
}
make -j8
trap cleanup EXIT
# store repo root as variable
REPO_ROOT=$(readlink -f $(dirname $(dirname "$0")))
OLD_CWD=$(readlink -f .)
pushd "$BUILD_DIR"
cmake "$REPO_ROOT" -DCMAKE_INSTALL_PREFIX=/usr -DUSE_SYSTEM_CIMG=Off -DUSE_CCACHE=Off
make -j$(nproc)
ctest -V
@@ -23,20 +38,35 @@ LINUXDEPLOY_ARGS=("--appdir" "AppDir" "-e" "bin/linuxdeploy" "-i" "/ws/resources
# deploy patchelf which is a dependency of linuxdeploy
bin/linuxdeploy "${LINUXDEPLOY_ARGS[@]}"
tar cfvz /out/appdir.tgz AppDir
# bundle AppImage plugin
mkdir -p AppDir/plugins
# cannot add appimage plugin yet, since it won't work on CentOS 6 (at least for now)
# therefore we also need to use appimagetool directly to build an AppImage
# but we can still prepare the AppDir
wget https://github.com/AppImage/AppImageKit/releases/download/continuous/appimagetool-x86_64.AppImage
chmod +x appimagetool-x86_64.AppImage
sed -i 's/AI\x02/\x00\x00\x00/' appimagetool*.AppImage
wget https://github.com/TheAssassin/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-"$ARCH".AppImage
chmod +x linuxdeploy-plugin-appimage-"$ARCH".AppImage
sed -i 's|AI\x02|\x00\x00\x00|' linuxdeploy*.AppImage
./linuxdeploy-plugin-appimage-"$ARCH".AppImage --appimage-extract
mv squashfs-root/ AppDir/plugins/linuxdeploy-plugin-appimage
appimage=linuxdeploy-centos6-x86_64.AppImage
./appimagetool-x86_64.AppImage --appimage-extract
squashfs-root/AppRun AppDir "$appimage" 2>&1
ln -s ../../plugins/linuxdeploy-plugin-appimage/AppRun AppDir/usr/bin/linuxdeploy-plugin-appimage
chown "$OUTDIR_OWNER" "$appimage"
export UPD_INFO="gh-releases-zsync|linuxdeploy|linuxdeploy|continuous|linuxdeploy-$ARCH.AppImage"
export OUTPUT=linuxdeploy-"$ARCH".AppImage
mv "$appimage" /out
# build AppImage using plugin
AppDir/usr/bin/linuxdeploy-plugin-appimage --appdir AppDir/
# rename AppImage to avoid "Text file busy" issues when using it to create another one
mv "$OUTPUT" test.AppImage
# also have to patch our test AppImage, but we can leave the newly produced one untouched
sed -i 's|AI\x02|\x00\x00\x00|' test.AppImage
# verify that the resulting AppImage works
./test.AppImage --appimage-extract-and-run "${LINUXDEPLOY_ARGS[@]}"
# check whether AppImage plugin is found and works
./test.AppImage --appimage-extract-and-run "${LINUXDEPLOY_ARGS[@]}" --output appimage
chown "$OUTDIR_OWNER" "$OUTPUT"
mv "$OUTPUT"* "$OLD_CWD"/
+5 -2
View File
@@ -30,6 +30,8 @@ if [ "$ARCH" == "x86_64" ]; then
EXTRA_CMAKE_ARGS=()
elif [ "$ARCH" == "i386" ]; then
EXTRA_CMAKE_ARGS=("-DCMAKE_TOOLCHAIN_FILE=$REPO_ROOT/cmake/toolchains/i386-linux-gnu.cmake" "-DUSE_SYSTEM_CIMG=OFF")
elif [ "$ARCH" == "arm64" ] && [ "$BUILD_TYPE" == "arm64-native" ]; then
EXTRA_CMAKE_ARGS=()
else
echo "Architecture not supported: $ARCH" 1>&2
exit 1
@@ -75,12 +77,13 @@ mv squashfs-root/ AppDir/plugins/linuxdeploy-plugin-appimage
ln -s ../../plugins/linuxdeploy-plugin-appimage/AppRun AppDir/usr/bin/linuxdeploy-plugin-appimage
export UPD_INFO="gh-releases-zsync|linuxdeploy|linuxdeploy|continuous|linuxdeploy-$ARCH.AppImage"
export OUTPUT="linuxdeploy-devbuild-$ARCH.AppImage"
# build AppImage using plugin
AppDir/usr/bin/linuxdeploy-plugin-appimage --appdir AppDir/
# rename AppImage to avoid "Text file busy" issues when using it to create another one
mv ./linuxdeploy-"$ARCH".AppImage test.AppImage
mv "$OUTPUT" test.AppImage
# verify that the resulting AppImage works
./test.AppImage "${LINUXDEPLOY_ARGS[@]}"
@@ -88,4 +91,4 @@ mv ./linuxdeploy-"$ARCH".AppImage test.AppImage
# check whether AppImage plugin is found and works
./test.AppImage "${LINUXDEPLOY_ARGS[@]}" --output appimage
mv linuxdeploy-"$ARCH".AppImage* "$OLD_CWD"
mv "$OUTPUT"* "$OLD_CWD"/

Some files were not shown because too many files have changed in this diff Show More