100 Commits

Author SHA1 Message Date
TheAssassin 6a952b57f9 Make custom AppRun files executable
This eliminates the need for users to make the files executable
before running linuxdeploy.
2019-06-28 21:40:14 +02:00
TheAssassin 8fbe191d7a Fix APPIMAGE_EXTRACT_AND_RUN support for plugins, mk. 1 2019-06-28 20:18:51 +02:00
TheAssassin 2a1127d7e8 Show acceptable icon sizes in error message
CC #75.
2019-05-24 23:25:03 +02:00
TheAssassin 3f81577b04 Fix missing newline in error messages 2019-05-24 22:49:19 +02:00
TheAssassin 834b467a41 Fix data printed in error message 2019-05-24 22:48:53 +02:00
TheAssassin 46ccb8965d Add missing valid resolutions (CC #75) 2019-05-24 16:19:36 +02:00
TheAssassin 5c3a51fd48 Merge pull request #71 from dbarach/master
Add a workspace sanity check
2019-03-27 17:12:19 +01:00
Dave Barach 44cb9466b3 Merge branch 'master' of https://github.com/dbarach/linuxdeploy
Signed-off-by: Dave Barach <dave@barachs.net>
2019-03-27 11:08:11 -04:00
Dave Barach 1dfcab8556 Add a workspace sanity check
Check to make sure that one source file in one of the git submodules
is present. If not, throw a fatal error which explains what probably
went wrong, and how to fix it:

"Missing submodule(s), please 'git clone --recurse-submodules...'"

Signed-off-by: Dave Barach <dave@barachs.net>
2019-03-27 11:03:25 -04:00
Dave Barach e62e8d8396 Add a workspace sanity check
Check to make sure that one source file in one of the git submodules
is present. If not, throw a fatal error which explains what probably
went wrong, and how to fix it:

"Missing submodule(s), please 'git clone --recurse-submodules...'"

Signed-off-by: Dave Barach <dave@barachs.net>
2019-03-27 10:23:47 -04:00
TheAssassin 875842ee3b Fix linking issues 2019-03-21 15:13:08 +01:00
TheAssassin a4fe77305d Reduce redundancy when adding boost header-only libs 2019-03-21 11:51:06 +01:00
TheAssassin 4f44dcf954 Fix Docker build script path issue 2019-03-21 11:28:15 +01:00
TheAssassin 44b234734b Upload CentOS 6 binaries 2019-03-21 11:27:02 +01:00
TheAssassin 871f1d6e99 Fix permissions 2019-03-21 11:20:45 +01:00
TheAssassin f06643ea5f Experimental CentOS 6 build 2019-03-21 11:13:44 +01:00
TheAssassin 6baa443fd7 appimagetool is being annoying 2019-03-21 10:32:17 +01:00
TheAssassin 77c52883f1 Remove deprecated debug code 2019-03-20 17:25:13 +01:00
TheAssassin 157861d236 Make symlinking work for older versions of ln, too 2019-03-20 17:23:14 +01:00
TheAssassin 32dca18eee We don't use exceptions for error communication 2019-03-20 17:22:46 +01:00
TheAssassin 1f498772b4 Properly handle nonexisting files 2019-02-23 18:01:47 +01:00
TheAssassin f9fc51a832 Improve search for patchelf
CC https://github.com/linuxdeploy/linuxdeploy-plugin-qt/issues/24.
2019-02-20 13:13:34 +01:00
TheAssassin a3e06e0024 Statically link desktopfile library 2019-02-07 00:46:59 +01:00
TheAssassin 956a253428 Return final deployment path
deployFile allows for specifying a directory as destination, and copies
files into there, simulating the behavior of tools like cp. To do that,
it creates the directory, then appends the filename of the input file
to it and uses that as destination for the "copy file" call.

It's pretty handy for some applications to get the full path of the
new file returned by this method directly (doesn't have to implement
this concatenation more than once).
2019-02-06 23:23:48 +01:00
TheAssassin ce6597fb9d Better handle debug-symbols-only ELF files 2019-01-29 01:00:36 +01:00
TheAssassin 028d85a070 Explicitly disable all copy/move(-assignment) behavior 2019-01-29 00:03:35 +01:00
TheAssassin 8df605cb19 Use shared pointer to manage PImpl object 2019-01-29 00:02:49 +01:00
TheAssassin 3a0870842c Update linuxdeploy-desktopfile 2019-01-28 16:52:20 +01:00
TheAssassin 1510d0c333 Update README.md
[ci skip]
2019-01-07 15:45:43 +01:00
TheAssassin 7c8ab1c773 Fix desktop file deployment 2018-12-22 23:26:28 +01:00
TheAssassin 5374e7ece9 Switch to extracted desktop file library 2018-12-22 23:09:04 +01:00
TheAssassin 6b715c691a Give test case more suitable name 2018-12-22 23:02:39 +01:00
TheAssassin 78f33a7190 Move linuxdeploy-specific helper out of desktop file class 2018-12-22 23:02:15 +01:00
TheAssassin 3df27ba175 Add proper desktop file
The auto-generated desktop file does trigger integration tools like
AppImageLauncher, this one shows it's a CLI tool and should just be
launched now.
2018-12-21 19:08:33 +01:00
TheAssassin 2ea9a367b5 Check whether parsing with comments is supported 2018-12-21 19:08:33 +01:00
TheAssassin 673ccf5691 Improve simple desktop file test 2018-12-21 19:08:33 +01:00
TheAssassin d743e11486 Merge pull request #63 from linuxdeploy/issue-62
Fix handling of localized desktop file entries
2018-12-09 16:13:06 +01:00
TheAssassin cddefc3806 Validate some constraints on localized keys 2018-12-06 12:09:18 +01:00
TheAssassin 1f5315926d Increase readability 2018-12-06 12:08:51 +01:00
TheAssassin a12f3ac0fe Improve error message 2018-12-06 11:56:21 +01:00
TheAssassin 640b756a7f Temporarily allow localization brackets in key names
Must be revised when introducing proper localization support.
2018-12-06 11:49:14 +01:00
TheAssassin d486f936e2 Test localized keys support
This is the unit test that was missing to cover the use case described
in #69.
2018-12-06 11:47:25 +01:00
TheAssassin b7faefdc56 Merge pull request #60 from linuxdeploy/issue-59
Ship 32-bit strip binary
2018-11-24 00:44:39 +01:00
TheAssassin 4585cb1a28 Download known working version of strip for i386, mk. 2 2018-11-24 00:34:38 +01:00
TheAssassin 23c85c732a Download known working version of strip for i386 2018-11-24 00:04:40 +01:00
TheAssassin b3e259bda1 Merge branch 'master' into issue-59 2018-11-23 22:08:37 +01:00
TheAssassin d42abe363c Merge pull request #61 from linuxdeploy/debug-desktopfile-unit-tests-in-release-builds
Fix desktop file parser unit test failures
2018-11-23 22:08:03 +01:00
TheAssassin ef90b09c79 Fix remaining issues with usage of assert 2018-11-23 20:52:54 +01:00
TheAssassin ce097235f2 Note for self: -O1+ strips out expressions surrounded by assert() 2018-11-23 18:05:56 +01:00
TheAssassin d65574544f Ship 32-bit strip binary, mk. 3 2018-11-23 17:55:53 +01:00
TheAssassin b38612d07e Ship 32-bit strip binary, mk. 2 2018-11-23 17:17:38 +01:00
TheAssassin 9cddf75449 Ship 32-bit strip binary 2018-11-23 16:32:43 +01:00
TheAssassin b974f44ffd Debug desktop file unit tests, mk.1
They're only broken on non-debug builds, so it's quite likely the
optimizations break the code.
2018-11-21 00:03:20 +01:00
TheAssassin ecaeda4533 Deactivate unit tests that fail for no apparent reason on Travis CI
Will re-enable and debug them eventually. Right now, they prevent
binaries from being published, which is really a problem.
2018-11-19 22:25:20 +01:00
TheAssassin ccfd05b5e0 Improve DesktopFile's comparison operators 2018-11-19 22:12:14 +01:00
TheAssassin 6cf9bc55a7 Fix comparison editor 2018-11-19 22:06:29 +01:00
TheAssassin 1e3e074f35 Properly copy desktop file reader 2018-11-19 22:06:08 +01:00
TheAssassin 7b16864dbe Add missing return statement 2018-11-19 21:51:26 +01:00
TheAssassin 0b5ab2fc36 Fix return type of setter 2018-11-19 21:51:26 +01:00
TheAssassin b3d0e7f20f Merge pull request #57 from linuxdeploy/fix-plugin-detection
Fix plugin detection
2018-11-19 21:09:23 +01:00
TheAssassin 132931772c Fix directory check 2018-11-19 20:52:45 +01:00
TheAssassin 6f7a2fd54a Reduce verbosity of debug logging related to plugin detection 2018-11-19 20:50:09 +01:00
TheAssassin c4258759b4 Make sure directories aren't falsely recognized as plugins 2018-11-19 20:48:04 +01:00
TheAssassin 786a24cb25 Fix CMake syntax 2018-11-16 00:25:27 +01:00
TheAssassin 35f1acf00d Cleaning up coverage data after creating them makes no sense
The cleanup shall take place before running the test binaries which
create the new data, not afterwards.
2018-11-16 00:23:03 +01:00
TheAssassin be0a891770 Improve test fixture names 2018-11-15 23:45:42 +01:00
TheAssassin 92a1370b30 Be able to use EXPECT_EQ with DesktopFile objects
GoogleTest internally uses operator==(first, second) instead of
first.operator==(second). By implementing the operators outside the
classes, GoogleTest can be made happy.
2018-11-15 23:36:04 +01:00
TheAssassin 541da1b573 Test (in)equality operators 2018-11-15 23:32:36 +01:00
TheAssassin f274de8045 Make sure default keys don't overwrite existing ones 2018-11-15 21:24:08 +01:00
TheAssassin 6a951558ce Use assert to check for impossible scenarios 2018-11-15 21:23:43 +01:00
TheAssassin a4b13a1916 Clean up coverage data before new run
This makes sure that reports on subsequent runs are accurate.
2018-11-15 21:19:22 +01:00
TheAssassin 1c4e4a3888 Remove redundant setters/getters 2018-11-15 20:53:16 +01:00
TheAssassin e4bf795211 No need for a string conversion operator
Doesn't make sense here anyway.
2018-11-15 20:44:43 +01:00
TheAssassin e994eacfa0 Prevent unnecessary log messages in unit tests 2018-11-15 19:08:03 +01:00
TheAssassin beb2ee15be Don't use exceptions to detect abnormal behavior
https://isocpp.org/wiki/faq/exceptions#why-not-exceptions
2018-11-15 18:48:58 +01:00
TheAssassin 2e1a37ccf5 Fix path to test data 2018-11-15 18:05:08 +01:00
TheAssassin 520ac6de9b Reduce amount of implicit behavior in desktop file parser 2018-11-15 18:03:46 +01:00
TheAssassin 1bcdcab057 Restructure desktop file tests, build single binary 2018-11-15 17:58:02 +01:00
TheAssassin 1d9c907ec3 Merge pull request #55 from linuxdeploy/test_desktopfile_parser_conformance
Test desktopfile parser conformance
2018-11-15 17:51:06 +01:00
TheAssassin 3e584f5551 Merge branch 'master' into test_desktopfile_parser_conformance 2018-11-15 17:21:23 +01:00
TheAssassin f7975f1b80 Use return types with guaranteed sizes
This will ensure the conversions work equally on both 32-bit platforms
(int == long on 32-bit Linux systems, on 64 bit long > int).
2018-11-15 17:19:42 +01:00
TheAssassin 4af76a92c5 Fix duplicate key detection 2018-11-15 13:41:53 +01:00
TheAssassin b6f5f371b6 Avoid copying data more often than necessary c 2018-11-15 13:40:22 +01:00
TheAssassin d10e0614a1 Increase build speed of tests 2018-11-15 13:39:17 +01:00
TheAssassin 4ffa1a66ae Improve code style 2018-11-15 13:22:41 +01:00
TheAssassin 9707b81931 Fix basic format header checks 2018-11-15 13:14:31 +01:00
TheAssassin 21b12cc6b6 Use EXPECT instead of ASSERT 2018-11-15 13:01:10 +01:00
TheAssassin ae61f6b9d8 Update README.md 2018-11-15 01:35:09 +01:00
TheAssassin b43b04f693 Check for valid and invalid keys (spec/basic format) 2018-11-15 01:29:14 +01:00
TheAssassin 61fb8bebdb Fix execution of desktop file tests 2018-11-15 00:58:56 +01:00
TheAssassin 002ba4a496 Split two checks to make sure they're tested separately
Otherwise, one test case is always uncovered (either the first one
passes and the second one triggers, or the first one triggers and the
second one is never tested).
2018-11-14 11:22:38 +01:00
TheAssassin 244d82fede Test behavior on lines with multiple = characters 2018-11-14 11:19:02 +01:00
TheAssassin 9f8121ebff Check whether invalid lines are recognized 2018-11-14 11:16:35 +01:00
TheAssassin 80adfa8872 Recognize broken section headings, mk. 4 2018-11-14 11:14:24 +01:00
TheAssassin 4a07c8151e Make sure errors are recognized in all sections, not just the first one 2018-11-14 11:10:34 +01:00
TheAssassin ded20c162d Recognize broken section headings, mk. 3 2018-11-14 10:59:17 +01:00
TheAssassin bf152a509b Recognize broken section headings, mk. 2 2018-11-14 10:46:48 +01:00
TheAssassin dc8f446ca4 Recognize broken section headings, mk. 1 2018-11-14 10:41:47 +01:00
TheAssassin fbc1d78122 Use custom exceptions for error handling 2018-11-14 10:31:41 +01:00
TheAssassin 9b2ff305e0 Merge pull request #52 from linuxdeploy/generate-coverage-reports
Generate coverage reports
2018-11-10 19:54:05 +01:00
46 changed files with 405 additions and 1950 deletions
+3 -18
View File
@@ -76,24 +76,9 @@
[submodule "lib/googletest"]
path = lib/googletest
url = https://github.com/google/googletest
[submodule "lib/boost-lexical_cast"]
path = lib/boost-lexical_cast
url = https://github.com/boostorg/lexical_cast
[submodule "lib/boost-concept_check"]
path = lib/boost-concept_check
url = https://github.com/boostorg/concept_check
[submodule "lib/boost-numeric_conversion"]
path = lib/boost-numeric_conversion
url = https://github.com/boostorg/numeric_conversion
[submodule "lib/boost-array"]
path = lib/boost-array
url = https://github.com/boostorg/array
[submodule "lib/boost-container"]
path = lib/boost-container
url = https://github.com/boostorg/container
[submodule "lib/boost-move"]
path = lib/boost-move
url = https://github.com/boostorg/move
[submodule "lib/boost-math"]
path = lib/boost-math
url = https://github.com/boostorg/math
[submodule "lib/linuxdeploy-desktopfile"]
path = lib/linuxdeploy-desktopfile
url = https://github.com/linuxdeploy/linuxdeploy-desktopfile
+8 -1
View File
@@ -55,7 +55,14 @@ matrix:
- 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
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*
install:
- git clone https://github.com/NixOS/patchelf.git -b 0.8
+5
View File
@@ -10,6 +10,11 @@ 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")
if (EXISTS "${PROJECT_SOURCE_DIR}/lib/cpp-subprocess/subprocess.hpp")
else()
message (FATAL_ERROR "Missing submodule(s), please 'git submodule update --init --recursive'...")
endif()
# support for ccache
# call CMake with -DUSE_CCACHE=ON to make use of it
set(USE_CCACHE ON CACHE BOOL "")
+11 -63
View File
@@ -14,58 +14,20 @@ linuxdeploy is designed to be an AppDir maintenance tool. It provides extensive
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
## User guides and examples
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).
Please see the [linuxdeploy user guide](https://docs.appimage.org/packaging-guide/linuxdeploy-user-guide.html) and the [native binaries packaging guide](https://docs.appimage.org/packaging-guide/native-binaries.html) in the [AppImage documentation](https://docs.appimage.org). There's also an [examples section](https://docs.appimage.org/packaging-guide/native-binaries.html#examples).
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:
## Projects using linuxdeploy
```sh
# automake
./configure --prefix=/usr
make install DESTDIR=AppDir
This is an incomplete list of projects using linuxdeploy. You might want to read their build scripts to see how they use linuxdeploy.
# 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 --appdir 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 called an "iterative workflow". In case of errors, you can simply fix them, and re-run linuxdeploy afterwards.
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).
- [Pext](https://github.com/Pext/Pext)
- [AppImageLauncher](https://github.com/TheAssassin/AppImageLauncher)
- [OpenRCT2](https://github.com/OpenRCT2/OpenRCT2)
- [AppImageUpdate](https://github.com/AppImage/AppImageUpdate)
- [appimaged](https://github.com/AppImage/appimaged)
## Plugins
@@ -86,25 +48,11 @@ linuxdeploy currently ships with some plugins. These are likely out of date. In
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>`.
**A list of official and community plugins can be found in the [awesome-linuxdeploy](http://github.com/linuxdeploy/awesome-linuxdeploy) project.**
**Note:** If you want to suggest a plugin for a specific framework, language etc., please feel free to [create a new issue](https://github.com/linuxdeploy/linuxdeploy/issues/new). Current plugin requests can be found [here](https://github.com/linuxdeploy/linuxdeploy/issues?utf8=%E2%9C%93&q=label%3A%22plugin+request%22).
## User guides and examples
Please see the [linuxdeploy user guide](https://docs.appimage.org/packaging-guide/linuxdeploy-user-guide.html) and the [native binaries packaging guide](https://docs.appimage.org/packaging-guide/native-binaries.html) in the [AppImage documentation](https://docs.appimage.org). There's also an [examples section](https://docs.appimage.org/packaging-guide/native-binaries.html#examples).
## Projects using linuxdeploy
This is an incomplete list of projects using linuxdeploy. You might want to read their build scripts to see how they use linuxdeploy.
- [Pext](https://github.com/Pext/Pext)
- [AppImageLauncher](https://github.com/TheAssassin/AppImageLauncher)
- [OpenRCT2](https://github.com/OpenRCT2/OpenRCT2)
- [AppImageUpdate](https://github.com/AppImage/AppImageUpdate)
- [appimaged](https://github.com/AppImage/appimaged)
## Troubleshooting
> I bundled additional resources, but when I try to run them, either the system binary is called or the file is not found.
+12 -3
View File
@@ -218,8 +218,11 @@ function(SETUP_TARGET_FOR_COVERAGE_GCOVR_XML)
endforeach()
add_custom_target(${Coverage_NAME}
# Clean old coverage data
COMMAND find ${PROJECT_BINARY_DIR} -type f -iname '*.gcno' -delete
# Run tests
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
COMMAND ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
# Running gcovr
COMMAND ${GCOVR_PATH} --xml
@@ -272,8 +275,11 @@ function(SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML)
endforeach()
add_custom_target(${Coverage_NAME}
# Clean old coverage data
COMMAND find ${PROJECT_BINARY_DIR} -type f -iname '*.gcno' -delete
# Run tests
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
COMMAND ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
# Create folder
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${Coverage_NAME}
@@ -329,8 +335,11 @@ function(SETUP_TARGET_FOR_COVERAGE_GCOVR_TEXT)
endforeach()
add_custom_target(${Coverage_NAME}
# Clean old coverage data
COMMAND find ${PROJECT_BINARY_DIR} -type f -iname '*.gcno' -delete
# Run tests
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
COMMAND ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
# Create folder
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${Coverage_NAME}
+10 -5
View File
@@ -1,11 +1,12 @@
// system includes
#include <memory>
#include <string>
// library includes
#include <boost/filesystem.hpp>
// local includes
#include "linuxdeploy/core/desktopfile/desktopfile.h"
#include "linuxdeploy/desktopfile/desktopfile.h"
#pragma once
@@ -19,7 +20,7 @@ namespace linuxdeploy {
private:
// private data class pattern
class PrivateData;
PrivateData* d;
std::shared_ptr<PrivateData> d;
public:
// default constructor
@@ -27,7 +28,11 @@ namespace linuxdeploy {
// the directory will be created if it doesn't exist
explicit AppDir(const boost::filesystem::path& path);
~AppDir();
// we don't want any copy/move(-assignment) behavior, therefore we delete those operators/constructors
AppDir(const AppDir&) = delete;
AppDir(AppDir&&) = delete;
void operator=(const AppDir&) = delete;
void operator=(AppDir&&) = delete;
// alternative constructor
// shortcut for using a normal string instead of a path
@@ -59,7 +64,7 @@ namespace linuxdeploy {
bool deployIcon(const boost::filesystem::path& path);
// deploy arbitrary file
void deployFile(const boost::filesystem::path& from, const boost::filesystem::path& to);
boost::filesystem::path deployFile(const boost::filesystem::path& from, const boost::filesystem::path& to);
// create an <AppDir> relative symlink to <target> at <symlink>.
bool createRelativeSymlink(const boost::filesystem::path& target, const boost::filesystem::path& symlink);
@@ -96,7 +101,7 @@ namespace linuxdeploy {
bool deployDependenciesForExistingFiles();
// disable deployment of copyright files for this instance
bool setDisableCopyrightFilesDeployment(bool disable);
void setDisableCopyrightFilesDeployment(bool disable);
};
}
}
@@ -1,132 +0,0 @@
// system includes
#include <unordered_map>
// library includes
#include <boost/filesystem.hpp>
// local includes
#include "desktopfileentry.h"
#pragma once
namespace linuxdeploy {
namespace core {
namespace desktopfile {
/*
* Parse and read desktop files.
*/
class DesktopFile {
public:
// describes a single section
typedef std::unordered_map<std::string, DesktopFileEntry> section_t;
// describes all sections in the desktop file
typedef std::unordered_map<std::string, section_t> sections_t;
private:
// private data class pattern
class PrivateData;
std::shared_ptr<PrivateData> d;
public:
// default constructor
DesktopFile();
// construct from existing desktop file
// if the file exists, it will be read using DesktopFileReader
// if reading fails, exceptions will be thrown (see DesktopFileReader for more information)
explicit DesktopFile(const boost::filesystem::path& path);
// construct by reading an existing stream
// file must exist, otherwise std::runtime_error is thrown
explicit DesktopFile(std::istream& is);
// copy constructor
DesktopFile(const DesktopFile& other);
// copy assignment constructor
DesktopFile& operator=(const DesktopFile& other);
// move assignment operator
DesktopFile& operator=(DesktopFile&& other) noexcept;
// equality operator
bool operator==(const DesktopFile& other);
// inequality operator
bool operator!=(const DesktopFile& other);
public:
// returns true if a file has been loaded, false otherwise
bool isEmpty() const;
// read desktop file
// sets path associated with this file
// throws exceptions in case of issues, see DesktopFileReader for more information
void read(const boost::filesystem::path& path);
// read desktop file from existing stream
// throws exceptions in case of issues, see DesktopFileReader for more information
void read(std::istream& is);
// get path associated with this file
boost::filesystem::path path() const;
// sets the path associated with this desktop file
// used to e.g., save the desktop file
void setPath(const boost::filesystem::path& path);
// clear contents of desktop file
void clear();
// save desktop file
bool save() const;
// save desktop file to path
// does not change path associated with desktop file
// throws exceptions in case of errors, see DesktopFileWriter::save(...) for more information
bool save(const boost::filesystem::path& path) const;
// save desktop file to ostream
// does not change path associated with desktop file
// throws exceptions in case of errors, see DesktopFileWriter::save(...) for more information
bool save(std::ostream& os) const;
// check if entry exists in given section and key
bool entryExists(const std::string& section, const std::string& key) const;
// get key from desktop file
// an std::string passed as value parameter will be populated with the contents
// returns true (and populates value) if the key exists, false otherwise
bool getEntry(const std::string& section, const std::string& key, std::string& value) const;
// get key from desktop file
// an std::string passed as value parameter will be populated with the contents
// returns true (and populates value) if the key exists, false otherwise
bool getEntry(const std::string& section, const std::string& key, DesktopFileEntry& value) const;
// add key to section in desktop file
// the section will be created if it doesn't exist already
// returns true if an existing key was overwritten, false otherwise
bool setEntry(const std::string& section, const std::string& key, const std::string& value);
// add key to section in desktop file
// the section will be created if it doesn't exist already
// returns true if an existing key was overwritten, false otherwise
bool setEntry(const std::string& section, const DesktopFileEntry& entry);
// add key to section in desktop file
// the section will be created if it doesn't exist already
// returns true if an existing key was overwritten, false otherwise
bool setEntry(const std::string& section, const DesktopFileEntry&& entry);
// create common application entries in desktop file
// returns false if one of the keys exists and was left unmodified
bool addDefaultKeys(const std::string& executableFileName);
// validate desktop file
bool validate() const;
};
}
}
}
@@ -1,75 +0,0 @@
#pragma once
// system headers
#include <memory>
#include <string>
// library headers
#include <boost/lexical_cast.hpp>
namespace linuxdeploy {
namespace core {
namespace desktopfile {
class DesktopFileEntry {
private:
// opaque data class pattern
class PrivateData;
std::shared_ptr<PrivateData> d;
public:
// default constructor
DesktopFileEntry();
// construct from key and value
explicit DesktopFileEntry(std::string key, std::string value);
// copy constructor
DesktopFileEntry(const DesktopFileEntry& other);
// copy assignment constructor
DesktopFileEntry& operator=(const DesktopFileEntry& other);
// move assignment operator
DesktopFileEntry& operator=(DesktopFileEntry&& other) noexcept;
// equality operator
bool operator==(const DesktopFileEntry& other) const;
// inequality operator
bool operator!=(const DesktopFileEntry& other) const;
public:
// checks whether a key and value have been set
bool isEmpty() const;
// return entry's key
const std::string& key() const;
// return entry's value
const std::string& value() const;
public:
// allow conversion of entry to string
// returns value
explicit operator std::string() const;
// convert value to integer
// throws boost::bad_lexical_cast in case of type errors
int asInt() const;
// convert value to long
// throws boost::bad_lexical_cast in case of type errors
long asLong() const;
// convert value to double
// throws boost::bad_lexical_cast in case of type errors
double asDouble() const;
// split CSV list value into vector
// the separator used to split the string is a semicolon as per desktop file spec
std::vector<std::string> parseStringList() const;
};
}
}
}
+15 -3
View File
@@ -11,6 +11,7 @@
// local headers
#include "linuxdeploy/core/log.h"
#include "linuxdeploy/util/util.h"
#pragma once
@@ -48,10 +49,16 @@ namespace linuxdeploy {
auto output = subprocess::check_output({pluginPath.c_str(), "--plugin-api-version"});
std::string stdoutOutput = output.buf.data();
// only interpret last line (fixes issues with --appimage-extract-and-run, where the runtime
// prints all the paths it extracts out to stdout)
const auto& lines = util::splitLines(stdoutOutput);
const auto& lastLine = lines.back();
try {
auto apiLevel = std::stoi(stdoutOutput);
return apiLevel;
const auto pluginApiLevel = std::stoi(lastLine);
return pluginApiLevel;
} catch (const std::invalid_argument&) {
ldLog() << LD_DEBUG << "Failed to understand plugin response:" << lastLine << std::endl;
return -1;
}
}
@@ -87,7 +94,12 @@ namespace linuxdeploy {
if (d->apiLevel != API_LEVEL) {
std::stringstream msg;
msg << "This class only supports API level " << API_LEVEL << ", not " << d->apiLevel;
if (d->apiLevel < 0) {
msg << "Could not read plugin API level";
} else {
msg << "This class only supports API level " << API_LEVEL << ", not " << d->apiLevel;
}
throw WrongApiLevelError(msg.str());
}
}
+23 -99
View File
@@ -9,77 +9,31 @@ add_library(args INTERFACE)
target_sources(args INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/args/args.hxx)
target_include_directories(args INTERFACE args)
add_subdirectory(linuxdeploy-desktopfile)
function(ld_add_boost_headeronly_lib)
set(options "")
set(oneValueArgs TARGET_NAME ROOT_DIR)
set(multiValueArgs LINK_LIBRARIES)
cmake_parse_arguments(A "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
# message(STATUS "Adding boost header-only library ${A_TARGET_NAME} in directory ${A_ROOT_DIR} with dependencies to ${A_LINK_LIBRARIES}")
add_library(${A_TARGET_NAME} INTERFACE)
set_property(TARGET ${A_TARGET_NAME} PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${A_ROOT_DIR}/include>")
set_property(TARGET ${A_TARGET_NAME} PROPERTY INTERFACE_LINK_LIBRARIES ${A_LINK_LIBRARIES})
endfunction()
if(NOT USE_SYSTEM_BOOST)
add_library(boost_config INTERFACE)
set_property(TARGET boost_config PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-config/include>")
ld_add_boost_headeronly_lib(TARGET_NAME boost_config ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/boost-config)
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")
ld_add_boost_headeronly_lib(TARGET_NAME boost_throw_exception ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/boost-throw_exception LINK_LIBRARIES boost_throw_exception)
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")
foreach(boost_lib_name utility predef assert core type_traits iterator mpl preprocessor static_assert detail smart_ptr exception io container_hash range integer)
ld_add_boost_headeronly_lib(TARGET_NAME boost_${boost_lib_name} ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/boost-${boost_lib_name} LINK_LIBRARIES boost_config;boost_throw_exception)
endforeach()
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 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 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 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 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 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 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 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 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 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 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 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 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 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 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")
ld_add_boost_headeronly_lib(TARGET_NAME boost_functional ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/boost-utility LINK_LIBRARIES boost_config;boost_container_hash)
file(GLOB boost_system_srcs ${CMAKE_CURRENT_SOURCE_DIR}/boost-system/src/*.cpp)
add_library(boost_system STATIC ${boost_system_srcs})
@@ -92,7 +46,7 @@ if(NOT USE_SYSTEM_BOOST)
file(GLOB boost_filesystem_srcs ${CMAKE_CURRENT_SOURCE_DIR}/boost-filesystem/src/*.cpp)
add_library(boost_filesystem STATIC ${boost_filesystem_srcs})
target_include_directories(boost_filesystem PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/boost-filesystem/include)
target_link_libraries(boost_filesystem PUBLIC boost_config boost_utility boost_system)
target_link_libraries(boost_filesystem PUBLIC boost_config boost_utility boost_system boost_throw_exception)
file(GLOB boost_regex_srcs ${CMAKE_CURRENT_SOURCE_DIR}/boost-regex/src/*.cpp)
add_library(boost_regex STATIC ${boost_regex_srcs})
@@ -101,38 +55,8 @@ if(NOT USE_SYSTEM_BOOST)
boost_config boost_predef boost_assert boost_throw_exception boost_smart_ptr boost_core boost_mpl
boost_type_traits boost_static_assert boost_integer boost_preprocessor boost_functional boost_detail
)
add_library(boost_numeric_conversion INTERFACE)
set_property(TARGET boost_numeric_conversion PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-numeric_conversion/include>")
set_property(TARGET boost_numeric_conversion PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
add_library(boost_concept_check INTERFACE)
set_property(TARGET boost_concept_check PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-concept_check/include>")
set_property(TARGET boost_concept_check PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
target_link_libraries(boost_concept_check INTERFACE boost_numeric_conversion)
add_library(boost_array INTERFACE)
set_property(TARGET boost_array PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-array/include>")
set_property(TARGET boost_array PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
add_library(boost_move INTERFACE)
set_property(TARGET boost_move PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-move/include>")
set_property(TARGET boost_move PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
add_library(boost_container INTERFACE)
set_property(TARGET boost_container PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-container/include>")
set_property(TARGET boost_container PROPERTY INTERFACE_LINK_LIBRARIES boost_config boost_move)
add_library(boost_math INTERFACE)
set_property(TARGET boost_math PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-math/include>")
set_property(TARGET boost_math PROPERTY INTERFACE_LINK_LIBRARIES boost_config boost_move)
add_library(boost_lexical_cast INTERFACE)
set_property(TARGET boost_lexical_cast PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-lexical_cast/include>")
set_property(TARGET boost_lexical_cast PROPERTY INTERFACE_LINK_LIBRARIES "boost_config")
target_link_libraries(boost_lexical_cast INTERFACE boost_concept_check boost_numeric_conversion boost_array boost_container boost_math)
endif()
if(BUILD_TESTING)
if(BUILD_TESTING AND NOT TARGET gtest)
add_subdirectory(googletest)
endif()
Submodule lib/boost-array deleted from cef221d8b4
Submodule lib/boost-math deleted from 6bbba17f9e
Submodule lib/boost-move deleted from 3ce9452f93
+8
View File
@@ -0,0 +1,8 @@
[Desktop Entry]
Name=linuxdeploy
Type=Application
Terminal=true
NoDisplay=true
Exec=linuxdeploy
Icon=linuxdeploy
Categories=Development;
+1 -1
View File
@@ -10,7 +10,7 @@ if(USE_SYSTEM_BOOST)
set(BOOST_LIBS Boost::filesystem Boost::regex)
else()
# use custom built libs
set(BOOST_LIBS boost_system boost_filesystem boost_regex boost_lexical_cast)
set(BOOST_LIBS boost_system boost_filesystem boost_regex)
endif()
+33 -3
View File
@@ -8,6 +8,7 @@
using namespace linuxdeploy::core;
using namespace linuxdeploy::core::log;
using namespace linuxdeploy::desktopfile;
namespace bf = boost::filesystem;
namespace linuxdeploy {
@@ -32,14 +33,13 @@ namespace linuxdeploy {
return deployedDesktopFiles[0];
}
auto firstDeployedDesktopFileName = boost::filesystem::path(
desktopFilePaths.front()).filename().string();
auto firstDeployedDesktopFileName = boost::filesystem::path(desktopFilePaths.front()).filename().string();
auto desktopFileMatchingName = find_if(
deployedDesktopFiles.begin(),
deployedDesktopFiles.end(),
[&firstDeployedDesktopFileName](const desktopfile::DesktopFile& desktopFile) {
auto fileName = desktopFile.path().filename().string();
auto fileName = bf::path(desktopFile.path()).filename().string();
return fileName == firstDeployedDesktopFileName;
}
);
@@ -85,4 +85,34 @@ namespace linuxdeploy {
return false;
}
}
bool addDefaultKeys(DesktopFile& desktopFile, const std::string& executableFileName) {
ldLog() << "Adding default values to desktop file:" << desktopFile.path() << std::endl;
auto rv = true;
auto setDefault = [&rv, &desktopFile](const std::string& section, const std::string& key, const std::string& value) {
if (desktopFile.entryExists(section, key)) {
DesktopFileEntry entry;
// this should never return false
auto entryExists = desktopFile.getEntry(section, key, entry);
assert(entryExists);
ldLog() << LD_WARNING << "Key exists, not modified:" << key << "(current value:" << entry.value() << LD_NO_SPACE << ")" << std::endl;
rv = false;
} else {
auto entryOverwritten = desktopFile.setEntry(section, DesktopFileEntry(key, value));
assert(!entryOverwritten);
}
};
setDefault("Desktop Entry", "Name", executableFileName);
setDefault("Desktop Entry", "Exec", executableFileName);
setDefault("Desktop Entry", "Icon", executableFileName);
setDefault("Desktop Entry", "Type", "Application");
setDefault("Desktop Entry", "Categories", "Utility;");
return rv;
}
}

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