You've already forked linuxdeploy
mirror of
https://github.com/encounter/linuxdeploy.git
synced 2026-07-10 12:18:44 -07:00
Compare commits
63 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 18f2d94241 | |||
| 9743988c80 | |||
| 84b614c1ea | |||
| 1035ef726d | |||
| 1c7e768b86 | |||
| a28181d98c | |||
| fcd3ad49db | |||
| cc6310cbbd | |||
| c58d9716b0 | |||
| 3e84f424e7 | |||
| a386ab19fd | |||
| 4f84082155 | |||
| 8aa1bc9d89 | |||
| 56d9d6b540 | |||
| 5165301a44 | |||
| c1452fa870 | |||
| 03cae41d55 | |||
| c10eafe823 | |||
| 4a7301eba5 | |||
| a3cc38d406 | |||
| 144fd2deb0 | |||
| b96389a064 | |||
| b156ffc0cb | |||
| bd052a5b1f | |||
| f06d5e5832 | |||
| a0ace9f75c | |||
| 2b7a5928a5 | |||
| ec862d0af9 | |||
| df61b059d3 | |||
| 5baac459b3 | |||
| c783be934b | |||
| ae6dfcfe21 | |||
| c07025ab8a | |||
| c438d5ee2b | |||
| ee15c88978 | |||
| 80fc055373 | |||
| 5d81258547 | |||
| d57e4750c2 | |||
| ddbca26b1b | |||
| 2e503362a0 | |||
| 7a2390ea95 | |||
| 312287d937 | |||
| a641ae7fac | |||
| b332dc7e7d | |||
| b16329f8ba | |||
| ee6fd2e594 | |||
| 4ee5a903ce | |||
| 852ac4d038 | |||
| eea9a5a9f9 | |||
| b046bef4c9 | |||
| e311bc9217 | |||
| 0cb0223560 | |||
| e7b3a0987a | |||
| efb59d6ea7 | |||
| 39ddfc5c79 | |||
| d5aa361eb4 | |||
| 08a1bf9b69 | |||
| eba0d70576 | |||
| 1a4d9e8130 | |||
| 2b94a4b408 | |||
| dcf4f79059 | |||
| 345fc638b6 | |||
| 8d3284c447 |
@@ -1,3 +1,6 @@
|
||||
cmake-build-*/
|
||||
*build*/
|
||||
.idea/
|
||||
squashfs-root/
|
||||
tests/
|
||||
*.AppImage
|
||||
|
||||
@@ -73,3 +73,6 @@
|
||||
[submodule "lib/boost-integer"]
|
||||
path = lib/boost-integer
|
||||
url = https://github.com/boostorg/integer.git
|
||||
[submodule "lib/CImg"]
|
||||
path = lib/CImg
|
||||
url = https://github.com/dtschump/CImg.git
|
||||
|
||||
+28
-10
@@ -1,19 +1,37 @@
|
||||
language: cpp
|
||||
sudo: required
|
||||
|
||||
addons:
|
||||
apt:
|
||||
update: true
|
||||
packages:
|
||||
- libmagic-dev
|
||||
- cimg-dev
|
||||
- automake # required for patchelf
|
||||
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
|
||||
|
||||
install:
|
||||
- git clone https://github.com/NixOS/patchelf.git
|
||||
- git clone https://github.com/NixOS/patchelf.git -b 0.8
|
||||
- cd patchelf
|
||||
- ./bootstrap.sh
|
||||
- ./configure --prefix=/usr
|
||||
- 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 ..
|
||||
@@ -27,7 +45,7 @@ after_success:
|
||||
# make sure only pushes to rewrite create a new release, otherwise pretend PR and upload to transfer.sh
|
||||
- if [ "$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*.AppImage*
|
||||
- bash upload.sh linuxdeploy-"$ARCH".AppImage*
|
||||
|
||||
branches:
|
||||
except:
|
||||
|
||||
@@ -11,6 +11,7 @@ add_definitions(-DLINUXDEPLOY_VERSION="${LINUXDEPLOY_VERSION}")
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/Modules/")
|
||||
|
||||
set(USE_SYSTEM_BOOST OFF CACHE BOOL "Set to ON to use system boost libraries instead of building up to date boost libraries from source")
|
||||
set(USE_SYSTEM_CIMG ON CACHE BOOL "Set to OFF to use CImg library bundled in lib directory")
|
||||
|
||||
add_subdirectory(lib)
|
||||
|
||||
|
||||
@@ -2,4 +2,100 @@
|
||||
|
||||
AppDir creation and maintenance tool.
|
||||
|
||||
**More info will follow soon!**
|
||||
## About
|
||||
|
||||
AppImages are a well known and quite popular format for distributing applications from developers to end users.
|
||||
|
||||
[appimagetool](https://github.com/AppImage/AppImageKit), the tool creating AppImages, expects directories in a specific format that will then be converted into the final AppImage. This format is called [AppDir](https://github.com/TheAssassin/linuxdeploy/wiki/AppDir-specification). It is not very difficult to understand, but creating AppDirs for arbitrary applications tends to be a very repetitive task. Also, bundling all the dependencies properly can be a quite difficult task. It seems like there is a need for tools which simplify these tasks.
|
||||
|
||||
linuxdeploy is designed to be an AppDir maintenance tool. It provides extensive functionalities to create and bundle AppDirs for applications. It features a plugin system that allows for easy bundling of frameworks and creating output bundles such as AppImages with little effort.
|
||||
|
||||
linuxdeploy was greatly influenced by [linuxdeployqt](https://github.com/probonopd/linuxdeployqt), and while it employs stricter rules on AppDirs, it's more flexible in use. If you use linuxdeployqt at the moment, consider switching to linuxdeploy today!
|
||||
|
||||
|
||||
## Usage
|
||||
|
||||
linuxdeploy, being a tool for creating AppDirs and eventually AppImages, is released as an AppImage itself. Please download and use the AppImage for normal use. If you encounter errors, e.g., when building the tool from source, please try with the AppImage first before [creating an issue](https://github.com/TheAssassin/linuxdeploy/issues/new).
|
||||
|
||||
There are two main ways to use linuxdeploy: Provide the paths to all files you want to bundle manually, or create an FHS-like directory and run linuxdeploy on it.
|
||||
|
||||
Most build systems provide some kind of `make install` functionality that is capable of producing FHS-like directory trees that can be turned into AppDirs:
|
||||
|
||||
```sh
|
||||
# automake
|
||||
./configure --prefix=/usr
|
||||
make install DESTDIR=AppDir
|
||||
|
||||
# cmake
|
||||
mkdir build && cd build
|
||||
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
|
||||
make install DESTDIR=AppDir
|
||||
|
||||
# qmake
|
||||
qmake CONFIG+=release PREFIX=/usr .
|
||||
make install INSTALL_ROOT=AppDir
|
||||
```
|
||||
|
||||
Now, simply run linuxdeploy like `./linuxdeploy*.AppImage --appdir AppDir`.
|
||||
|
||||
Please use `./linuxdeploy*.AppImage --help` to get a list of options supported by linuxdeploy.
|
||||
|
||||
If your build system cannot produce such install trees or you prefer to bundle everything manually, you can also specify the paths to the resources yourself. linuxdeploy provides the following options for this use case:
|
||||
|
||||
```
|
||||
-l[library...],
|
||||
--lib=[library...],
|
||||
--library=[library...] Shared library to deploy
|
||||
-e[executable...],
|
||||
--executable=[executable...] Executable to deploy
|
||||
-d[desktop file...],
|
||||
--desktop-file=[desktop file...] Desktop file to deploy
|
||||
enough for some tests
|
||||
-i[icon file...],
|
||||
--icon-file=[icon file...] Icon to deploy
|
||||
```
|
||||
|
||||
An example run could look like this:
|
||||
|
||||
```bash
|
||||
./linuxdeploy*.AppImage --app-name myapp --appdir AppDir --init-appdir -e myapp -d myapp.desktop -i myapp_64x64.png
|
||||
```
|
||||
|
||||
Of course both approaches can be combined, e.g., you can bundle additional executables with your main app.
|
||||
|
||||
linuxdeploy doesn't mind being run on an AppDir more than once, as it recognize previous runs, and should not break files within the AppDir. This is to allow you debug issues allows you to run linuxdeploy after resolving an issue that it reports.
|
||||
If you ever encounter issues when running linuxdeploy on an existing AppDir, please let us know by [creating an issue](https://github.com/TheAssassin/linuxdeploy/issues/new).
|
||||
|
||||
|
||||
## Plugins
|
||||
|
||||
linuxdeploy features a plugin system. Plugins are separate executables which implement a CLI-based plugin interface ([specification](https://github.com/TheAssassin/linuxdeploy/wiki/Plugin-system)).
|
||||
|
||||
There are two types of plugins: bundling and output plugins. Bundling plugins can be used to add resources to the AppDir. Output plugins turn the AppDir in actual bundles, e.g., AppImages.
|
||||
|
||||
linuxdeploy looks for plugins in the following places:
|
||||
|
||||
- the directory containing the linuxdeploy binary
|
||||
- when using the AppImage: the directory containing the AppImage
|
||||
- the directories in the user's `$PATH`
|
||||
|
||||
You can use `./linuxdeploy*.AppImage --list-plugins` to get a list of all the plugins linuxdeploy has detected on your system.
|
||||
|
||||
linuxdeploy ships with some plugins
|
||||
|
||||
If you want to use a plugin to bundle additional resources, please add `./linuxdeploy*.AppImage --plugin <name>` to your linuxdeploy command. Output plugins can be activated using `./linuxdeploy*.AppImage --output <name>`.
|
||||
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
> I bundled additional resources, but when I try to run them, either the system binary is called or the file is not found.
|
||||
|
||||
linuxdeploy does not change any environment variables such as `$PATH`. Your application **must** search for additional resources such as icon files or executables relative to the main binary.
|
||||
|
||||
## Contact
|
||||
|
||||
The easiest way to get in touch with the developers is to join the IRC chatroom [#AppImage](https://webchat.freenode.net/?channels=appimage) on FreeNode. This is the preferred way for general feedback or questions how to use this application.
|
||||
|
||||
To report problems, please [create an issue](https://github.com/TheAssassin/linuxdeploy/issues/new) on GitHub.
|
||||
|
||||
Contributions welcome! Please feel free to fork this repository and send us a pull request. Even small changes, e.g., in this README, are highly appreciated!
|
||||
|
||||
@@ -1,22 +1,28 @@
|
||||
# required for PNG imported target
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
message(STATUS "Searching for CImg")
|
||||
|
||||
find_path(CIMG_H_DIR
|
||||
NAMES CImg.h
|
||||
HINTS ${CMAKE_INSTALL_PREFIX}
|
||||
PATH_SUFFIXES include include/linux
|
||||
)
|
||||
|
||||
if(NOT CIMG_H_DIR)
|
||||
message(FATAL_ERROR "CImg.h not found")
|
||||
endif()
|
||||
|
||||
find_package(PNG REQUIRED)
|
||||
find_package(JPEG REQUIRED)
|
||||
|
||||
add_library(CImg INTERFACE IMPORTED)
|
||||
if(NOT USE_SYSTEM_CIMG)
|
||||
message(STATUS "Using bundled CImg library")
|
||||
|
||||
set(CIMG_H_DIR "${PROJECT_SOURCE_DIR}/lib/CImg/")
|
||||
else()
|
||||
message(STATUS "Searching for CImg")
|
||||
|
||||
find_path(CIMG_H_DIR
|
||||
NAMES CImg.h
|
||||
HINTS ${CMAKE_INSTALL_PREFIX}
|
||||
PATH_SUFFIXES include include/linux
|
||||
)
|
||||
|
||||
if(NOT CIMG_H_DIR)
|
||||
message(FATAL_ERROR "CImg.h not found")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_library(CImg INTERFACE)
|
||||
set_property(TARGET CImg PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CIMG_H_DIR};${JPEG_INCLUDE_DIR}")
|
||||
set_property(TARGET CImg PROPERTY INTERFACE_LINK_LIBRARIES "PNG::PNG;${JPEG_LIBRARIES}")
|
||||
set_property(TARGET CImg PROPERTY INTERFACE_COMPILE_DEFINITIONS "cimg_display=0;cimg_use_png=1;cimg_use_jpeg=1")
|
||||
|
||||
@@ -3,20 +3,17 @@ cmake_minimum_required(VERSION 3.3)
|
||||
|
||||
message(STATUS "Searching for libmagic")
|
||||
|
||||
# on Debian-ish systems, libmagic depends on zlib
|
||||
find_package(ZLIB REQUIRED)
|
||||
find_library(LIBMAGIC_LIBRARIES magic)
|
||||
|
||||
find_library(LIBMAGIC_A libmagic.a)
|
||||
|
||||
if(NOT LIBMAGIC_A)
|
||||
message(FATAL_ERROR "libmagic.a not found")
|
||||
if(NOT LIBMAGIC_LIBRARIES)
|
||||
message(FATAL_ERROR "libmagic not found")
|
||||
endif()
|
||||
|
||||
find_path(LIBMAGIC_MAGIC_H_DIR
|
||||
NAMES magic.h
|
||||
HINTS ${CMAKE_INSTALL_PREFIX}
|
||||
PATH_SUFFIXES include include/linux
|
||||
)
|
||||
)
|
||||
|
||||
if(NOT LIBMAGIC_MAGIC_H_DIR)
|
||||
message(FATAL_ERROR "magic.h not found")
|
||||
@@ -24,4 +21,4 @@ endif()
|
||||
|
||||
add_library(libmagic_static INTERFACE IMPORTED)
|
||||
set_property(TARGET libmagic_static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${LIBMAGIC_MAGIC_H_DIR})
|
||||
set_property(TARGET libmagic_static PROPERTY INTERFACE_LINK_LIBRARIES ${LIBMAGIC_A};ZLIB::ZLIB)
|
||||
set_property(TARGET libmagic_static PROPERTY INTERFACE_LINK_LIBRARIES ${LIBMAGIC_LIBRARIES})
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
set(CMAKE_SYSTEM_NAME Linux CACHE STRING "" FORCE)
|
||||
set(CMAKE_SYSTEM_PROCESSOR i386 CACHE STRING "" FORCE)
|
||||
|
||||
set(CMAKE_C_FLAGS "-m32" CACHE STRING "" FORCE)
|
||||
set(CMAKE_CXX_FLAGS "-m32" CACHE STRING "" FORCE)
|
||||
@@ -42,6 +42,13 @@ namespace linuxdeploy {
|
||||
// the dependencies are copied to the normal destination, though
|
||||
bool deployLibrary(const boost::filesystem::path& path, const boost::filesystem::path& destination = "");
|
||||
|
||||
// force deploy shared library
|
||||
//
|
||||
// works like deployLibrary, except that it doesn't check the excludelist
|
||||
// this is useful to deploy libraries and their dependencies that are blacklisted and would otherwise not be deployed
|
||||
// the excludelist check is only disabled for the current library, and will be enabled for the dependencies again
|
||||
bool forceDeployLibrary(const boost::filesystem::path& path, const boost::filesystem::path& destination = "");
|
||||
|
||||
// deploy executable
|
||||
bool deployExecutable(const boost::filesystem::path& path, const boost::filesystem::path& destination = "");
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <poll.h>
|
||||
|
||||
// library headers
|
||||
#include <boost/filesystem.hpp>
|
||||
@@ -22,6 +23,7 @@ namespace linuxdeploy {
|
||||
class PluginBase<API_LEVEL>::PrivateData {
|
||||
public:
|
||||
const boost::filesystem::path pluginPath;
|
||||
std::string name;
|
||||
int apiLevel;
|
||||
PLUGIN_TYPE pluginType;
|
||||
|
||||
@@ -33,6 +35,10 @@ namespace linuxdeploy {
|
||||
|
||||
apiLevel = getApiLevelFromExecutable();
|
||||
pluginType = getPluginTypeFromExecutable();
|
||||
|
||||
boost::cmatch res;
|
||||
boost::regex_match(path.filename().c_str(), res, PLUGIN_EXPR);
|
||||
name = res[1].str();
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -128,10 +134,10 @@ namespace linuxdeploy {
|
||||
}
|
||||
log << std::endl;
|
||||
|
||||
auto process = subprocess::Popen(args);
|
||||
auto process = subprocess::Popen(args, subprocess::output{stdout}, subprocess::error{stderr});
|
||||
process.wait();
|
||||
|
||||
auto retcode = process.wait();
|
||||
return retcode;
|
||||
return process.retcode();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
// library includes
|
||||
#include <boost/filesystem.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
// local includes
|
||||
#include "linuxdeploy/core/log.h"
|
||||
@@ -18,6 +19,11 @@ namespace linuxdeploy {
|
||||
OUTPUT_TYPE,
|
||||
};
|
||||
|
||||
/*
|
||||
* Official regular expression to check filenames for plugins
|
||||
*/
|
||||
static const boost::regex PLUGIN_EXPR(R"(^linuxdeploy-plugin-([^\s\.-]+)(?:-[^\.]+)?(?:\..+)?$)");
|
||||
|
||||
/*
|
||||
* Plugin interface.
|
||||
*/
|
||||
|
||||
@@ -64,6 +64,14 @@ namespace linuxdeploy {
|
||||
return strncmp(string.c_str(), prefix.c_str(), prefix.size()) == 0;
|
||||
}
|
||||
|
||||
static bool stringEndsWith(const std::string& string, const std::string& suffix) {
|
||||
// sanity check
|
||||
if (string.size() < suffix.size())
|
||||
return false;
|
||||
|
||||
return strcmp(string.c_str() + (string.size() - suffix.size()), suffix.c_str()) == 0;
|
||||
}
|
||||
|
||||
static bool stringContains(const std::string& string, const std::string& part) {
|
||||
return string.find(part) != std::string::npos;
|
||||
}
|
||||
Submodule
+1
Submodule lib/CImg added at 631cb96120
+18
-18
@@ -15,74 +15,74 @@ target_link_libraries(test_cpp_feather_ini_parser PRIVATE cpp-feather-ini-parser
|
||||
add_test(test_cpp_feather_ini_parser test_cpp_feather_ini_parser)
|
||||
|
||||
if(NOT USE_SYSTEM_BOOST)
|
||||
add_library(boost_config IMPORTED INTERFACE)
|
||||
add_library(boost_config INTERFACE)
|
||||
set_property(TARGET boost_config PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-config/include>")
|
||||
|
||||
add_library(boost_utility IMPORTED INTERFACE)
|
||||
add_library(boost_utility INTERFACE)
|
||||
set_property(TARGET boost_utility PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-utility/include>")
|
||||
set_property(TARGET boost_utility PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_predef IMPORTED INTERFACE)
|
||||
add_library(boost_predef INTERFACE)
|
||||
set_property(TARGET boost_predef PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-predef/include>")
|
||||
set_property(TARGET boost_predef PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_assert IMPORTED INTERFACE)
|
||||
add_library(boost_assert INTERFACE)
|
||||
set_property(TARGET boost_assert PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-assert/include>")
|
||||
set_property(TARGET boost_assert PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_core IMPORTED INTERFACE)
|
||||
add_library(boost_core INTERFACE)
|
||||
set_property(TARGET boost_core PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-core/include>")
|
||||
set_property(TARGET boost_core PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_type_traits IMPORTED INTERFACE)
|
||||
add_library(boost_type_traits INTERFACE)
|
||||
set_property(TARGET boost_type_traits PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-type_traits/include>")
|
||||
set_property(TARGET boost_type_traits PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_iterator IMPORTED INTERFACE)
|
||||
add_library(boost_iterator INTERFACE)
|
||||
set_property(TARGET boost_iterator PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-iterator/include>")
|
||||
set_property(TARGET boost_iterator PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_mpl IMPORTED INTERFACE)
|
||||
add_library(boost_mpl INTERFACE)
|
||||
set_property(TARGET boost_mpl PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-mpl/include>")
|
||||
set_property(TARGET boost_mpl PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_preprocessor IMPORTED INTERFACE)
|
||||
add_library(boost_preprocessor INTERFACE)
|
||||
set_property(TARGET boost_preprocessor PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-preprocessor/include>")
|
||||
set_property(TARGET boost_preprocessor PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_static_assert IMPORTED INTERFACE)
|
||||
add_library(boost_static_assert INTERFACE)
|
||||
set_property(TARGET boost_static_assert PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-static_assert/include>")
|
||||
set_property(TARGET boost_static_assert PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_detail IMPORTED INTERFACE)
|
||||
add_library(boost_detail INTERFACE)
|
||||
set_property(TARGET boost_detail PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-detail/include>")
|
||||
set_property(TARGET boost_detail PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_smart_ptr IMPORTED INTERFACE)
|
||||
add_library(boost_smart_ptr INTERFACE)
|
||||
set_property(TARGET boost_smart_ptr PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-smart_ptr/include>")
|
||||
set_property(TARGET boost_smart_ptr PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_throw_exception IMPORTED INTERFACE)
|
||||
add_library(boost_throw_exception INTERFACE)
|
||||
set_property(TARGET boost_throw_exception PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-throw_exception/include>")
|
||||
set_property(TARGET boost_throw_exception PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_io IMPORTED INTERFACE)
|
||||
add_library(boost_io INTERFACE)
|
||||
set_property(TARGET boost_io PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-io/include>")
|
||||
set_property(TARGET boost_io PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_container_hash IMPORTED INTERFACE)
|
||||
add_library(boost_container_hash INTERFACE)
|
||||
set_property(TARGET boost_container_hash PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-container_hash/include>")
|
||||
set_property(TARGET boost_container_hash PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_functional IMPORTED INTERFACE)
|
||||
add_library(boost_functional INTERFACE)
|
||||
set_property(TARGET boost_functional PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-functional/include>")
|
||||
set_property(TARGET boost_functional PROPERTY INTERFACE_LINK_LIBRARIES "boost_config;boost_container_hash")
|
||||
|
||||
add_library(boost_range IMPORTED INTERFACE)
|
||||
add_library(boost_range INTERFACE)
|
||||
set_property(TARGET boost_range PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-range/include>")
|
||||
set_property(TARGET boost_range PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
add_library(boost_integer IMPORTED INTERFACE)
|
||||
add_library(boost_integer INTERFACE)
|
||||
set_property(TARGET boost_integer PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-integer/include>")
|
||||
set_property(TARGET boost_integer PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
|
||||
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
# 3.5 is required for imported boost targets
|
||||
cmake_minimum_required(VERSION 3.5)
|
||||
|
||||
# globally include own includes
|
||||
include_directories(${PROJECT_SOURCE_DIR}/include)
|
||||
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
# 3.5 is required for imported boost targets
|
||||
# 3.6 is required for the PkgConfig module's IMPORTED_TARGET library feature
|
||||
cmake_minimum_required(VERSION 3.6)
|
||||
cmake_minimum_required(VERSION 2.8)
|
||||
|
||||
# include headers to make CLion happy
|
||||
file(GLOB HEADERS ${PROJECT_SOURCE_DIR}/include/linuxdeploy/core/*.h)
|
||||
|
||||
+53
-29
@@ -13,7 +13,7 @@
|
||||
#include "linuxdeploy/core/appdir.h"
|
||||
#include "linuxdeploy/core/elf.h"
|
||||
#include "linuxdeploy/core/log.h"
|
||||
#include "util.h"
|
||||
#include "linuxdeploy/util/util.h"
|
||||
#include "excludelist.h"
|
||||
|
||||
using namespace linuxdeploy::core;
|
||||
@@ -144,34 +144,40 @@ namespace linuxdeploy {
|
||||
if (!success)
|
||||
return false;
|
||||
|
||||
while (!stripOperations.empty()) {
|
||||
const auto& filePath = *(stripOperations.begin());
|
||||
if (getenv("NO_STRIP") != nullptr) {
|
||||
ldLog() << LD_WARNING << "$NO_STRIP environment variable detected, not stripping binaries" << std::endl;
|
||||
stripOperations.clear();
|
||||
} else {
|
||||
while (!stripOperations.empty()) {
|
||||
const auto& filePath = *(stripOperations.begin());
|
||||
|
||||
if (util::stringStartsWith(elf::ElfFile(filePath).getRPath(), "$")) {
|
||||
ldLog() << LD_WARNING << "Not calling strip on binary" << filePath << LD_NO_SPACE << ": rpath starts with $" << std::endl;
|
||||
} else {
|
||||
ldLog() << "Calling strip on library" << filePath << std::endl;
|
||||
if (util::stringStartsWith(elf::ElfFile(filePath).getRPath(), "$")) {
|
||||
ldLog() << LD_WARNING << "Not calling strip on binary" << filePath << LD_NO_SPACE
|
||||
<< ": rpath starts with $" << std::endl;
|
||||
} else {
|
||||
ldLog() << "Calling strip on library" << filePath << std::endl;
|
||||
|
||||
std::map<std::string, std::string> env;
|
||||
env.insert(std::make_pair(std::string("LC_ALL"), std::string("C")));
|
||||
std::map<std::string, std::string> env;
|
||||
env.insert(std::make_pair(std::string("LC_ALL"), std::string("C")));
|
||||
|
||||
subprocess::Popen proc(
|
||||
{getStripPath().c_str(), filePath.c_str()},
|
||||
subprocess::output(subprocess::PIPE),
|
||||
subprocess::error(subprocess::PIPE),
|
||||
subprocess::environment(env)
|
||||
);
|
||||
subprocess::Popen proc(
|
||||
{getStripPath().c_str(), filePath.c_str()},
|
||||
subprocess::output(subprocess::PIPE),
|
||||
subprocess::error(subprocess::PIPE),
|
||||
subprocess::environment(env)
|
||||
);
|
||||
|
||||
std::string err = proc.communicate().second.buf.data();
|
||||
std::string err = proc.communicate().second.buf.data();
|
||||
|
||||
if (proc.retcode() != 0 &&
|
||||
!util::stringContains(err, "Not enough room for program headers")) {
|
||||
ldLog() << LD_ERROR << "Strip call failed:" << err << std::endl;
|
||||
success = false;
|
||||
if (proc.retcode() != 0 &&
|
||||
!util::stringContains(err, "Not enough room for program headers")) {
|
||||
ldLog() << LD_ERROR << "Strip call failed:" << err << std::endl;
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stripOperations.erase(stripOperations.begin());
|
||||
stripOperations.erase(stripOperations.begin());
|
||||
}
|
||||
}
|
||||
|
||||
if (!success)
|
||||
@@ -327,14 +333,15 @@ namespace linuxdeploy {
|
||||
return patchelfPath;
|
||||
}
|
||||
|
||||
bool deployLibrary(const bf::path& path, int recursionLevel = 0, const bf::path& destination = "") {
|
||||
bool deployLibrary(const bf::path& path, int recursionLevel = 0, bool forceDeploy = false,const bf::path &destination = bf::path()) {
|
||||
auto logPrefix = getLogPrefix(recursionLevel);
|
||||
|
||||
if (hasBeenVisitedAlready(path)) {
|
||||
if (!forceDeploy && hasBeenVisitedAlready(path)) {
|
||||
ldLog() << LD_DEBUG << logPrefix << LD_NO_SPACE << "File has been visited already:" << path << std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static auto isInExcludelist = [&logPrefix](const bf::path& fileName) {
|
||||
for (const auto& excludePattern : generatedExcludelist) {
|
||||
// simple string match is faster than using fnmatch
|
||||
@@ -356,7 +363,7 @@ namespace linuxdeploy {
|
||||
return false;
|
||||
};
|
||||
|
||||
if (isInExcludelist(path.filename())) {
|
||||
if (!forceDeploy && isInExcludelist(path.filename())) {
|
||||
ldLog() << logPrefix << LD_NO_SPACE << "Skipping deployment of blacklisted library" << path << std::endl;
|
||||
|
||||
// mark file as visited
|
||||
@@ -372,6 +379,12 @@ namespace linuxdeploy {
|
||||
|
||||
auto destinationPath = destination.empty() ? appDirPath / "usr/lib/" : destination;
|
||||
|
||||
// not sure whether this is 100% bullet proof, but it simulates the cp command behavior
|
||||
if (destinationPath.string().back() == '/' || bf::is_directory(destinationPath)) {
|
||||
destinationPath /= path.filename();
|
||||
}
|
||||
|
||||
|
||||
deployFile(path, destinationPath);
|
||||
deployCopyrightFiles(path, logPrefix);
|
||||
|
||||
@@ -393,8 +406,9 @@ namespace linuxdeploy {
|
||||
rpath = "$ORIGIN/" + relPath.string() + ":$ORIGIN";
|
||||
}
|
||||
|
||||
setElfRPathOperations[destinationPath / path.filename()] = rpath;
|
||||
stripOperations.insert(destinationPath / path.filename());
|
||||
|
||||
setElfRPathOperations[destinationPath] = rpath;
|
||||
stripOperations.insert(destinationPath);
|
||||
|
||||
if (!deployElfDependencies(path, recursionLevel))
|
||||
return false;
|
||||
@@ -578,7 +592,11 @@ namespace linuxdeploy {
|
||||
}
|
||||
|
||||
bool AppDir::deployLibrary(const bf::path& path, const bf::path& destination) {
|
||||
return d->deployLibrary(path, 0, destination);
|
||||
return d->deployLibrary(path, 0, false, destination);
|
||||
}
|
||||
|
||||
bool AppDir::forceDeployLibrary(const bf::path& path, const bf::path& destination) {
|
||||
return d->deployLibrary(path, 0, true, destination);
|
||||
}
|
||||
|
||||
bool AppDir::deployExecutable(const bf::path& path, const boost::filesystem::path& destination) {
|
||||
@@ -683,7 +701,13 @@ namespace linuxdeploy {
|
||||
for (const auto& iconPath : foundIconPaths) {
|
||||
ldLog() << LD_DEBUG << "Icon found:" << iconPath << std::endl;
|
||||
|
||||
if (iconPath.stem() == iconName) {
|
||||
const bool matchesFilenameWithExtension = iconPath.filename() == iconName;
|
||||
|
||||
if (iconPath.stem() == iconName || 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())) {
|
||||
|
||||
+6
-2
@@ -8,7 +8,7 @@
|
||||
// local headers
|
||||
#include "linuxdeploy/core/elf.h"
|
||||
#include "linuxdeploy/core/log.h"
|
||||
#include "util.h"
|
||||
#include "linuxdeploy/util/util.h"
|
||||
|
||||
using namespace linuxdeploy::core::log;
|
||||
|
||||
@@ -99,7 +99,11 @@ namespace linuxdeploy {
|
||||
util::trim(libraryPath);
|
||||
paths.push_back(bf::absolute(libraryPath));
|
||||
} else {
|
||||
ldLog() << LD_DEBUG << "Invalid ldd output: " << line << std::endl;
|
||||
if (util::stringContains("not found", line)) {
|
||||
ldLog() << LD_ERROR << "Could not find dependency:" << line << std::endl;
|
||||
} else {
|
||||
ldLog() << LD_DEBUG << "Invalid ldd output: " << line << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+26
-2
@@ -11,9 +11,11 @@
|
||||
#include "linuxdeploy/core/elf.h"
|
||||
#include "linuxdeploy/core/log.h"
|
||||
#include "linuxdeploy/plugin/plugin.h"
|
||||
#include "linuxdeploy/util/util.h"
|
||||
|
||||
using namespace linuxdeploy::core;
|
||||
using namespace linuxdeploy::core::log;
|
||||
using namespace linuxdeploy::util;
|
||||
|
||||
namespace bf = boost::filesystem;
|
||||
|
||||
@@ -117,7 +119,7 @@ int main(int argc, char** argv) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!appDir.deployLibrary(libraryPath)) {
|
||||
if (!appDir.forceDeployLibrary(libraryPath)) {
|
||||
std::cerr << "Failed to deploy library: " << libraryPath << std::endl;
|
||||
return 1;
|
||||
}
|
||||
@@ -245,10 +247,32 @@ int main(int argc, char** argv) {
|
||||
|
||||
auto deployedDesktopFiles = appDir.deployedDesktopFiles();
|
||||
|
||||
desktopfile::DesktopFile desktopFile;
|
||||
|
||||
if (deployedDesktopFiles.empty()) {
|
||||
ldLog() << LD_WARNING << "Could not find desktop file in AppDir, cannot create links for AppRun, desktop file and icon in AppDir root" << std::endl;
|
||||
} else {
|
||||
auto& desktopFile = deployedDesktopFiles[0];
|
||||
if (!appName.Get().empty()) {
|
||||
auto desktopFileMatchingName = std::find_if(
|
||||
deployedDesktopFiles.begin(),
|
||||
deployedDesktopFiles.end(),
|
||||
[&appName](const desktopfile::DesktopFile& desktopFile) {
|
||||
auto fileName = desktopFile.path().filename().string();
|
||||
return stringStartsWith(fileName, appName.Get()) && stringEndsWith(fileName, ".desktop");
|
||||
}
|
||||
);
|
||||
|
||||
if (desktopFileMatchingName != deployedDesktopFiles.end()) {
|
||||
desktopFile = *desktopFileMatchingName;
|
||||
ldLog() << "Found desktop file matching app name:" << desktopFile.path() << std::endl;
|
||||
} else {
|
||||
desktopFile = deployedDesktopFiles[0];
|
||||
ldLog() << LD_WARNING << "Could not find suitable desktop file for given app name" << appName << LD_NO_SPACE << ", using first desktop file found:" << desktopFile.path() << std::endl;
|
||||
}
|
||||
} else {
|
||||
desktopFile = deployedDesktopFiles[0];
|
||||
ldLog() << LD_WARNING << "App name not specified, using first desktop file found:" << desktopFile.path() << std::endl;
|
||||
}
|
||||
|
||||
ldLog() << "Deploying desktop file:" << desktopFile.path() << std::endl;
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user