1 Commits

Author SHA1 Message Date
Alexis Lopez Zubieta 18f2d94241 Print the subprocess output directly to stdout and stderr. 2018-08-04 12:33:41 -05:00
102 changed files with 1461 additions and 4164 deletions
-107
View File
@@ -1,107 +0,0 @@
name: CI
on:
push:
pull_request:
workflow_dispatch:
schedule:
# build at least once a month
- cron: '0 0 1 * *'
jobs:
build-and-test:
strategy:
matrix:
ARCH: [x86_64, i386, aarch64]
BUILD_TYPE: [appimage, coverage]
fail-fast: false
name: ${{ matrix.BUILD_TYPE }} ${{ matrix.ARCH }}
runs-on: ubuntu-latest
env:
ARCH: ${{ matrix.ARCH }}
BUILD_TYPE: ${{ matrix.BUILD_TYPE }}
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
- name: Install dependencies (x86_64)
if: matrix.ARCH == 'x86_64'
run: |
sudo apt-get update
sudo apt-get install -y gcovr libmagic-dev libjpeg-dev libpng-dev libboost-filesystem-dev libboost-regex-dev cimg-dev
- name: Install dependencies (i386)
if: matrix.ARCH == 'i386'
run: |
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y gcovr libmagic-dev:i386 libjpeg-dev:i386 libpng-dev:i386 libboost-filesystem-dev:i386 libboost-regex-dev:i386 cimg-dev gcc-multilib g++-multilib libfuse2:i386
- name: Test coverage (native)
run: bash -ex ci/test-coverage.sh
if: matrix.ARCH != 'aarch64' && matrix.BUILD_TYPE == 'coverage'
- name: Test coverage (VM)
if: matrix.ARCH != 'x86_64' && matrix.ARCH != 'i386' && matrix.BUILD_TYPE == 'coverage'
uses: uraimo/run-on-arch-action@v2.2.0
with:
arch: ${{ matrix.ARCH }}
distro: ubuntu20.04
githubToken: ${{ github.token }}
dockerRunArgs: |
--volume "${PWD}:/build"
install: |
apt-get update
apt-get install -y build-essential wget git pkg-config autoconf libmagic-dev libjpeg-dev libpng-dev cimg-dev libboost-filesystem-dev libboost-regex-dev gcovr
run: |
cd /build
ARCH=$(uname -m) ci/test-coverage.sh
- name: Build, test and build AppImage (native)
if: matrix.ARCH != 'aarch64' && matrix.BUILD_TYPE != 'coverage'
run: bash -ex ci/build.sh
- name: Build, test and build AppImage (VM)
if: matrix.ARCH != 'x86_64' && matrix.ARCH != 'i386' && matrix.BUILD_TYPE != 'coverage'
uses: uraimo/run-on-arch-action@v2.2.0
with:
arch: ${{ matrix.ARCH }}
distro: ubuntu20.04
githubToken: ${{ github.token }}
dockerRunArgs: |
--volume "${PWD}:/build"
install: |
apt-get update
apt-get install -y build-essential wget git pkg-config autoconf libmagic-dev libjpeg-dev libpng-dev cimg-dev libboost-filesystem-dev libboost-regex-dev gcovr
run: |
cd /build
ARCH=$(uname -m) ci/build.sh
- name: Archive artifacts
uses: actions/upload-artifact@v2
if: matrix.BUILD_TYPE != 'coverage'
with:
name: AppImage
path: linuxdeploy*.AppImage*
upload:
name: Create release and upload artifacts
needs:
- build-and-test
runs-on: ubuntu-latest
steps:
- name: Download artifacts
uses: actions/download-artifact@v2
- name: Inspect directory after downloading artifacts
run: ls -alFR
- name: Create release and upload artifacts
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
wget -q https://github.com/TheAssassin/pyuploadtool/releases/download/continuous/pyuploadtool-x86_64.AppImage
chmod +x pyuploadtool-x86_64.AppImage
./pyuploadtool-x86_64.AppImage **/linuxdeploy*.AppImage*
+1 -1
View File
@@ -2,5 +2,5 @@ cmake-build-*/
*build*/
.idea/
squashfs-root/
tests/
*.AppImage
*.swp
+72 -6
View File
@@ -1,12 +1,78 @@
[submodule "lib/cpp-subprocess"]
path = lib/cpp-subprocess
url = https://github.com/arun11299/cpp-subprocess.git
[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
[submodule "lib/boost-regex"]
path = lib/boost-regex
url = https://github.com/boostorg/regex.git
[submodule "lib/boost-system"]
path = lib/boost-system
url = https://github.com/boostorg/system.git
[submodule "lib/boost-config"]
path = lib/boost-config
url = https://github.com/boostorg/config.git
[submodule "lib/boost-utility"]
path = lib/boost-utility
url = https://github.com/boostorg/utility.git
[submodule "lib/boost-predef"]
path = lib/boost-predef
url = https://github.com/boostorg/predef.git
[submodule "lib/boost-assert"]
path = lib/boost-assert
url = https://github.com/boostorg/assert.git
[submodule "lib/boost-core"]
path = lib/boost-core
url = https://github.com/boostorg/core.git
[submodule "lib/boost-type_traits"]
path = lib/boost-type_traits
url = https://github.com/boostorg/type_traits.git
[submodule "lib/boost-iterator"]
path = lib/boost-iterator
url = https://github.com/boostorg/iterator.git
[submodule "lib/boost-mpl"]
path = lib/boost-mpl
url = https://github.com/boostorg/mpl.git
[submodule "lib/boost-preprocessor"]
path = lib/boost-preprocessor
url = https://github.com/boostorg/preprocessor.git
[submodule "lib/boost-static_assert"]
path = lib/boost-static_assert
url = https://github.com/boostorg/static_assert.git
[submodule "lib/boost-detail"]
path = lib/boost-detail
url = https://github.com/boostorg/detail.git
[submodule "lib/boost-smart_ptr"]
path = lib/boost-smart_ptr
url = https://github.com/boostorg/smart_ptr.git
[submodule "lib/boost-exception"]
path = lib/boost-exception
url = https://github.com/boostorg/exception.git
[submodule "lib/linuxdeploy-desktopfile"]
path = lib/linuxdeploy-desktopfile
url = https://github.com/linuxdeploy/linuxdeploy-desktopfile
[submodule "lib/cmake-scripts"]
path = lib/cmake-scripts
url = https://github.com/linuxdeploy/cmake-scripts.git
[submodule "lib/boost-throw_exception"]
path = lib/boost-throw_exception
url = https://github.com/boostorg/throw_exception.git
[submodule "lib/boost-io"]
path = lib/boost-io
url = https://github.com/boostorg/io.git
[submodule "lib/boost-functional"]
path = lib/boost-functional
url = https://github.com/boostorg/functional.git
[submodule "lib/boost-container_hash"]
path = lib/boost-container_hash
url = https://github.com/boostorg/container_hash.git
[submodule "lib/boost-range"]
path = lib/boost-range
url = https://github.com/boostorg/range.git
[submodule "lib/boost-integer"]
path = lib/boost-integer
url = https://github.com/boostorg/integer.git
[submodule "lib/CImg"]
path = lib/CImg
url = https://github.com/dtschump/CImg.git
+53
View File
@@ -0,0 +1,53 @@
language: cpp
sudo: required
matrix:
include:
- env: ARCH=x86_64
addons:
apt:
update: true
packages:
- libmagic-dev
- libjpeg-dev
- libpng-dev
- cimg-dev
- automake # required for patchelf
- env: ARCH=i386
addons:
apt:
update: true
packages:
- libmagic-dev:i386
- libjpeg-dev:i386
- libpng-dev:i386
- gcc-multilib
- g++-multilib
- automake # required for patchelf
- libfuse2:i386
install:
- git clone https://github.com/NixOS/patchelf.git -b 0.8
- cd patchelf
- ./bootstrap.sh
- if [ "$ARCH" == "i386" ]; then ./configure --prefix=/usr --build=i686-pc-linux-gnu CFLAGS=-m32 CXXFLAGS=-m32 LDFLAGS=-m32; fi
- if [ "$ARCH" == "x86_64" ]; then ./configure --prefix=/usr; fi
- make -j$(nproc)
- sudo make install
- cd ..
- rm -rf patchelf
script:
- travis/build.sh
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
- wget -c https://github.com/probonopd/uploadtool/raw/master/upload.sh
- bash upload.sh linuxdeploy-"$ARCH".AppImage*
branches:
except:
- # Do not build tags that we create when we upload to GitHub Releases
- /^(?i:continuous)$/
+5 -44
View File
@@ -5,53 +5,14 @@ project(linuxdeploy C CXX)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(LINUXDEPLOY_VERSION 0.1-alpha-1)
add_definitions(-DLINUXDEPLOY_VERSION="${LINUXDEPLOY_VERSION}")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/cmake/Modules/")
# 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()
include(CTest)
if(BUILD_TESTING)
# including this before including lib/ makes sure that the top level project's gtest is used everywhere
include(${PROJECT_SOURCE_DIR}/lib/cmake-scripts/include-or-build-gtest.cmake)
endif()
set(USE_SYSTEM_BOOST OFF CACHE BOOL "Set to ON to use system boost libraries instead of building up to date boost libraries from source")
set(USE_SYSTEM_CIMG ON CACHE BOOL "Set to OFF to use CImg library bundled in lib directory")
add_subdirectory(lib)
add_subdirectory(src)
if(BUILD_TESTING)
enable_testing()
add_subdirectory(tests)
endif()
+48 -18
View File
@@ -2,7 +2,6 @@
AppDir creation and maintenance tool.
## About
AppImages are a well known and quite popular format for distributing applications from developers to end users.
@@ -14,22 +13,58 @@ linuxdeploy is designed to be an AppDir maintenance tool. It provides extensive
linuxdeploy was greatly influenced by [linuxdeployqt](https://github.com/probonopd/linuxdeployqt), and while it employs stricter rules on AppDirs, it's more flexible in use. If you use linuxdeployqt at the moment, consider switching to linuxdeploy today!
## User guides and examples
## Usage
Please see the [linuxdeploy user guide](https://docs.appimage.org/packaging-guide/from-source/linuxdeploy-user-guide.html) and the [native binaries packaging guide](https://docs.appimage.org/packaging-guide/from-source/native-binaries.html) in the [AppImage documentation](https://docs.appimage.org). There's also an [examples section](https://docs.appimage.org/packaging-guide/from-source/native-binaries.html#examples).
linuxdeploy, being a tool for creating AppDirs and eventually AppImages, is released as an AppImage itself. Please download and use the AppImage for normal use. If you encounter errors, e.g., when building the tool from source, please try with the AppImage first before [creating an issue](https://github.com/TheAssassin/linuxdeploy/issues/new).
There are two main ways to use linuxdeploy: Provide the paths to all files you want to bundle manually, or create an FHS-like directory and run linuxdeploy on it.
## Projects using linuxdeploy
Most build systems provide some kind of `make install` functionality that is capable of producing FHS-like directory trees that can be turned into AppDirs:
This is an incomplete list of projects using linuxdeploy. You might want to read their build scripts to see how they use linuxdeploy.
```sh
# automake
./configure --prefix=/usr
make install DESTDIR=AppDir
- [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)
- [MediaElch](https://github.com/Komet/MediaElch/)
- [CPU-X](https://github.com/X0rg/CPU-X) (details available [here](https://github.com/AppImage/AppImageKit/wiki/Bundling-GTK3-apps#fully-automated-deployment-from-sources-with-github-actions-cpu-x))
# cmake
mkdir build && cd build
cmake .. -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX=/usr
make install DESTDIR=AppDir
# qmake
qmake CONFIG+=release PREFIX=/usr .
make install INSTALL_ROOT=AppDir
```
Now, simply run linuxdeploy like `./linuxdeploy*.AppImage --appdir AppDir`.
Please use `./linuxdeploy*.AppImage --help` to get a list of options supported by linuxdeploy.
If your build system cannot produce such install trees or you prefer to bundle everything manually, you can also specify the paths to the resources yourself. linuxdeploy provides the following options for this use case:
```
-l[library...],
--lib=[library...],
--library=[library...] Shared library to deploy
-e[executable...],
--executable=[executable...] Executable to deploy
-d[desktop file...],
--desktop-file=[desktop file...] Desktop file to deploy
enough for some tests
-i[icon file...],
--icon-file=[icon file...] Icon to deploy
```
An example run could look like this:
```bash
./linuxdeploy*.AppImage --app-name myapp --appdir AppDir --init-appdir -e myapp -d myapp.desktop -i myapp_64x64.png
```
Of course both approaches can be combined, e.g., you can bundle additional executables with your main app.
linuxdeploy doesn't mind being run on an AppDir more than once, as it recognize previous runs, and should not break files within the AppDir. This is to allow you debug issues allows you to run linuxdeploy after resolving an issue that it reports.
If you ever encounter issues when running linuxdeploy on an existing AppDir, please let us know by [creating an issue](https://github.com/TheAssassin/linuxdeploy/issues/new).
## Plugins
@@ -46,14 +81,10 @@ linuxdeploy looks for plugins in the following places:
You can use `./linuxdeploy*.AppImage --list-plugins` to get a list of all the plugins linuxdeploy has detected on your system.
linuxdeploy currently ships with some plugins. These are likely out of date. In case of issues, please download the latest version, which will take precendence over the bundled plugin.
linuxdeploy ships with some plugins
If you want to use a plugin to bundle additional resources, please add `./linuxdeploy*.AppImage --plugin <name>` to your linuxdeploy command. Output plugins can be activated using `./linuxdeploy*.AppImage --output <name>`.
**A list of official and community plugins can be found in the [awesome-linuxdeploy](http://github.com/linuxdeploy/awesome-linuxdeploy) project.**
**Note:** If you want to suggest a plugin for a specific framework, language etc., please feel free to [create a new issue](https://github.com/linuxdeploy/linuxdeploy/issues/new). Current plugin requests can be found [here](https://github.com/linuxdeploy/linuxdeploy/issues?utf8=%E2%9C%93&q=label%3A%22plugin+request%22).
## Troubleshooting
@@ -61,7 +92,6 @@ If you want to use a plugin to bundle additional resources, please add `./linuxd
linuxdeploy does not change any environment variables such as `$PATH`. Your application **must** search for additional resources such as icon files or executables relative to the main binary.
## Contact
The easiest way to get in touch with the developers is to join the IRC chatroom [#AppImage](https://webchat.freenode.net/?channels=appimage) on FreeNode. This is the preferred way for general feedback or questions how to use this application.
-59
View File
@@ -1,59 +0,0 @@
#! /bin/bash
set -e
set -x
INSTALL_DESTDIR="$1"
if [[ "$INSTALL_DESTDIR" == "" ]]; then
echo "Error: build dir $BUILD_DIR does not exist" 1>&2
exit 1
fi
# support cross-compilation for 32-bit ISAs
case "$ARCH" in
"x86_64"|"amd64"|"armhf"|"aarch64")
;;
"i386"|"i586"|"i686")
export CFLAGS="-m32"
export CXXFLAGS="-m32"
;;
*)
echo "Error: unsupported architecture: $ARCH"
exit 1
;;
esac
# use RAM disk if possible
if [ "$CI" == "" ] && [ -d /dev/shm ]; then
TEMP_BASE=/dev/shm
else
TEMP_BASE=/tmp
fi
cleanup () {
if [ -d "$BUILD_DIR" ]; then
rm -rf "$BUILD_DIR"
fi
}
trap cleanup EXIT
BUILD_DIR=$(mktemp -d -p "$TEMP_BASE" linuxdeploy-build-XXXXXX)
pushd "$BUILD_DIR"
# fetch source code
wget http://mirrors.kernel.org/gnu/binutils/binutils-2.35.tar.xz -O- | tar xJ --strip-components=1
# configure static build
# inspired by https://github.com/andrew-d/static-binaries/blob/master/binutils/build.sh
./configure --prefix=/usr --disable-nls --enable-static-link --disable-shared-plugins --disable-dynamicplugin --disable-tls --disable-pie
# citing the script linked above: "This strange dance is required to get things to be statically linked."
make -j "$(nproc)"
make clean
make -j "$(nproc)" LDFLAGS="-all-static"
# install into user-specified destdir
make install DESTDIR="$(readlink -f "$INSTALL_DESTDIR")"
-62
View File
@@ -1,62 +0,0 @@
#! /bin/bash
set -e
set -x
INSTALL_DESTDIR="$1"
if [[ "$INSTALL_DESTDIR" == "" ]]; then
echo "Error: build dir $BUILD_DIR does not exist" 1>&2
exit 1
fi
# support cross-compilation for 32-bit ISAs
case "$ARCH" in
"x86_64"|"amd64"|"armhf"|"aarch64")
;;
"i386"|"i586"|"i686")
export CFLAGS="-m32"
export CXXFLAGS="-m32"
;;
*)
echo "Error: unsupported architecture: $ARCH"
exit 1
;;
esac
# use RAM disk if possible
if [ "$CI" == "" ] && [ -d /dev/shm ]; then
TEMP_BASE=/dev/shm
else
TEMP_BASE=/tmp
fi
cleanup () {
if [ -d "$BUILD_DIR" ]; then
rm -rf "$BUILD_DIR"
fi
}
trap cleanup EXIT
BUILD_DIR=$(mktemp -d -p "$TEMP_BASE" linuxdeploy-build-XXXXXX)
pushd "$BUILD_DIR"
# fetch source code
git clone https://github.com/NixOS/patchelf.git .
# cannot use -b since it's not supported in really old versions of git
git checkout 0.8
# prepare configure script
./bootstrap.sh
# configure static build
env LDFLAGS="-static -static-libgcc -static-libstdc++" ./configure --prefix=/usr
# build binary
make -j "$(nproc)"
# install into user-specified destdir
make install DESTDIR="$INSTALL_DESTDIR"
-98
View File
@@ -1,98 +0,0 @@
#! /bin/bash
set -e
set -x
# use RAM disk if possible
if [ "$CI" == "" ] && [ -d /dev/shm ]; then
TEMP_BASE=/dev/shm
else
TEMP_BASE=/tmp
fi
BUILD_DIR=$(mktemp -d -p "$TEMP_BASE" linuxdeploy-build-XXXXXX)
cleanup () {
if [ -d "$BUILD_DIR" ]; then
rm -rf "$BUILD_DIR"
fi
}
trap cleanup EXIT
# store repo root as variable
REPO_ROOT=$(readlink -f $(dirname $(dirname $0)))
OLD_CWD=$(readlink -f .)
pushd "$BUILD_DIR"
if [ "$ARCH" == "x86_64" ]; then
EXTRA_CMAKE_ARGS=()
elif [ "$ARCH" == "i386" ]; then
EXTRA_CMAKE_ARGS=("-DCMAKE_TOOLCHAIN_FILE=$REPO_ROOT/cmake/toolchains/i386-linux-gnu.cmake" "-DUSE_SYSTEM_CIMG=OFF")
elif [ "$ARCH" == "armhf" ]; then
EXTRA_CMAKE_ARGS=()
elif [ "$ARCH" == "aarch64" ]; then
EXTRA_CMAKE_ARGS=()
else
echo "Architecture not supported: $ARCH" 1>&2
exit 1
fi
# fetch up-to-date CMake
mkdir cmake-prefix
wget -O- https://github.com/Kitware/CMake/releases/download/v3.19.6/cmake-3.19.6-Linux-$(uname -m).tar.gz | tar -xz -C cmake-prefix --strip-components=1
export PATH="$(readlink -f cmake-prefix/bin):$PATH"
cmake --version
# configure build for AppImage release
cmake "$REPO_ROOT" -DSTATIC_BUILD=On -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=RelWithDebInfo "${EXTRA_CMAKE_ARGS[@]}"
make -j"$(nproc)"
## Run Unit Tests
ctest -V
# build patchelf
"$REPO_ROOT"/ci/build-static-patchelf.sh "$(readlink -f out/)"
patchelf_path="$(readlink -f out/usr/bin/patchelf)"
# build custom strip
"$REPO_ROOT"/ci/build-static-binutils.sh "$(readlink -f out/)"
strip_path="$(readlink -f out/usr/bin/strip)"
# use tools we just built for linuxdeploy run
export PATH="$(readlink -f out/usr/bin):$PATH"
# args are used more than once
LINUXDEPLOY_ARGS=("--appdir" "AppDir" "-e" "bin/linuxdeploy" "-i" "$REPO_ROOT/resources/linuxdeploy.png" "-d" "$REPO_ROOT/resources/linuxdeploy.desktop" "-e" "$patchelf_path" "-e" "$strip_path")
# deploy patchelf which is a dependency of linuxdeploy
bin/linuxdeploy "${LINUXDEPLOY_ARGS[@]}"
# bundle AppImage plugin
mkdir -p AppDir/plugins
wget https://github.com/encounter/linuxdeploy-plugin-appimage/releases/download/continuous/linuxdeploy-plugin-appimage-"$ARCH".AppImage
chmod +x linuxdeploy-plugin-appimage-"$ARCH".AppImage
./linuxdeploy-plugin-appimage-"$ARCH".AppImage --appimage-extract
mv squashfs-root/ AppDir/plugins/linuxdeploy-plugin-appimage
ln -s ../../plugins/linuxdeploy-plugin-appimage/AppRun AppDir/usr/bin/linuxdeploy-plugin-appimage
export UPD_INFO="gh-releases-zsync|linuxdeploy|linuxdeploy|continuous|linuxdeploy-$ARCH.AppImage.zsync"
export OUTPUT="linuxdeploy-$ARCH.AppImage"
# build AppImage using plugin
AppDir/usr/bin/linuxdeploy-plugin-appimage --appdir AppDir/
# rename AppImage to avoid "Text file busy" issues when using it to create another one
mv "$OUTPUT" test.AppImage
# verify that the resulting AppImage works
./test.AppImage "${LINUXDEPLOY_ARGS[@]}"
# check whether AppImage plugin is found and works
./test.AppImage "${LINUXDEPLOY_ARGS[@]}" --output appimage
mv "$OUTPUT"* "$OLD_CWD"/
-9
View File
@@ -1,9 +0,0 @@
#! /bin/bash
# get a compiler that allows for using modern-ish C++ (>= 11) on a distro that doesn't normally support it
# before you ask: yes, the binaries will work on CentOS 6 even without devtoolset (they somehow partially link C++
# things statically while using others from the system...)
# so, basically, it's magic!
source /opt/rh/devtoolset-*/enable
exec "$@"
-45
View File
@@ -1,45 +0,0 @@
#! /bin/bash
set -e
set -x
# use RAM disk if possible
if [ "$CI" == "" ] && [ -d /dev/shm ]; then
TEMP_BASE=/dev/shm
else
TEMP_BASE=/tmp
fi
BUILD_DIR=$(mktemp -d -p "$TEMP_BASE" linuxdeploy-build-XXXXXX)
cleanup () {
if [ -d "$BUILD_DIR" ]; then
rm -rf "$BUILD_DIR"
fi
}
trap cleanup EXIT
# store repo root as variable
REPO_ROOT=$(readlink -f $(dirname $(dirname $0)))
OLD_CWD=$(readlink -f .)
pushd "$BUILD_DIR"
if [ "$ARCH" == "x86_64" ]; then
EXTRA_CMAKE_ARGS=()
elif [ "$ARCH" == "i386" ]; then
EXTRA_CMAKE_ARGS=("-DCMAKE_TOOLCHAIN_FILE=$REPO_ROOT/cmake/toolchains/i386-linux-gnu.cmake" "-DUSE_SYSTEM_CIMG=OFF")
elif [ "$ARCH" == "armhf" ]; then
EXTRA_CMAKE_ARGS=()
elif [ "$ARCH" == "aarch64" ]; then
EXTRA_CMAKE_ARGS=()
else
echo "Architecture not supported: $ARCH" 1>&2
exit 1
fi
cmake "$REPO_ROOT" -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Debug -DENABLE_COVERAGE=ON "${EXTRA_CMAKE_ARGS[@]}"
# build, run tests and show coverage report
make -j$(nproc) coverage_text
-362
View File
@@ -1,362 +0,0 @@
# 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}
# Clean old coverage data
COMMAND find ${PROJECT_BINARY_DIR} -type f -iname '*.gcno' -delete
# Run tests
COMMAND ${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}
# Clean old coverage data
COMMAND find ${PROJECT_BINARY_DIR} -type f -iname '*.gcno' -delete
# Run tests
COMMAND ${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}
# Clean old coverage data
COMMAND find ${PROJECT_BINARY_DIR} -type f -iname '*.gcno' -delete
# Run tests
COMMAND ${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
+19 -88
View File
@@ -1,97 +1,28 @@
#[=======================================================================[.rst:
FindCImg
-------
# required for PNG imported target
cmake_minimum_required(VERSION 3.5)
Finds the CImg library.
find_package(PNG REQUIRED)
find_package(JPEG REQUIRED)
Imported Targets
^^^^^^^^^^^^^^^^
if(NOT USE_SYSTEM_CIMG)
message(STATUS "Using bundled CImg library")
This module provides the following imported targets, if found:
``CImg``
The CImg library
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``CImg_FOUND``
True if the system has the CImg library.
``CImg_VERSION``
The version of the CImg library which was found.
``CImg_INCLUDE_DIRS``
Include directories needed to use CImg.
``CImg_LIBRARIES``
Libraries needed to link to CImg.
Cache Variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``CImg_INCLUDE_DIR``
The directory containing ``CImg.h``.
#]=======================================================================]
# 3.6 required for PNG imported target
# 3.9 required for CMAKE_MATCH_<n>
cmake_minimum_required(VERSION 3.9)
find_path(CIMG_H_DIR
NAMES CImg.h
HINTS ${CMAKE_INSTALL_PREFIX} ${CIMG_DIR}
PATH_SUFFIXES include include/linux
)
if(NOT CIMG_H_DIR)
set(CImg_FOUND FALSE)
set(CIMG_H_DIR "${PROJECT_SOURCE_DIR}/lib/CImg/")
else()
set(CImg_FOUND TRUE)
message(STATUS "Searching for CImg")
find_package(PkgConfig)
find_path(CIMG_H_DIR
NAMES CImg.h
HINTS ${CMAKE_INSTALL_PREFIX}
PATH_SUFFIXES include include/linux
)
pkg_check_modules(libpng REQUIRED libpng)
pkg_check_modules(libjpeg REQUIRED libjpeg)
set(PNG_INCLUDE_DIR ${libpng_INCLUDE_DIRS})
set(JPEG_INCLUDE_DIR ${libjpeg_INCLUDE_DIRS})
if(STATIC_BUILD)
set(PNG_LIBRARY ${libpng_STATIC_LIBRARIES})
set(JPEG_LIBRARIES ${libjpeg_STATIC_LIBRARIES})
else()
set(PNG_LIBRARY ${libpng_LIBRARIES})
set(JPEG_LIBRARIES ${libjpeg_LIBRARIES})
endif()
set(CImg_INCLUDE_DIR ${CIMG_H_DIR} CACHE STRING "")
set(CImg_INCLUDE_DIRS ${CImg_INCLUDE_DIR})
set(CImg_LIBRARIES "${PNG_LIBRARY};${JPEG_LIBRARIES}")
set(CImg_DEFINITIONS "cimg_display=0;cimg_use_png=1;cimg_use_jpeg=1")
file(READ "${CIMG_H_DIR}/CImg.h" header)
string(REGEX MATCH "#define cimg_version ([0-9a-zA-Z\.]+)" _ "${header}")
set(CImg_VERSION "${CMAKE_MATCH_1}")
# CImg_VERSION
if(NOT TARGET CImg)
add_library(CImg INTERFACE)
set_property(TARGET CImg PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CIMG_H_DIR};${PNG_INCLUDE_DIR};${JPEG_INCLUDE_DIR}")
set_property(TARGET CImg PROPERTY INTERFACE_LINK_LIBRARIES "${CImg_LIBRARIES}")
set_property(TARGET CImg PROPERTY INTERFACE_COMPILE_DEFINITIONS "${CImg_DEFINITIONS}")
if(NOT CIMG_H_DIR)
message(FATAL_ERROR "CImg.h not found")
endif()
endif()
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(CImg
FOUND_VAR CImg_FOUND
REQUIRED_VARS
CImg_INCLUDE_DIRS
CImg_LIBRARIES
CImg_DEFINITIONS
VERSION_VAR CImg_VERSION
)
add_library(CImg INTERFACE)
set_property(TARGET CImg PROPERTY INTERFACE_INCLUDE_DIRECTORIES "${CIMG_H_DIR};${JPEG_INCLUDE_DIR}")
set_property(TARGET CImg PROPERTY INTERFACE_LINK_LIBRARIES "PNG::PNG;${JPEG_LIBRARIES}")
set_property(TARGET CImg PROPERTY INTERFACE_COMPILE_DEFINITIONS "cimg_display=0;cimg_use_png=1;cimg_use_jpeg=1")
+24
View File
@@ -0,0 +1,24 @@
# required for zlib imported target
cmake_minimum_required(VERSION 3.3)
message(STATUS "Searching for libmagic")
find_library(LIBMAGIC_LIBRARIES magic)
if(NOT LIBMAGIC_LIBRARIES)
message(FATAL_ERROR "libmagic not found")
endif()
find_path(LIBMAGIC_MAGIC_H_DIR
NAMES magic.h
HINTS ${CMAKE_INSTALL_PREFIX}
PATH_SUFFIXES include include/linux
)
if(NOT LIBMAGIC_MAGIC_H_DIR)
message(FATAL_ERROR "magic.h not found")
endif()
add_library(libmagic_static INTERFACE IMPORTED)
set_property(TARGET libmagic_static PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${LIBMAGIC_MAGIC_H_DIR})
set_property(TARGET libmagic_static PROPERTY INTERFACE_LINK_LIBRARIES ${LIBMAGIC_LIBRARIES})
-3
View File
@@ -3,6 +3,3 @@ 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)
+19 -38
View File
@@ -1,12 +1,11 @@
// system includes
#include <memory>
#include <string>
// library includes
#include <boost/filesystem.hpp>
// local includes
#include "linuxdeploy/desktopfile/desktopfile.h"
#include "linuxdeploy/core/desktopfile.h"
#pragma once
@@ -20,7 +19,7 @@ namespace linuxdeploy {
private:
// private data class pattern
class PrivateData;
std::shared_ptr<PrivateData> d;
PrivateData* d;
public:
// default constructor
@@ -28,21 +27,14 @@ namespace linuxdeploy {
// the directory will be created if it doesn't exist
explicit AppDir(const boost::filesystem::path& path);
// we don't want any copy/move(-assignment) behavior, therefore we delete those operators/constructors
AppDir(const AppDir&) = delete;
AppDir(AppDir&&) = delete;
void operator=(const AppDir&) = delete;
void operator=(AppDir&&) = delete;
~AppDir();
// alternative constructor
// shortcut for using a normal string instead of a path
explicit AppDir(const std::string& path);
// Set additional shared library name patterns to be excluded from deployment.
void setExcludeLibraryPatterns(const std::vector<std::string> &excludeLibraryPatterns);
// creates basic directory structure of an AppDir in "FHS" mode
bool createBasicStructure() const;
bool createBasicStructure();
// deploy shared library
//
@@ -60,62 +52,51 @@ namespace linuxdeploy {
// deploy executable
bool deployExecutable(const boost::filesystem::path& path, const boost::filesystem::path& destination = "");
// deploy dependencies for ELF file in AppDir, without copying it into the library dir
//
// the dependencies end up in the regular location
bool deployDependenciesOnlyForElfFile(const boost::filesystem::path& elfFilePath, bool failSilentForNonElfFile = false);
// deploy desktop file
bool deployDesktopFile(const desktopfile::DesktopFile& desktopFile);
// deploy icon
bool deployIcon(const boost::filesystem::path& path);
// deploy icon, changing its name to <target filename>.<ext>
bool deployIcon(const boost::filesystem::path& path, const std::string& targetFilename);
// deploy arbitrary file
boost::filesystem::path deployFile(const boost::filesystem::path& from, const boost::filesystem::path& to);
// copy arbitrary file (immediately)
bool copyFile(const boost::filesystem::path& from, const boost::filesystem::path& to, bool overwrite = false) const;
// create an <AppDir> relative symlink to <target> at <symlink>.
bool createRelativeSymlink(const boost::filesystem::path& target, const boost::filesystem::path& symlink) const;
void deployFile(const boost::filesystem::path& from, const boost::filesystem::path& to);
// execute deferred copy operations
bool executeDeferredOperations();
// return path to AppDir
boost::filesystem::path path() const;
boost::filesystem::path path();
// create a list of all icon paths in the AppDir
std::vector<boost::filesystem::path> deployedIconPaths() const;
std::vector<boost::filesystem::path> deployedIconPaths();
// create a list of all executable paths in the AppDir
std::vector<boost::filesystem::path> deployedExecutablePaths() const;
std::vector<boost::filesystem::path> deployedExecutablePaths();
// create a list of all desktop file paths in the AppDir
std::vector<desktopfile::DesktopFile> deployedDesktopFiles() const;
std::vector<desktopfile::DesktopFile> deployedDesktopFiles();
// create symlinks for AppRun, desktop file and icon in the AppDir root directory
bool setUpAppDirRoot(const desktopfile::DesktopFile& desktopFile, boost::filesystem::path customAppRunPath = "");
bool createLinksInAppDirRoot(const desktopfile::DesktopFile& desktopFile, boost::filesystem::path customAppRunPath = "");
// set application name of primary "entry point" application
// icons and other resources will then automatically be renamed using this value in order to
// make the deployment easier by not requiring special filenames
// resources' filenames should be prefixed with this value (example: linuxdeploy_48x48.png)
void setAppName(const std::string& appName);
// list all executables in <AppDir>/usr/bin
// this function does not perform a recursive search, but only searches the bin directory
std::vector<boost::filesystem::path> listExecutables() const;
std::vector<boost::filesystem::path> listExecutables();
// list all shared libraries in <AppDir>/usr/lib
// this function recursively searches the entire lib directory for shared libraries
std::vector<boost::filesystem::path> listSharedLibraries() const;
std::vector<boost::filesystem::path> listSharedLibraries();
// search for executables and libraries and deploy their dependencies
// calling this function can turn sure file trees created by make install commands into working
// AppDirs
bool deployDependenciesForExistingFiles() const;
// disable deployment of copyright files for this instance
void setDisableCopyrightFilesDeployment(bool disable);
bool deployDependenciesForExistingFiles();
};
}
}
+71
View File
@@ -0,0 +1,71 @@
// 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;
};
}
}
}
@@ -1,8 +1,6 @@
// system includes
#include <vector>
#include <string>
// including system elf header, which allows for interpretation of the return values of the methods
#include <elf.h>
// library includes
#include <boost/filesystem.hpp>
@@ -11,19 +9,13 @@
namespace linuxdeploy {
namespace core {
namespace elf_file {
namespace elf {
// thrown by constructor if file is not an ELF file
class ElfFileParseError : public std::runtime_error {
public:
explicit ElfFileParseError(const std::string& msg) : std::runtime_error(msg) {}
};
// thrown by traceDynamicDependencies() if a dependency is missing
class DependencyNotFoundError : public std::runtime_error {
public:
explicit DependencyNotFoundError(const std::string& msg) : std::runtime_error(msg) {}
};
class ElfFile {
private:
class PrivateData;
@@ -33,16 +25,6 @@ namespace linuxdeploy {
explicit ElfFile(const boost::filesystem::path& path);
~ElfFile();
public:
// return system ELF OS ABI
static uint8_t getSystemElfABI();
// return system ELF class (32-bit or 64-bit)
static uint8_t getSystemElfClass();
// return system (ELF) endianness
static uint8_t getSystemElfEndianness();
public:
// recursively trace dynamic library dependencies of a given ELF file
// this works for both libraries and executables
@@ -58,18 +40,6 @@ namespace linuxdeploy {
// set rpath in ELF file
// returns true on success, false otherwise
bool setRPath(const std::string& value);
// return ELF class
uint8_t getElfClass();
// return OS ABI
uint8_t getElfABI();
// check if this file is a debug symbols file
bool isDebugSymbolsFile();
// check whether the file contains a dynsym section
bool isDynamicallyLinked();
};
}
}
-2
View File
@@ -65,8 +65,6 @@ namespace linuxdeploy {
ldLog operator<<(stdEndlType strm);
ldLog operator<<(const LD_LOGLEVEL logLevel);
ldLog operator<<(const LD_STREAM_CONTROL streamControl);
void write(const char* s, const size_t n);
};
}
}
+22 -22
View File
@@ -2,19 +2,15 @@
#include <set>
#include <string>
#include <vector>
#include <fcntl.h>
#include <poll.h>
// library headers
#include <boost/filesystem.hpp>
#include <fnmatch.h>
#include <thread>
#include <subprocess.hpp>
// local headers
#include "linuxdeploy/core/log.h"
#include "linuxdeploy/util/util.h"
#include "linuxdeploy/subprocess/process.h"
#include "linuxdeploy/plugin/plugin_process_handler.h"
#pragma once
@@ -23,8 +19,6 @@
namespace linuxdeploy {
namespace plugin {
namespace base {
using namespace linuxdeploy::core::log;
template<int API_LEVEL>
class PluginBase<API_LEVEL>::PrivateData {
public:
@@ -49,20 +43,13 @@ namespace linuxdeploy {
private:
int getApiLevelFromExecutable() {
const auto arg = "--plugin-api-version";
const subprocess::subprocess proc({pluginPath.string(), arg});
const auto stdoutOutput = proc.check_output();
if (stdoutOutput.empty()) {
ldLog() << LD_WARNING << "received empty response from plugin" << pluginPath << "while trying to fetch data for" << "--plugin-api-version" << std::endl;
return -1;
}
auto output = subprocess::check_output({pluginPath.c_str(), "--plugin-api-version"});
std::string stdoutOutput = output.buf.data();
try {
auto apiLevel = std::stoi(stdoutOutput);
return apiLevel;
} catch (const std::exception&) {
} catch (const std::invalid_argument&) {
return -1;
}
}
@@ -73,8 +60,9 @@ namespace linuxdeploy {
// check whether plugin implements --plugin-type
try {
const subprocess::subprocess proc({pluginPath.c_str(), "--plugin-type"});
const auto stdoutOutput = proc.check_output();
auto output = subprocess::check_output({pluginPath.c_str(), "--plugin-type"});
std::string stdoutOutput = output.buf.data();
// the specification requires a single line, but we'll silently accept more than that, too
if (std::count(stdoutOutput.begin(), stdoutOutput.end(), '\n') >= 1) {
@@ -85,7 +73,7 @@ namespace linuxdeploy {
else if (firstLine == "output")
type = OUTPUT_TYPE;
}
} catch (const std::logic_error&) {}
} catch (const subprocess::CalledProcessError&) {}
return type;
}
@@ -136,8 +124,20 @@ namespace linuxdeploy {
template<int API_LEVEL>
int PluginBase<API_LEVEL>::run(const boost::filesystem::path& appDirPath) {
plugin_process_handler handler(d->name, path());
return handler.run(appDirPath);
auto pluginPath = path();
auto args = {pluginPath.c_str(), "--appdir", appDirPath.string().c_str()};
auto log = linuxdeploy::core::log::ldLog();
log << "Running process:";
for (const auto& arg : args) {
log << "" << arg;
}
log << std::endl;
auto process = subprocess::Popen(args, subprocess::output{stdout}, subprocess::error{stderr});
process.wait();
return process.retcode();
}
}
}

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