158 Commits

Author SHA1 Message Date
TheAssassin ee0acdb6f1 Patchelf is indeed also needed by the integration tests 2018-11-10 14:18:11 +01:00
TheAssassin e069f6cd22 Fix typos 2018-11-10 14:03:23 +01:00
TheAssassin 74d482612a Add support for ccache 2018-11-10 14:03:11 +01:00
TheAssassin 8f2a49daf0 Fix build command syntax 2018-11-10 14:02:53 +01:00
TheAssassin 4a9e0583d0 Build in parallel before running coverage tools
Also, don't run tests parallelized any more, because the output is
unreadable.
2018-11-10 13:24:01 +01:00
TheAssassin d83ca617e6 Fix release build check 2018-11-10 13:10:47 +01:00
TheAssassin 16483c38e4 Build binaries before running tests when calculating coverage 2018-11-10 13:04:21 +01:00
TheAssassin 65ef0bd7ed Travis accepts but doesn't like multi-value env 2018-11-10 13:00:51 +01:00
TheAssassin 60f2cb78cd Generate textual coverage reports, mk. 4
Fix Travis config syntax
2018-11-10 12:57:29 +01:00
TheAssassin 9b8d7698f4 Remove dependency on lcov
We don't use it anyway, but use the more modern and flexible gcovr.
2018-11-10 03:43:51 +01:00
TheAssassin 5b1b91da5f Generate textual coverage reports, mk. 3 2018-11-10 03:39:34 +01:00
TheAssassin 44571a4c6b Remove obviously broken release build check 2018-11-10 03:38:56 +01:00
TheAssassin 744368868b Generate textual coverage reports, mk. 2 2018-11-10 03:36:33 +01:00
TheAssassin d476f308f8 Generate textual coverage reports, mk. 1 2018-11-10 03:32:50 +01:00
TheAssassin 232a76d1ba Merge pull request #49 from linuxdeploy/restructure-libraries
Restructure libraries
2018-11-10 03:08:35 +01:00
TheAssassin b97c8b45f5 Fix linking issue 2018-11-10 02:59:31 +01:00
TheAssassin d6e6cac6e0 Move libraries into directories following package path 2018-11-10 01:43:36 +01:00
TheAssassin 830dc50136 Avoid recompiling code if excludelist hasn't changed 2018-11-10 01:39:55 +01:00
TheAssassin 16ed8bfa6a Merge pull request #44 from linuxdeploy/issue-39
Implement own desktop file parser
2018-11-09 23:06:59 +01:00
TheAssassin dbfdc6ebe6 Merge branch 'master' into issue-39 2018-11-09 22:19:59 +01:00
TheAssassin a6b09ee30c Revert "Create coverage report during build"
We cannot test for coverage in a release build, but we don't want to
build in debug mode for released binaries.

We might consider creating a separate coverage target for testing code
coverage.

This reverts commit aaaca8b321.
2018-11-09 22:17:49 +01:00
TheAssassin 8b8255b158 Clean up redundant includes 2018-11-09 22:04:59 +01:00
TheAssassin a87fd648e0 Add dedicated test for values with spaces
CC @azubieta
2018-11-09 21:28:40 +01:00
TheAssassin 574a883733 Don't require desktop file's path to exist 2018-11-09 21:28:40 +01:00
TheAssassin aaaca8b321 Create coverage report during build 2018-11-09 21:28:40 +01:00
TheAssassin 22bbd04304 Properly calculate processor count for coverage testing 2018-11-09 21:28:40 +01:00
TheAssassin 96b5c3c479 Generate text report for coverage 2018-11-09 21:28:40 +01:00
TheAssassin 35e67a26bb Add missing dependencies for boost::lexical_cast 2018-11-09 20:08:11 +01:00
TheAssassin 74fb390e2f Make sure to include boost::lexical_cast 2018-11-09 18:53:35 +01:00
TheAssassin 3b3f86f9a2 Revert "Remove unused submodule, mk. 2"
Was working on the wrong branch.

This reverts commit b1838315d9.
2018-11-09 18:52:18 +01:00
TheAssassin e6341435bd Revert "Make sure to include boost::lexical_cast"
Was working on the wrong branch.

This reverts commit e388ad9eb6.
2018-11-09 18:52:10 +01:00
TheAssassin e388ad9eb6 Make sure to include boost::lexical_cast 2018-11-09 18:50:44 +01:00
TheAssassin b1838315d9 Remove unused submodule, mk. 2 2018-11-09 18:50:23 +01:00
TheAssassin 6e525e0a65 Add missing newline 2018-11-09 18:31:27 +01:00
TheAssassin b540240ba5 Improve efficiency 2018-11-09 18:31:19 +01:00
TheAssassin 5d219c99b7 Remove unnecessary dependency from target 2018-11-09 18:30:47 +01:00
TheAssassin 459c5aad9a Fix use of DesktopFile class 2018-11-09 18:24:16 +01:00
TheAssassin c6a517c1f5 Remove unused submodule 2018-11-09 16:07:47 +01:00
TheAssassin 11bbe4d219 Rewrite DesktopFile using own parser 2018-11-09 16:04:40 +01:00
TheAssassin 0d59a27905 Improve test workflow
Use ASSERT first to make sure teh function that performs the work has
run as intended, then use EXPECT to make sure all checks are run.
2018-11-09 13:41:32 +01:00
TheAssassin a4e48db545 Fix include paths 2018-11-09 13:15:03 +01:00
TheAssassin b56e202c40 Add targets for remaining coverage report types 2018-11-09 03:24:03 +01:00
TheAssassin 8b4feb5fd5 Add data getter 2018-11-09 03:16:14 +01:00
TheAssassin 156b45f819 Mark query function as const 2018-11-09 03:10:36 +01:00
TheAssassin 3e1d340612 Add DesktopFileWriter 2018-11-09 03:05:20 +01:00
TheAssassin 8a2d57e8d5 Move definition of types into DesktopFile
Types will be shared with future DesktopFileWriter class.
2018-11-09 02:26:09 +01:00
TheAssassin be1b2c95d4 Move type definitions into class 2018-11-09 02:14:48 +01:00
TheAssassin 4bb1ef124b Move into proper namespace 2018-11-09 01:56:05 +01:00
TheAssassin 93c947b56a Check whether keys and values with spaces are parsed properly 2018-11-09 01:48:44 +01:00
TheAssassin 4bf295d4d6 Validate all values in desktop file 2018-11-09 01:45:36 +01:00
TheAssassin 2c40482bc0 Implement subscript operator returning sections 2018-11-09 01:44:02 +01:00
TheAssassin a647205226 Implement conversion to double 2018-11-09 01:32:18 +01:00
TheAssassin 73832323c8 Implement actual parsing 2018-11-09 01:12:48 +01:00
TheAssassin 169275e023 Fix semantics of isEmpty() 2018-11-09 00:58:09 +01:00
TheAssassin 78e5d0858e Add actual data structures 2018-11-09 00:57:06 +01:00
TheAssassin b4efb2bc56 Increase test coverage 2018-11-09 00:54:32 +01:00
TheAssassin aa2e8b9105 Allow construction from istream 2018-11-09 00:43:02 +01:00
TheAssassin 793b35dc61 Parse file in constructor 2018-11-09 00:37:58 +01:00
TheAssassin 5ba8b613d6 Fix includes 2018-11-09 00:36:55 +01:00
TheAssassin 75f2511437 Add some convenience function to convert/parse value 2018-11-09 00:08:40 +01:00
TheAssassin 9a4916fe84 Desktop file entry initial commit 2018-11-08 23:08:32 +01:00
TheAssassin e584088656 Use already existing function to copy data 2018-11-08 22:45:50 +01:00
TheAssassin 8a79cfbe1d Mark query functions as const 2018-11-08 22:38:29 +01:00
TheAssassin 22ecabc51b Desktop file parser initial commit 2018-11-08 22:18:23 +01:00
TheAssassin 81dfae892c Add support for code coverage measurements 2018-11-08 22:17:21 +01:00
TheAssassin bedd66d161 INI parser now contains a CMake script 2018-11-07 23:20:29 +01:00
TheAssassin 62f04213ce Use fixed fork of INI parser 2018-11-07 23:20:26 +01:00
TheAssassin 4790fabc44 Revert "Temporary workaround for #39"
Fixed the issue properly in the dependency, therefore the workaround is
no longer needed.

This reverts commit 6112a6353e.
2018-11-07 22:21:52 +01:00
TheAssassin 6112a6353e Temporary workaround for #39 2018-11-07 20:09:24 +01:00
TheAssassin 82b7ccd76a Merge pull request #41 from linuxdeploy/integration_test
Improve AppDir root files deployment
2018-11-06 15:48:05 +01:00
TheAssassin 4e33e395de Show warning if existing AppRun is overwritten 2018-11-06 15:39:35 +01:00
Alexis Lopez Zubieta 9d25fee1dc Make "Deploying custom AppRun" a regular message 2018-11-06 08:26:15 -06:00
Alexis Lopez Zubieta 9d78e0786b Ensure that custom AppRun are deployed even if no desktop files are found 2018-11-06 07:48:12 -06:00
Alexis Lopez Zubieta 9f20e5829d Restructure the code in order to make it more clear 2018-11-05 21:26:48 -06:00
Alexis Lopez Zubieta 5055efdc05 Rename linuxdeploy.cpp and linuxdeploy.h to core.cpp and core.h 2018-11-05 18:33:14 -06:00
Alexis Lopez Zubieta 19ecbb2d70 remove empty line 2018-11-05 16:24:09 -06:00
Alexis Lopez Zubieta 0e92331a12 Document linuxdeploy::deployAppDirRootFiles 2018-11-05 16:23:04 -06:00
Alexis Lopez Zubieta 4bf1948774 Document linuxdeploy::getMainDesktopFile 2018-11-05 16:07:01 -06:00
Alexis Lopez Zubieta f201c57177 Optimize imports 2018-11-05 15:57:37 -06:00
Alexis Lopez Zubieta d7c0e94f11 Reformat 2018-11-05 15:55:13 -06:00
Alexis Lopez Zubieta 700f6fe15f Remove declaration of getMainDesktopFile 2018-11-05 15:54:59 -06:00
Alexis Lopez Zubieta 012e621ec5 Throw an exception when no deskotp files are found 2018-11-05 15:47:11 -06:00
Alexis Lopez Zubieta 6c674aa184 Making getMainDesktopFile parameters constant references 2018-11-05 15:43:35 -06:00
Alexis Lopez Zubieta 553bb9fcb0 No need to override constructor 2018-11-05 15:41:06 -06:00
Alexis Lopez Zubieta 906dcab283 Fix code style 2018-11-05 15:40:15 -06:00
Alexis Lopez Zubieta fc3d80c281 remove duplicated 'public' 2018-11-05 15:39:47 -06:00
Alexis Lopez Zubieta f0bb1fb472 bring empty line back 2018-11-05 15:39:00 -06:00
Alexis Lopez Zubieta f3f30166f2 Importing boost::filesystem as bf to keep consistency its usage across the project 2018-11-05 15:38:12 -06:00
Alexis Lopez Zubieta 2210b7e65d Remove integration test 'build_minimal_appimage_with_custom_apprun' 2018-11-05 15:33:15 -06:00
Alexis Lopez Zubieta cc800588d2 Optimize imports 2018-11-05 15:28:11 -06:00
Alexis Lopez Zubieta 29cda3b1ac Change return type to bool 2018-11-05 15:27:58 -06:00
Alexis Lopez Zubieta 16b0a5948a createLinksInAppDirRoot is capable of dealing with an empty customAppRunPath so there is no need to check it 2018-11-05 15:27:58 -06:00
Alexis Lopez Zubieta 41569a4f53 The ".DirIcon" creation seems not to be responsibility of deployAppDirRootFiles 2018-11-05 15:27:58 -06:00
Alexis Lopez Zubieta 7ff05ca98e Removing AppRun file existence check as createLinksInAppDirRoot also perform this check 2018-11-05 15:27:58 -06:00
Alexis Lopez Zubieta cab57f86d6 Put main desktop file lookup into a separated function 2018-11-05 15:27:58 -06:00
Alexis Lopez Zubieta 93fea697e5 Move desktop file deployment away from desktop file lookup 2018-11-05 15:27:58 -06:00
Alexis Lopez Zubieta bd12fefc35 Complete deployAppDirRootFilesWithExistentAppRun definition 2018-11-05 15:12:27 -06:00
Alexis Lopez Zubieta 2cdedc252c Replace args::ValueFlagList by vector<string> in deployAppDirRootFiles function signature 2018-11-05 15:12:27 -06:00
Alexis Lopez Zubieta 1fa90fbd5c Add namespace and prepare unittest 2018-11-05 15:12:27 -06:00
Alexis Lopez Zubieta 7318d68c96 Move deployAppDirRootFiles function into a separated file to allow unit testing 2018-11-05 15:12:27 -06:00
Alexis Lopez Zubieta e5f4755da7 Move deploy AppDir root files into a separated function 2018-11-05 15:12:27 -06:00
Alexis Lopez Zubieta 31f20a398f Add integration test to build a minimal appimage with custom AppRun 2018-11-05 15:12:27 -06:00
Alexis LĂłpez Zubieta d9ca907da8 Add symlinkFile to the public AppDir interface (#42)
* Add symlinkFile to the public AppDir interface

* Rename AppDir::symlinkFile to AppDir::createSymlink

* change return value to bool

* Remove duplicated header

* Remove blank lines

* Add comment

* Fix test name

* Change createSymlink signature. Name changed to createRelativeSymlink and remove the useRelativePath argument

* Remove commented tests.
2018-11-05 22:10:18 +01:00
TheAssassin 542edaf410 Allow disabling copyright files deployment for debugging 2018-11-04 17:21:36 +01:00
TheAssassin e683561430 Merge pull request #38 from linuxdeploy/refactor-subprocessing
Refactor subprocessing
2018-10-25 15:36:57 +02:00
TheAssassin 0de7caa8ee Document complex if query
[ci skip]
2018-10-25 15:33:22 +02:00
TheAssassin f1690cc2a3 Use new subprocessing function to create symlinks 2018-10-25 15:18:55 +02:00
TheAssassin 53e0850a2b Use new subprocessing function to handle calls to strip 2018-10-25 15:17:43 +02:00
TheAssassin 3949a5fc57 Use new subprocessing function to set rpath in ELF files 2018-10-25 15:12:27 +02:00
TheAssassin 001b8f974c Use new subprocessing function to read rpath in ELF files 2018-10-25 14:58:47 +02:00
TheAssassin 2f5e04ec24 Increase stream buffer size again 2018-10-25 14:38:03 +02:00
TheAssassin 8d01c448d3 Increase subprocess stream reading reliability 2018-10-25 14:37:17 +02:00
TheAssassin 10df75f877 Extract subprocessing into separate library 2018-10-25 14:34:54 +02:00
TheAssassin 0c5b198e2f Merge pull request #33 from linuxdeploy/tests
Add Unit Tests
2018-10-25 01:26:46 +02:00
TheAssassin 5d2984ae02 Merge branch 'master' into tests 2018-10-25 01:21:46 +02:00
TheAssassin 33829c07d0 Remove redundant variables and fix paths 2018-10-25 01:16:05 +02:00
TheAssassin 90f8ed26b8 Fix path in unit test 2018-10-25 01:12:47 +02:00
TheAssassin cbaa343a82 Add missing trailing newline character
[ci skip]
2018-10-25 01:08:52 +02:00
TheAssassin 9cf0663baa Hardcode all paths to recognize sudden changes of destination paths 2018-10-25 01:06:12 +02:00
TheAssassin e94494ea31 Move declaration of variables to top 2018-10-25 00:48:13 +02:00
TheAssassin 2dce34daf9 Use ASSERT_* instead of if()s and FAIL() 2018-10-25 00:46:46 +02:00
TheAssassin 7260078b6c Move test into subdirectory named like internal library 2018-10-25 00:39:45 +02:00
TheAssassin 4bdceec7d8 Use standard lower-case file extension 2018-10-25 00:30:41 +02:00
TheAssassin ca6c710c38 Remove deprecated code 2018-10-25 00:27:32 +02:00
TheAssassin 8a31d3d677 Fix cross-compiling toolchain 2018-10-25 00:27:32 +02:00
TheAssassin 5e94977f78 Fix cpp-feather-ini-parser test execution 2018-10-25 00:27:32 +02:00
TheAssassin 2f96dec588 Fix tests' structure, code style and use of GTest 2018-10-25 00:27:32 +02:00
TheAssassin a1308955e7 Use CMake's BUILD_TESTING instead of proprietary custom variable 2018-10-25 00:27:32 +02:00
Alexis Lopez Zubieta 7e4a320f61 Make ctest run un verbose mode. 2018-10-25 00:27:32 +02:00
Alexis Lopez Zubieta 172db51186 Add unit test for AppDir::depoloyLibrary but with an invalid path. 2018-10-25 00:27:32 +02:00
Alexis Lopez Zubieta d09186f69f Run unit tests on the build.sh script 2018-10-25 00:27:32 +02:00
Alexis Lopez Zubieta 376eddb14d Add unit test for AppDir::deployFile 2018-10-25 00:27:32 +02:00
Alexis Lopez Zubieta 47ff6c8e9d Add AppDir::deployIcon test. 2018-10-25 00:27:03 +02:00
TheAssassin 41371c9d90 Improve Travis uploading 2018-10-25 00:20:05 +02:00
Alexis Lopez Zubieta eacc907c85 Add unit test for AppDir::deployDesktopFile 2018-10-24 13:09:59 +02:00
Alexis Lopez Zubieta 4c9943f0d1 Add unit test for AppDir::deployExecutable 2018-10-24 13:09:59 +02:00
Alexis Lopez Zubieta a0503a7102 Add test for AppDir::depoloyLibrary 2018-10-24 13:09:59 +02:00
Alexis Lopez Zubieta f1e752d452 Add unit test for AppDir::createBasicStructure 2018-10-24 13:09:59 +02:00
Alexis Lopez Zubieta 55b6ee19e1 Add tests infrastructure 2018-10-24 13:09:50 +02:00
TheAssassin 4c0d5ea891 Remove erroneous null termination
The std::string is created using char pointer _and_ buffer size, so
null termination wasn't necessary in there (might even be problematic
with other tools which aren't strictly text based).

CC #35.
2018-10-24 12:46:24 +02:00
TheAssassin 83a8f52f98 Replace communicate() to prevent buffer overflow 2018-10-14 17:11:05 +02:00
TheAssassin b1bf306510 Fix compatibility with newer versions of ldd 2018-10-14 17:11:05 +02:00
TheAssassin d2a021d57b Update README.md 2018-10-07 22:17:20 +02:00
TheAssassin 2f7ad201f1 Don't overwrite existing AppRun
... unless custom AppRun was specified
2018-10-07 00:10:57 +02:00
TheAssassin 485507a2d1 Buffer subprocess communication 2018-10-07 00:05:59 +02:00
TheAssassin cdee469e60 Fix uploading of .zsync file 2018-10-05 02:03:38 +02:00
TheAssassin a892d066cc Improve update information 2018-10-04 15:21:38 +02:00
TheAssassin 57175e0c75 Embed update information 2018-10-04 15:16:22 +02:00
TheAssassin 88695de067 Fix desktop file filename handling 2018-09-30 21:20:36 +02:00
TheAssassin 0f19458792 Improve error message 2018-09-30 21:11:05 +02:00
TheAssassin c8d78eb602 Remove --app-name parameter completely
Fixes #19.
2018-09-30 17:12:28 +02:00
TheAssassin 6b8b59ee77 Search for plugins in current working directory 2018-09-29 21:56:58 +02:00
TheAssassin 3674af54b2 Fix syntax 2018-09-26 00:39:21 +02:00
TheAssassin 73ecd9d318 Actually copy files before running plugins
Some plugins like the Qt one expect libraries etc. to be deployed
already, like the plugin spec defines. We should try to adhere to the
spec.
2018-09-26 00:36:57 +02:00
TheAssassin 1ad4e5e6a9 Make sure to run ldd with LC_ALL=C 2018-09-22 23:21:00 +02:00
TheAssassin f3b54236a6 Update build.sh 2018-09-16 04:23:17 +02:00
TheAssassin e885b47208 Merge pull request #30 from asashnov/fix-examples-link
fix examples link (ancor on the target HTML page is lowercased)
2018-09-06 13:08:36 +02:00
Alexander Sashnov 89788f5e26 fix examples link (ancor on the target HTML page is lowercased) 2018-09-06 17:55:24 +07:00
67 changed files with 2964 additions and 366 deletions
-1
View File
@@ -2,5 +2,4 @@ cmake-build-*/
*build*/
.idea/
squashfs-root/
tests/
*.AppImage
+24 -3
View File
@@ -4,9 +4,6 @@
[submodule "lib/args"]
path = lib/args
url = https://github.com/Taywee/args.git
[submodule "lib/cpp-feather-ini-parser"]
path = lib/cpp-feather-ini-parser
url = https://github.com/Turbine1991/cpp-feather-ini-parser.git
[submodule "lib/boost-filesystem"]
path = lib/boost-filesystem
url = https://github.com/boostorg/filesystem.git
@@ -76,3 +73,27 @@
[submodule "lib/CImg"]
path = lib/CImg
url = https://github.com/dtschump/CImg.git
[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
+31 -1
View File
@@ -26,6 +26,36 @@ matrix:
- 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
install:
- git clone https://github.com/NixOS/patchelf.git -b 0.8
@@ -44,7 +74,7 @@ script:
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" != "master" ]; then export TRAVIS_EVENT_TYPE=pull_request; fi
- 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*
+38
View File
@@ -10,6 +10,44 @@ 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")
# support for ccache
# call CMake with -DUSE_CCACHE=ON to make use of it
set(USE_CCACHE ON CACHE BOOL "")
if(USE_CCACHE)
find_program(CCACHE ccache)
if(CCACHE)
message(STATUS "Using ccache")
set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE})
set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE})
else()
message(WARNING "USE_CCACHE set, but could not find ccache")
endif()
endif()
set(ENABLE_COVERAGE OFF CACHE BOOL "Enable coverage measurements")
if(ENABLE_COVERAGE)
include(CodeCoverage)
message(WARNING "Enabling code coverage measurements -> disables optimizations and embeds debug information!")
append_coverage_compiler_flags()
set(COVERAGE_GCOVR_EXCLUDES ${PROJECT_SOURCE_DIR}/lib ${PROJECT_BINARY_DIR})
include(ProcessorCount)
ProcessorCount(processor_count)
set(command cmake --build . --target all -- -j ${processor_count} && ctest -V)
setup_target_for_coverage_gcovr_html(NAME coverage EXECUTABLE "${command}")
setup_target_for_coverage_gcovr_xml(NAME coverage_xml EXECUTABLE "${command}")
setup_target_for_coverage_gcovr_text(NAME coverage_text EXECUTABLE "${command}")
endif()
add_subdirectory(lib)
add_subdirectory(src)
include(CTest)
if(BUILD_TESTING)
add_subdirectory(tests)
endif()
+12 -1
View File
@@ -91,7 +91,18 @@ If you want to use a plugin to bundle additional resources, please add `./linuxd
## 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).
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
+353
View File
@@ -0,0 +1,353 @@
# Copyright (c) 2012 - 2017, Lars Bilke
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without modification,
# are permitted provided that the following conditions are met:
#
# 1. Redistributions of source code must retain the above copyright notice, this
# list of conditions and the following disclaimer.
#
# 2. Redistributions in binary form must reproduce the above copyright notice,
# this list of conditions and the following disclaimer in the documentation
# and/or other materials provided with the distribution.
#
# 3. Neither the name of the copyright holder nor the names of its contributors
# may be used to endorse or promote products derived from this software without
# specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# CHANGES:
#
# 2012-01-31, Lars Bilke
# - Enable Code Coverage
#
# 2013-09-17, Joakim Söderberg
# - Added support for Clang.
# - Some additional usage instructions.
#
# 2016-02-03, Lars Bilke
# - Refactored functions to use named parameters
#
# 2017-06-02, Lars Bilke
# - Merged with modified version from github.com/ufz/ogs
#
#
# USAGE:
#
# 1. Copy this file into your cmake modules path.
#
# 2. Add the following line to your CMakeLists.txt:
# include(CodeCoverage)
#
# 3. Append necessary compiler flags:
# APPEND_COVERAGE_COMPILER_FLAGS()
#
# 4. If you need to exclude additional directories from the report, specify them
# using the COVERAGE_LCOV_EXCLUDES variable before calling SETUP_TARGET_FOR_COVERAGE_LCOV.
# Example:
# set(COVERAGE_LCOV_EXCLUDES 'dir1/*' 'dir2/*')
#
# 5. Use the functions described below to create a custom make target which
# runs your test executable and produces a code coverage report.
#
# 6. Build a Debug build:
# cmake -DCMAKE_BUILD_TYPE=Debug ..
# make
# make my_coverage_target
#
include(CMakeParseArguments)
# Check prereqs
find_program( GCOV_PATH gcov )
find_program( LCOV_PATH NAMES lcov lcov.bat lcov.exe lcov.perl)
find_program( GENHTML_PATH NAMES genhtml genhtml.perl genhtml.bat )
find_program( GCOVR_PATH gcovr PATHS ${CMAKE_SOURCE_DIR}/scripts/test)
find_program( SIMPLE_PYTHON_EXECUTABLE python )
if(NOT GCOV_PATH)
message(FATAL_ERROR "gcov not found! Aborting...")
endif() # NOT GCOV_PATH
if("${CMAKE_CXX_COMPILER_ID}" MATCHES "(Apple)?[Cc]lang")
if("${CMAKE_CXX_COMPILER_VERSION}" VERSION_LESS 3)
message(FATAL_ERROR "Clang version must be 3.0.0 or greater! Aborting...")
endif()
elseif(NOT CMAKE_COMPILER_IS_GNUCXX)
message(FATAL_ERROR "Compiler is not GNU gcc! Aborting...")
endif()
set(COVERAGE_COMPILER_FLAGS "-g -O0 --coverage -fprofile-arcs -ftest-coverage"
CACHE INTERNAL "")
set(CMAKE_CXX_FLAGS_COVERAGE
${COVERAGE_COMPILER_FLAGS}
CACHE STRING "Flags used by the C++ compiler during coverage builds."
FORCE )
set(CMAKE_C_FLAGS_COVERAGE
${COVERAGE_COMPILER_FLAGS}
CACHE STRING "Flags used by the C compiler during coverage builds."
FORCE )
set(CMAKE_EXE_LINKER_FLAGS_COVERAGE
""
CACHE STRING "Flags used for linking binaries during coverage builds."
FORCE )
set(CMAKE_SHARED_LINKER_FLAGS_COVERAGE
""
CACHE STRING "Flags used by the shared libraries linker during coverage builds."
FORCE )
mark_as_advanced(
CMAKE_CXX_FLAGS_COVERAGE
CMAKE_C_FLAGS_COVERAGE
CMAKE_EXE_LINKER_FLAGS_COVERAGE
CMAKE_SHARED_LINKER_FLAGS_COVERAGE )
if(NOT CMAKE_BUILD_TYPE STREQUAL "Debug")
message(WARNING "Code coverage results with an optimised (non-Debug) build may be misleading")
endif() # NOT CMAKE_BUILD_TYPE STREQUAL "Debug"
if(CMAKE_C_COMPILER_ID STREQUAL "GNU")
link_libraries(gcov)
else()
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage")
endif()
# Defines a target for running and collection code coverage information
# Builds dependencies, runs the given executable and outputs reports.
# NOTE! The executable should always have a ZERO as exit code otherwise
# the coverage generation will not complete.
#
# SETUP_TARGET_FOR_COVERAGE_LCOV(
# NAME testrunner_coverage # New target name
# EXECUTABLE testrunner -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
# DEPENDENCIES testrunner # Dependencies to build first
# )
function(SETUP_TARGET_FOR_COVERAGE_LCOV)
set(options NONE)
set(oneValueArgs NAME)
set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES LCOV_ARGS GENHTML_ARGS)
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT LCOV_PATH)
message(FATAL_ERROR "lcov not found! Aborting...")
endif() # NOT LCOV_PATH
if(NOT GENHTML_PATH)
message(FATAL_ERROR "genhtml not found! Aborting...")
endif() # NOT GENHTML_PATH
# Setup target
add_custom_target(${Coverage_NAME}
# Cleanup lcov
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -directory . --zerocounters
# Create baseline to make sure untouched files show up in the report
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -c -i -d . -o ${Coverage_NAME}.base
# Run tests
COMMAND ${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
# Capturing lcov counters and generating report
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --directory . --capture --output-file ${Coverage_NAME}.info
# add baseline counters
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} -a ${Coverage_NAME}.base -a ${Coverage_NAME}.info --output-file ${Coverage_NAME}.total
COMMAND ${LCOV_PATH} ${Coverage_LCOV_ARGS} --gcov-tool ${GCOV_PATH} --remove ${Coverage_NAME}.total ${COVERAGE_LCOV_EXCLUDES} --output-file ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned
COMMAND ${GENHTML_PATH} ${Coverage_GENHTML_ARGS} -o ${Coverage_NAME} ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned
COMMAND ${CMAKE_COMMAND} -E remove ${Coverage_NAME}.base ${Coverage_NAME}.total ${PROJECT_BINARY_DIR}/${Coverage_NAME}.info.cleaned
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
DEPENDS ${Coverage_DEPENDENCIES}
COMMENT "Resetting code coverage counters to zero.\nProcessing code coverage counters and generating report."
)
# Show where to find the lcov info report
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
COMMAND ;
COMMENT "Lcov code coverage info report saved in ${Coverage_NAME}.info."
)
# Show info where to find the report
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
COMMAND ;
COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report."
)
endfunction() # SETUP_TARGET_FOR_COVERAGE_LCOV
# Defines a target for running and collection code coverage information
# Builds dependencies, runs the given executable and outputs reports.
# NOTE! The executable should always have a ZERO as exit code otherwise
# the coverage generation will not complete.
#
# SETUP_TARGET_FOR_COVERAGE_GCOVR_XML(
# NAME ctest_coverage # New target name
# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
# DEPENDENCIES executable_target # Dependencies to build first
# )
function(SETUP_TARGET_FOR_COVERAGE_GCOVR_XML)
set(options NONE)
set(oneValueArgs NAME)
set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT SIMPLE_PYTHON_EXECUTABLE)
message(FATAL_ERROR "python not found! Aborting...")
endif() # NOT SIMPLE_PYTHON_EXECUTABLE
if(NOT GCOVR_PATH)
message(FATAL_ERROR "gcovr not found! Aborting...")
endif() # NOT GCOVR_PATH
# Combine excludes to several -e arguments
set(GCOVR_EXCLUDES "")
foreach(EXCLUDE ${COVERAGE_GCOVR_EXCLUDES})
list(APPEND GCOVR_EXCLUDES "-e")
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
endforeach()
add_custom_target(${Coverage_NAME}
# Run tests
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
# Running gcovr
COMMAND ${GCOVR_PATH} --xml
-r ${PROJECT_SOURCE_DIR} ${GCOVR_EXCLUDES}
--object-directory=${PROJECT_BINARY_DIR}
-o ${Coverage_NAME}.xml
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
DEPENDS ${Coverage_DEPENDENCIES}
COMMENT "Running gcovr to produce Cobertura code coverage report."
)
# Show info where to find the report
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
COMMAND ;
COMMENT "Cobertura code coverage report saved in ${Coverage_NAME}.xml."
)
endfunction() # SETUP_TARGET_FOR_COVERAGE_GCOVR_XML
# Defines a target for running and collection code coverage information
# Builds dependencies, runs the given executable and outputs reports.
# NOTE! The executable should always have a ZERO as exit code otherwise
# the coverage generation will not complete.
#
# SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML(
# NAME ctest_coverage # New target name
# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
# DEPENDENCIES executable_target # Dependencies to build first
# )
function(SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML)
set(options NONE)
set(oneValueArgs NAME)
set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT SIMPLE_PYTHON_EXECUTABLE)
message(FATAL_ERROR "python not found! Aborting...")
endif() # NOT SIMPLE_PYTHON_EXECUTABLE
if(NOT GCOVR_PATH)
message(FATAL_ERROR "gcovr not found! Aborting...")
endif() # NOT GCOVR_PATH
# Combine excludes to several -e arguments
set(GCOVR_EXCLUDES "")
foreach(EXCLUDE ${COVERAGE_GCOVR_EXCLUDES})
list(APPEND GCOVR_EXCLUDES "-e")
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
endforeach()
add_custom_target(${Coverage_NAME}
# Run tests
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
# Create folder
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${Coverage_NAME}
# Running gcovr
COMMAND ${GCOVR_PATH} --html --html-details
-r ${PROJECT_SOURCE_DIR} ${GCOVR_EXCLUDES}
--object-directory=${PROJECT_BINARY_DIR}
-o ${Coverage_NAME}/index.html
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
DEPENDS ${Coverage_DEPENDENCIES}
COMMENT "Running gcovr to produce HTML code coverage report."
)
# Show info where to find the report
add_custom_command(TARGET ${Coverage_NAME} POST_BUILD
COMMAND ;
COMMENT "Open ./${Coverage_NAME}/index.html in your browser to view the coverage report."
)
endfunction() # SETUP_TARGET_FOR_COVERAGE_GCOVR_HTML
# Defines a target for running and collection code coverage information
# Builds dependencies, runs the given executable and outputs reports.
# NOTE! The executable should always have a ZERO as exit code otherwise
# the coverage generation will not complete.
#
# SETUP_TARGET_FOR_COVERAGE_GCOVR_TEXT(
# NAME ctest_coverage # New target name
# EXECUTABLE ctest -j ${PROCESSOR_COUNT} # Executable in PROJECT_BINARY_DIR
# DEPENDENCIES executable_target # Dependencies to build first
# )
function(SETUP_TARGET_FOR_COVERAGE_GCOVR_TEXT)
set(options NONE)
set(oneValueArgs NAME)
set(multiValueArgs EXECUTABLE EXECUTABLE_ARGS DEPENDENCIES)
cmake_parse_arguments(Coverage "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
if(NOT SIMPLE_PYTHON_EXECUTABLE)
message(FATAL_ERROR "python not found! Aborting...")
endif() # NOT SIMPLE_PYTHON_EXECUTABLE
if(NOT GCOVR_PATH)
message(FATAL_ERROR "gcovr not found! Aborting...")
endif() # NOT GCOVR_PATH
# Combine excludes to several -e arguments
set(GCOVR_EXCLUDES "")
foreach(EXCLUDE ${COVERAGE_GCOVR_EXCLUDES})
list(APPEND GCOVR_EXCLUDES "-e")
list(APPEND GCOVR_EXCLUDES "${EXCLUDE}")
endforeach()
add_custom_target(${Coverage_NAME}
# Run tests
${Coverage_EXECUTABLE} ${Coverage_EXECUTABLE_ARGS}
# Create folder
COMMAND ${CMAKE_COMMAND} -E make_directory ${PROJECT_BINARY_DIR}/${Coverage_NAME}
# Running gcovr
COMMAND ${GCOVR_PATH}
-r ${PROJECT_SOURCE_DIR} ${GCOVR_EXCLUDES}
--object-directory=${PROJECT_BINARY_DIR}
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
DEPENDS ${Coverage_DEPENDENCIES}
COMMENT "Running gcovr to produce HTML code coverage report."
)
endfunction() # SETUP_TARGET_FOR_COVERAGE_GCOVR_TEXT
function(APPEND_COVERAGE_COMPILER_FLAGS)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}" PARENT_SCOPE)
message(STATUS "Appending code coverage compiler flags: ${COVERAGE_COMPILER_FLAGS}")
endfunction() # APPEND_COVERAGE_COMPILER_FLAGS
+3
View File
@@ -3,3 +3,6 @@ set(CMAKE_SYSTEM_PROCESSOR i386 CACHE STRING "" FORCE)
set(CMAKE_C_FLAGS "-m32" CACHE STRING "" FORCE)
set(CMAKE_CXX_FLAGS "-m32" CACHE STRING "" FORCE)
# https://gitlab.kitware.com/cmake/cmake/issues/16920#note_299077
set(THREADS_PTHREAD_ARG "2" CACHE STRING "Forcibly set by CMakeLists.txt" FORCE)
+7 -1
View File
@@ -5,7 +5,7 @@
#include <boost/filesystem.hpp>
// local includes
#include "linuxdeploy/core/desktopfile.h"
#include "linuxdeploy/core/desktopfile/desktopfile.h"
#pragma once
@@ -61,6 +61,9 @@ namespace linuxdeploy {
// deploy arbitrary file
void 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);
// execute deferred copy operations
bool executeDeferredOperations();
@@ -91,6 +94,9 @@ namespace linuxdeploy {
// calling this function can turn sure file trees created by make install commands into working
// AppDirs
bool deployDependenciesForExistingFiles();
// disable deployment of copyright files for this instance
bool setDisableCopyrightFilesDeployment(bool disable);
};
}
}
-71
View File
@@ -1,71 +0,0 @@
// system includes
// library includes
#include <boost/filesystem.hpp>
#pragma once
namespace linuxdeploy {
namespace core {
namespace desktopfile {
/*
* Parse and read desktop files.
*/
class DesktopFile {
private:
// private data class pattern
class PrivateData;
PrivateData* d;
public:
// default constructor
DesktopFile();
// construct from existing desktop file
// file must exist
explicit DesktopFile(const boost::filesystem::path& path);
// read desktop file
// sets path associated with this file
bool read(const boost::filesystem::path& path);
// 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
bool save(const boost::filesystem::path& path) 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;
// 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);
// 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;
};
}
}
}
@@ -0,0 +1,132 @@
// 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;
};
}
}
}
@@ -0,0 +1,75 @@
#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;
};
}
}
}
+69 -25
View File
@@ -158,50 +158,94 @@ namespace linuxdeploy {
auto printOutput = [&pfds, opfd, epfd, this, &process]() {
poll(pfds.data(), pfds.size(), -1);
if (opfd->revents & POLLIN) {
std::vector<char> lineBuf(16384);
fgets(lineBuf.data(), static_cast<int>(lineBuf.size()), process.output());
std::stringstream ss;
ss << lineBuf.data();
lineBuf.clear();
std::string currentLine;
auto printUntilLastLine = [this](std::vector<char>& buf, size_t& bufSize, const std::string& streamType) {
std::ostringstream oss;
while (std::getline(ss, currentLine)) {
oss << "[" << d->name << "/stdout] " << currentLine << std::endl;
while (true) {
const auto firstLineFeed = std::find(buf.begin(), buf.end(), '\n');
const auto firstCarriageReturn = std::find(buf.begin(), buf.end(), '\r');
if (firstLineFeed == buf.end() && firstCarriageReturn == buf.end())
break;
const auto endOfLine = std::min(firstLineFeed, firstCarriageReturn);
std::string line(buf.begin(), endOfLine+1);
oss << "[" << d->name << "/" << streamType << "] " << line;
bufSize -= std::distance(buf.begin(), endOfLine+1);
buf.erase(buf.begin(), endOfLine+1);
}
auto messages = oss.str();
if (!messages.empty())
ldLog() << messages;
};
std::vector<char> stdoutBuf(16 * 1024);
std::vector<char> stderrBuf(16 * 1024);
size_t stdoutBufSize = 0;
size_t stderrBufSize = 0;
if (opfd->revents & POLLIN) {
if (stdoutBufSize >= stdoutBuf.size())
throw std::runtime_error("Buffer overflow");
while (true) {
auto bytesRead = fread(
reinterpret_cast<void*>(stdoutBuf.data() + stdoutBufSize),
sizeof(char),
static_cast<size_t>(stdoutBuf.size() - stdoutBufSize),
process.output()
);
if (bytesRead == 0)
break;
stdoutBufSize += bytesRead;
printUntilLastLine(stdoutBuf, stdoutBufSize, "stdout");
}
linuxdeploy::core::log::ldLog() << oss.str();
}
std::this_thread::sleep_for(std::chrono::milliseconds(50));
if (epfd->revents & POLLIN) {
std::vector<char> lineBuf(16384);
fgets(lineBuf.data(), static_cast<int>(lineBuf.size()), process.error());
if (stderrBufSize >= stderrBuf.size())
throw std::runtime_error("Buffer overflow");
std::stringstream ss;
ss << lineBuf.data();
lineBuf.clear();
while (true) {
auto bytesRead = fread(
reinterpret_cast<void*>(stderrBuf.data() + stderrBufSize),
sizeof(char),
static_cast<size_t>(stderrBuf.size() - stderrBufSize),
process.error()
);
std::string currentLine;
if (bytesRead == 0)
break;
std::ostringstream oss;
while (std::getline(ss, currentLine)) {
oss << "[" << d->name << "/stderr] " << currentLine << std::endl;
stderrBufSize += bytesRead;
printUntilLastLine(stderrBuf, stderrBufSize, "stderr");
}
linuxdeploy::core::log::ldLog() << oss.str();
}
std::this_thread::sleep_for(std::chrono::milliseconds(50));
return true;
};
int retcode;
do {
if (!printOutput()) {
ldLog() << LD_ERROR << "Failed to communicate with process" << std::endl;
process.kill();
return -1;
}
} while (process.poll() < 0);
} while ((retcode = process.poll()) < 0);
if (!printOutput()) {
ldLog() << LD_ERROR << "Failed to communicate with process" << std::endl;
@@ -209,7 +253,7 @@ namespace linuxdeploy {
return -1;
}
return process.retcode();
return retcode;
}
}
}
+1
View File
@@ -5,6 +5,7 @@
#include <cstring>
#include <sstream>
#include <string>
#include <unistd.h>
#include <vector>
namespace linuxdeploy {
+19
View File
@@ -0,0 +1,19 @@
/**
* Wrapper for cpp-subprocess. Provides additional convenience functions.
*/
#pragma once
// library includes
#include <subprocess.hpp>
namespace linuxdeploy {
namespace util {
namespace subprocess {
using namespace ::subprocess;
// Reads output channels of existing Popen object into buffers and returns the contents
std::pair<std::string, std::string> check_output_error(Popen& proc);
}
}
}
+1
View File
@@ -1,5 +1,6 @@
// local includes
#include "misc.h"
#include "subprocess.h"
// import functions from misc module for convenience
namespace linuxdeploy {
+36 -8
View File
@@ -1,3 +1,5 @@
include(CTest)
add_library(subprocess INTERFACE)
target_sources(subprocess INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/cpp-subprocess/subprocess.hpp)
target_include_directories(subprocess INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/cpp-subprocess)
@@ -7,14 +9,6 @@ add_library(args INTERFACE)
target_sources(args INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/args/args.hxx)
target_include_directories(args INTERFACE args)
add_library(cpp-feather-ini-parser INTERFACE)
target_sources(cpp-feather-ini-parser INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/cpp-feather-ini-parser/INI.h)
target_include_directories(cpp-feather-ini-parser INTERFACE cpp-feather-ini-parser)
add_executable(test_cpp_feather_ini_parser EXCLUDE_FROM_ALL ${CMAKE_CURRENT_SOURCE_DIR}/cpp-feather-ini-parser/example/example.cpp)
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 INTERFACE)
set_property(TARGET boost_config PROPERTY INTERFACE_INCLUDE_DIRECTORIES "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/boost-config/include>")
@@ -107,4 +101,38 @@ 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)
add_subdirectory(googletest)
endif()
+1
Submodule lib/boost-array added at cef221d8b4
Submodule lib/boost-container added at 76b181f024

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