You've already forked linuxdeploy
mirror of
https://github.com/encounter/linuxdeploy.git
synced 2026-07-10 12:18:44 -07:00
Compare commits
158 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ee0acdb6f1 | |||
| e069f6cd22 | |||
| 74d482612a | |||
| 8f2a49daf0 | |||
| 4a9e0583d0 | |||
| d83ca617e6 | |||
| 16483c38e4 | |||
| 65ef0bd7ed | |||
| 60f2cb78cd | |||
| 9b8d7698f4 | |||
| 5b1b91da5f | |||
| 44571a4c6b | |||
| 744368868b | |||
| d476f308f8 | |||
| 232a76d1ba | |||
| b97c8b45f5 | |||
| d6e6cac6e0 | |||
| 830dc50136 | |||
| 16ed8bfa6a | |||
| dbfdc6ebe6 | |||
| a6b09ee30c | |||
| 8b8255b158 | |||
| a87fd648e0 | |||
| 574a883733 | |||
| aaaca8b321 | |||
| 22bbd04304 | |||
| 96b5c3c479 | |||
| 35e67a26bb | |||
| 74fb390e2f | |||
| 3b3f86f9a2 | |||
| e6341435bd | |||
| e388ad9eb6 | |||
| b1838315d9 | |||
| 6e525e0a65 | |||
| b540240ba5 | |||
| 5d219c99b7 | |||
| 459c5aad9a | |||
| c6a517c1f5 | |||
| 11bbe4d219 | |||
| 0d59a27905 | |||
| a4e48db545 | |||
| b56e202c40 | |||
| 8b4feb5fd5 | |||
| 156b45f819 | |||
| 3e1d340612 | |||
| 8a2d57e8d5 | |||
| be1b2c95d4 | |||
| 4bb1ef124b | |||
| 93c947b56a | |||
| 4bf295d4d6 | |||
| 2c40482bc0 | |||
| a647205226 | |||
| 73832323c8 | |||
| 169275e023 | |||
| 78e5d0858e | |||
| b4efb2bc56 | |||
| aa2e8b9105 | |||
| 793b35dc61 | |||
| 5ba8b613d6 | |||
| 75f2511437 | |||
| 9a4916fe84 | |||
| e584088656 | |||
| 8a79cfbe1d | |||
| 22ecabc51b | |||
| 81dfae892c | |||
| bedd66d161 | |||
| 62f04213ce | |||
| 4790fabc44 | |||
| 6112a6353e | |||
| 82b7ccd76a | |||
| 4e33e395de | |||
| 9d25fee1dc | |||
| 9d78e0786b | |||
| 9f20e5829d | |||
| 5055efdc05 | |||
| 19ecbb2d70 | |||
| 0e92331a12 | |||
| 4bf1948774 | |||
| f201c57177 | |||
| d7c0e94f11 | |||
| 700f6fe15f | |||
| 012e621ec5 | |||
| 6c674aa184 | |||
| 553bb9fcb0 | |||
| 906dcab283 | |||
| fc3d80c281 | |||
| f0bb1fb472 | |||
| f3f30166f2 | |||
| 2210b7e65d | |||
| cc800588d2 | |||
| 29cda3b1ac | |||
| 16b0a5948a | |||
| 41569a4f53 | |||
| 7ff05ca98e | |||
| cab57f86d6 | |||
| 93fea697e5 | |||
| bd12fefc35 | |||
| 2cdedc252c | |||
| 1fa90fbd5c | |||
| 7318d68c96 | |||
| e5f4755da7 | |||
| 31f20a398f | |||
| d9ca907da8 | |||
| 542edaf410 | |||
| e683561430 | |||
| 0de7caa8ee | |||
| f1690cc2a3 | |||
| 53e0850a2b | |||
| 3949a5fc57 | |||
| 001b8f974c | |||
| 2f5e04ec24 | |||
| 8d01c448d3 | |||
| 10df75f877 | |||
| 0c5b198e2f | |||
| 5d2984ae02 | |||
| 33829c07d0 | |||
| 90f8ed26b8 | |||
| cbaa343a82 | |||
| 9cf0663baa | |||
| e94494ea31 | |||
| 2dce34daf9 | |||
| 7260078b6c | |||
| 4bdceec7d8 | |||
| ca6c710c38 | |||
| 8a31d3d677 | |||
| 5e94977f78 | |||
| 2f96dec588 | |||
| a1308955e7 | |||
| 7e4a320f61 | |||
| 172db51186 | |||
| d09186f69f | |||
| 376eddb14d | |||
| 47ff6c8e9d | |||
| 41371c9d90 | |||
| eacc907c85 | |||
| 4c9943f0d1 | |||
| a0503a7102 | |||
| f1e752d452 | |||
| 55b6ee19e1 | |||
| 4c0d5ea891 | |||
| 83a8f52f98 | |||
| b1bf306510 | |||
| d2a021d57b | |||
| 2f7ad201f1 | |||
| 485507a2d1 | |||
| cdee469e60 | |||
| a892d066cc | |||
| 57175e0c75 | |||
| 88695de067 | |||
| 0f19458792 | |||
| c8d78eb602 | |||
| 6b8b59ee77 | |||
| 3674af54b2 | |||
| 73ecd9d318 | |||
| 1ad4e5e6a9 | |||
| f3b54236a6 | |||
| e885b47208 | |||
| 89788f5e26 |
@@ -2,5 +2,4 @@ cmake-build-*/
|
||||
*build*/
|
||||
.idea/
|
||||
squashfs-root/
|
||||
tests/
|
||||
*.AppImage
|
||||
|
||||
+24
-3
@@ -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
@@ -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*
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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)
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,34 +5,12 @@
|
||||
#include <cstring>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
#include <boost/filesystem.hpp>
|
||||
|
||||
namespace linuxdeploy {
|
||||
namespace util {
|
||||
namespace misc {
|
||||
static bool path_contains_file(boost::filesystem::path dir, boost::filesystem::path file) {
|
||||
// If dir ends with "/" and isn't the root directory, then the final
|
||||
// component returned by iterators will include "." and will interfere
|
||||
// with the std::equal check below, so we strip it before proceeding.
|
||||
if (dir.filename() == ".")
|
||||
dir.remove_filename();
|
||||
// We're also not interested in the file's name.
|
||||
assert(file.has_filename());
|
||||
file.remove_filename();
|
||||
|
||||
// If dir has more components than file, then file can't possibly
|
||||
// reside in dir.
|
||||
auto dir_len = std::distance(dir.begin(), dir.end());
|
||||
auto file_len = std::distance(file.begin(), file.end());
|
||||
if (dir_len > file_len)
|
||||
return false;
|
||||
|
||||
// This stops checking when it reaches dir.end(), so it's OK if file
|
||||
// has more directory components afterward. They won't be checked.
|
||||
return std::equal(dir.begin(), dir.end(), file.begin());
|
||||
};
|
||||
|
||||
static inline bool ltrim(std::string& s, char to_trim = ' ') {
|
||||
// TODO: find more efficient way to check whether elements have been removed
|
||||
size_t initialLength = s.length();
|
||||
|
||||
@@ -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,5 +1,6 @@
|
||||
// local includes
|
||||
#include "misc.h"
|
||||
#include "subprocess.h"
|
||||
|
||||
// import functions from misc module for convenience
|
||||
namespace linuxdeploy {
|
||||
|
||||
+36
-8
@@ -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()
|
||||
|
||||
Submodule
+1
Submodule lib/boost-array added at cef221d8b4
Submodule
+1
Submodule lib/boost-concept_check added at 7dbaa85413
Submodule
+1
Submodule lib/boost-container added at 76b181f024
Submodule
+1
Submodule lib/boost-lexical_cast added at 5cd9771337
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user