Migrate Desktop build environment to leverage Nix

- Add Conan to default.nix
- Integrate Qt5 Nix package (with forked repo for new QtWebView module)
- Fix rpaths in macOS and Linux
- Add Nix expressions to install nsis, appimagekit and linuxdeployqt
This commit is contained in:
Pedro Pombeiro 2019-02-15 09:04:03 +01:00
parent 2e7891406b
commit 2ac5ee019e
No known key found for this signature in database
GPG Key ID: C4A24185B2AA48A1
18 changed files with 731 additions and 261 deletions

View File

@ -5,8 +5,8 @@ android-sdk;4333796;aa190cfd7299cd6a1c687355bb2764e4
bundler;1.17.2;bundler
clojure_cli;1.9.0.391;
cmake;3.11.2;
conan;1.9.0;
golang;1.10.8;
conan;1.12.0;
golang;1.11.5;
leiningen;2.8.1;
maven;3.5.4;
nix;2.2.1;

View File

@ -1,52 +1,59 @@
let
pkgs = import ((import <nixpkgs> { }).fetchFromGitHub {
owner = "NixOS";
owner = "status-im";
repo = "nixpkgs";
rev = "168cbb39691cca2822ce1fdb3e8c0183af5c6d0d";
sha256 = "0fqasswfqrz2rbag9bz17j8y7615s0p9l23cw4sk2f384gk0zf6c";
rev = "15623aac6e8cbfa24d4268195bc8eda7303ea2ff";
sha256 = "0crjmspk65rbpkl3kqcj7433355i9fy530lhc48g2cz75xjk4sxh";
}) { config = { }; };
nodejs = pkgs."nodejs-10_x";
nodeInputs = import ./scripts/lib/setup/nix/global-node-packages/output {
# The remaining dependencies come from Nixpkgs
inherit pkgs;
inherit nodejs;
};
nodePkgs = (map (x: nodeInputs."${x}") (builtins.attrNames nodeInputs));
in pkgs.stdenv.mkDerivation rec {
name = "env";
env = pkgs.buildEnv { name = name; paths = buildInputs; };
statusDesktopBuildInputs = with pkgs; [
cmake
extra-cmake-modules
go_1_10
] ++ stdenv.lib.optional stdenv.isLinux python37; # for Conan
buildInputs = with pkgs; [
clojure
jq
leiningen
lsof # used in scripts/start-react-native.sh
maven
nodejs
openjdk
python27 # for e.g. gyp
watchman
unzip
wget
yarn
] ++ nodePkgs
++ statusDesktopBuildInputs
++ stdenv.lib.optional stdenv.isDarwin cocoapods;
shellHook = with pkgs; ''
local toolversion="$(git rev-parse --show-toplevel)/scripts/toolversion"
export JAVA_HOME="${openjdk}"
export ANDROID_HOME=~/.status/Android/Sdk
export ANDROID_SDK_ROOT="$ANDROID_HOME"
export ANDROID_NDK_ROOT="$ANDROID_SDK_ROOT/android-ndk-$($toolversion android-ndk)"
export ANDROID_NDK_HOME="$ANDROID_NDK_ROOT"
export ANDROID_NDK="$ANDROID_NDK_ROOT"
export PATH="$ANDROID_HOME/bin:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools:$PATH"
in with pkgs;
let
_stdenv = stdenvNoCC; # TODO: Try to use stdenv for Darwin
statusDesktop = callPackage ./scripts/lib/setup/nix/desktop { stdenv = _stdenv; };
nodeInputs = import ./scripts/lib/setup/nix/global-node-packages/output {
# The remaining dependencies come from Nixpkgs
inherit pkgs;
inherit nodejs;
};
nodePkgs = [
nodejs
python27 # for e.g. gyp
yarn
] ++ (map (x: nodeInputs."${x}") (builtins.attrNames nodeInputs));
[ -d "$ANDROID_NDK_ROOT" ] || ./scripts/setup # we assume that if the NDK dir does not exist, make setup needs to be run
'';
}
in _stdenv.mkDerivation rec {
name = "env";
env = buildEnv { name = name; paths = buildInputs; };
buildInputs = with _stdenv; [
clojure
curl
jq
leiningen
lsof # used in scripts/start-react-native.sh
maven
ncurses
ps # used in scripts/start-react-native.sh
openjdk
statusDesktop.buildInputs
watchman
unzip
wget
] ++ nodePkgs
++ lib.optional isDarwin cocoapods
++ lib.optional isLinux gcc7;
shellHook = ''
${statusDesktop.shellHook}
local toolversion="$(git rev-parse --show-toplevel)/scripts/toolversion"
export JAVA_HOME="${openjdk}"
export ANDROID_HOME=~/.status/Android/Sdk
export ANDROID_SDK_ROOT="$ANDROID_HOME"
export ANDROID_NDK_ROOT="$ANDROID_SDK_ROOT/android-ndk-$($toolversion android-ndk)"
export ANDROID_NDK_HOME="$ANDROID_NDK_ROOT"
export ANDROID_NDK="$ANDROID_NDK_ROOT"
export PATH="$ANDROID_HOME/bin:$ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$ANDROID_HOME/build-tools:$PATH"
[ -d "$ANDROID_NDK_ROOT" ] || ./scripts/setup # we assume that if the Android NDK dir does not exist, make setup needs to be run
'';
}

View File

@ -11,7 +11,6 @@ cmake_minimum_required(VERSION 2.8.11)
set(APP_NAME Status)
set(JS_APP_NAME StatusIm)
set(REACT_BUILD_STATIC_LIB ON)
project(${APP_NAME} CXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DUNICODE -std=c++11")
if(STATUS_NO_LOGGING)
@ -26,7 +25,9 @@ set(CMAKE_OSX_DEPLOYMENT_TARGET "10.9")
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/CMakeModules/")
set(USED_QT_MODULES Core Qml Quick WebSockets Svg)
project(${APP_NAME} C CXX)
set(USED_QT_MODULES Core Concurrent Qml Quick WebSockets Svg)
include(QtConfiguration)
set(ICON_PNG_RESOURCE_PATH "${CMAKE_SOURCE_DIR}/../deployment/status-icon.png")

View File

@ -13,8 +13,6 @@ plugins_path=""
asset_path="share"
executor=""
react_host=`hostname -I`
# Parse args
for arg in "$@"
do
@ -65,9 +63,12 @@ if [[ $on_device == 1 ]]; then
# adb reverse --no-rebind tcp:8081 tcp:808
# Run app on device
react_host=`hostname -I`
adb shell "cd $app_path && REACT_SERVER_HOST=$react_host ./@APP_NAME@ --host $react_host $args -- --desktop_file_hint=/usr/share/applications/webbrowser-app.desktop"
else
# Run app locally
@CMAKE_BINARY_DIR@/bin/@APP_NAME@ $args
# Note: Needed to add QT_XCB_GL_INTEGRATION=none when migrating to Nix, since running the app in debug mode inside Nix shell was failing at run time with "qt.glx: qglx_findConfig: Failed to finding matching FBConfig (1 1 1 0)\nCould not initialize GLX"
QT_XCB_GL_INTEGRATION=none @CMAKE_BINARY_DIR@/bin/@APP_NAME@ $args
fi

View File

@ -81,7 +81,7 @@
"react-native-image-crop-picker": "0.18.1",
"react-native-image-resizer": "1.0.0",
"react-native-invertible-scroll-view": "1.1.0",
"react-native-keychain": "git+https://github.com/status-im/react-native-keychain.git#v.3.0.0-2-status",
"react-native-keychain": "git+https://github.com/status-im/react-native-keychain.git#v.3.0.0-3-status",
"react-native-languages": "git+https://github.com/status-im/react-native-languages.git#v0.1.1-status",
"react-native-os": "1.1.0",
"react-native-qrcode": "0.2.6",

View File

@ -7071,9 +7071,9 @@ react-native-invertible-scroll-view@1.1.0:
react-clone-referenced-element "^1.0.1"
react-native-scrollable-mixin "^1.0.1"
"react-native-keychain@git+https://github.com/status-im/react-native-keychain.git#v.3.0.0-2-status":
"react-native-keychain@git+https://github.com/status-im/react-native-keychain.git#v.3.0.0-3-status":
version "3.0.0-rc.3"
resolved "git+https://github.com/status-im/react-native-keychain.git#ce6cec62222713f2cec7798b69c4fae6b493832f"
resolved "git+https://github.com/status-im/react-native-keychain.git#25a76813def48ba9bf0fd1b3dd1e915d002b55dd"
"react-native-languages@git+https://github.com/status-im/react-native-languages.git#v0.1.1-status":
version "3.0.2"

View File

@ -42,6 +42,14 @@ set(SnoreNotifyBackendSettings_STATIC_LIB ${SN_PREFIX}/lib${SN_LIBPATHSUFFIX}/${
set(SnoreNotifySettings_STATIC_LIB ${SN_PREFIX}/lib${SN_LIBPATHSUFFIX}/${CMAKE_STATIC_LIBRARY_PREFIX}snoresettings-qt5${CMAKE_STATIC_LIBRARY_SUFFIX})
set(SnoreNotify_CMAKE_ARGS -DCMAKE_INSTALL_PREFIX=${SN_PREFIX} -DSNORE_STATIC=ON -DBUILD_daemon=OFF -DBUILD_settings=OFF
-DBUILD_snoresend=OFF ${SnoreNotify_CMAKE_ARGS})
set(SnoreNotify_CMAKE_ARGS ${SnoreNotify_CMAKE_ARGS}
"-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
"-DCMAKE_C_COMPILER_AR=${CMAKE_C_COMPILER_AR}"
"-DCMAKE_C_COMPILER_RANLIB=${CMAKE_C_COMPILER_RANLIB}"
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DCMAKE_CXX_COMPILER_AR=${CMAKE_CXX_COMPILER_AR}"
"-DCMAKE_CXX_COMPILER_RANLIB=${CMAKE_CXX_COMPILER_RANLIB}"
"-DCMAKE_LINKER=${CMAKE_LINKER}")
if (CMAKE_CROSSCOMPILING)
set(SnoreNotify_CMAKE_ARGS ${SnoreNotify_CMAKE_ARGS}
"-DCMAKE_C_FLAGS=${CMAKE_C_FLAGS}"
@ -53,13 +61,6 @@ if (CMAKE_CROSSCOMPILING)
"-DCMAKE_SYSTEM_NAME=${CMAKE_SYSTEM_NAME}"
"-DCMAKE_SYSTEM_PROCESSOR=${CMAKE_SYSTEM_PROCESSOR}"
"-DCMAKE_AR=${CMAKE_AR}"
"-DCMAKE_C_COMPILER=${CMAKE_C_COMPILER}"
"-DCMAKE_C_COMPILER_AR=${CMAKE_C_COMPILER_AR}"
"-DCMAKE_C_COMPILER_RANLIB=${CMAKE_C_COMPILER_RANLIB}"
"-DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER}"
"-DCMAKE_CXX_COMPILER_AR=${CMAKE_CXX_COMPILER_AR}"
"-DCMAKE_CXX_COMPILER_RANLIB=${CMAKE_CXX_COMPILER_RANLIB}"
"-DCMAKE_LINKER=${CMAKE_LINKER}"
"-DCMAKE_RC_COMPILER=${CMAKE_RC_COMPILER}"
"-DCMAKE_EXE_LINKER_FLAGS=${CMAKE_EXE_LINKER_FLAGS}"
"-DCMAKE_COMPILER_PREFIX=${CMAKE_COMPILER_PREFIX}"

View File

@ -7,11 +7,11 @@ if [ "$1" = 'Windows' ]; then
export GOOS=windows
export GOARCH=amd64
export CGO_ENABLED=1
export CC=$5
export CC_FOR_TARGET=$5
export CXX_FOR_TARGET=$6
fi
export CC=$5
export CC_FOR_TARGET=$5
export CXX_FOR_TARGET=$6
cd $4/lib
go get ./
cd ..

View File

@ -15,12 +15,6 @@ if [ -z $TARGET_SYSTEM_NAME ]; then
fi
WINDOWS_CROSSTOOLCHAIN_PKG_NAME='mxetoolchain-x86_64-w64-mingw32'
if [ -z $STATUS_NO_LOGGING ]; then
COMPILE_FLAGS="-DCMAKE_CXX_FLAGS:='-DBUILD_FOR_BUNDLE=1'"
else
COMPILE_FLAGS="-DCMAKE_CXX_FLAGS:=-DBUILD_FOR_BUNDLE=1 -DSTATUS_NO_LOGGING=1"
fi
external_modules_dir=( \
'node_modules/react-native-languages/desktop' \
'node_modules/react-native-config/desktop' \
@ -76,20 +70,21 @@ function joinExistingPath() {
fi
}
function join { local IFS="$1"; shift; echo "$*"; }
CMAKE_EXTRA_FLAGS=$'-DCMAKE_CXX_FLAGS:=\'-DBUILD_FOR_BUNDLE=1\''
[ -n $STATUS_NO_LOGGING ] && CMAKE_EXTRA_FLAGS="$CMAKE_EXTRA_FLAGS -DSTATUS_NO_LOGGING=1"
if is_windows_target; then
CMAKE_EXTRA_FLAGS="$CMAKE_EXTRA_FLAGS -DCMAKE_TOOLCHAIN_FILE='Toolchain-Ubuntu-mingw64.cmake'"
CMAKE_EXTRA_FLAGS="$CMAKE_EXTRA_FLAGS -DCMAKE_C_COMPILER='x86_64-w64-mingw32.shared-gcc'"
CMAKE_EXTRA_FLAGS="$CMAKE_EXTRA_FLAGS -DCMAKE_CXX_COMPILER='x86_64-w64-mingw32.shared-g++'"
CMAKE_EXTRA_FLAGS="$CMAKE_EXTRA_FLAGS -DCMAKE_RC_COMPILER='x86_64-w64-mingw32.shared-windres'"
fi
STATUSREACTPATH="$(cd "$SCRIPTPATH" && cd '..' && pwd)"
WORKFOLDER="$(joinExistingPath "$STATUSREACTPATH" 'StatusImPackage')"
DEPLOYQTFNAME='linuxdeployqt-continuous-x86_64_20181215.AppImage'
APPIMAGETOOLFNAME='appimagetool-x86_64_20190221.AppImage'
DEPLOYQT=$(joinPath . "$DEPLOYQTFNAME")
APPIMAGETOOL=$(joinPath . "$APPIMAGETOOLFNAME")
STATUSIM_APPIMAGE_ARCHIVE="StatusImAppImage_20181208.zip"
APPIMAGE_OPTIONS=""
if [[ ! -c /dev/fuse ]]; then # doesn't exist when run under docker
# We extract it to avoid having to use fuse and privileged mode in docker
APPIMAGE_OPTIONS="--appimage-extract-and-run"
fi
function init() {
if [ -z $STATUSREACTPATH ]; then
echo "${RED}STATUSREACTPATH environment variable is not defined!${NC}"
@ -103,36 +98,14 @@ function init() {
fi
fi
if is_macos; then
if [ -z $MACDEPLOYQT ]; then
set +e
MACDEPLOYQT=$(which macdeployqt)
if [ -z $MACDEPLOYQT ]; then
echo "${RED}MACDEPLOYQT environment variable is not defined and macdeployqt executable not found in path!${NC}"
exit 1
fi
set -e
fi
DEPLOYQT="$MACDEPLOYQT"
elif is_linux; then
if is_linux; then
rm -rf ./desktop/toolchain/
# TODO: Use Conan for Linux and MacOS builds too
if is_windows_target; then
if ! program_exists 'python3'; then
echo "${RED}python3 prerequisite is missing. Exiting.${NC}"
exit 1
fi
export PATH=$STATUSREACTPATH:$PATH
if ! program_exists 'conan'; then
if ! program_exists 'pip3'; then
echo "${RED}pip3 package manager not found. Exiting.${NC}"
exit 1
fi
echo "${RED}Conan package manager not found. Installing...${NC}"
pip3 install conan==$(toolversion conan)
echo "${RED}Conan package manager not found. Exiting...${NC}"
exit 1
fi
conan remote add --insert 0 -f status-im https://conan.status.im
@ -197,24 +170,13 @@ function compile() {
fi
export PATH=$bin_dir:$PATH
done <<< "$bin_dirs"
cmake -Wno-dev \
-DCMAKE_TOOLCHAIN_FILE='Toolchain-Ubuntu-mingw64.cmake' \
-DCMAKE_C_COMPILER='x86_64-w64-mingw32.shared-gcc' \
-DCMAKE_CXX_COMPILER='x86_64-w64-mingw32.shared-g++' \
-DCMAKE_RC_COMPILER='x86_64-w64-mingw32.shared-windres' \
-DCMAKE_BUILD_TYPE=Release \
-DEXTERNAL_MODULES_DIR="$EXTERNAL_MODULES_DIR" \
-DDESKTOP_FONTS="$DESKTOP_FONTS" \
-DJS_BUNDLE_PATH="$JS_BUNDLE_PATH" \
$COMPILE_FLAGS || exit 1
else
cmake -Wno-dev \
-DCMAKE_BUILD_TYPE=Release \
-DEXTERNAL_MODULES_DIR="$EXTERNAL_MODULES_DIR" \
-DDESKTOP_FONTS="$DESKTOP_FONTS" \
-DJS_BUNDLE_PATH="$JS_BUNDLE_PATH" \
$COMPILE_FLAGS || exit 1
fi
cmake -Wno-dev \
-DCMAKE_BUILD_TYPE=Release \
-DEXTERNAL_MODULES_DIR="$EXTERNAL_MODULES_DIR" \
-DDESKTOP_FONTS="$DESKTOP_FONTS" \
-DJS_BUNDLE_PATH="$JS_BUNDLE_PATH" \
$CMAKE_EXTRA_FLAGS || exit 1
make -S -j5 || exit 1
popd
}
@ -268,6 +230,42 @@ function bundleWindows() {
./deployment/windows/nsis/setup.nsi
}
if is_linux; then
#
# getRecursiveDependencies will use ldd to go through the dependencies of a library,
# and output those which are ELF binaries
#
declare -A treated_libs=()
declare -A treated_package_dirs=()
function getRecursiveDependencies() {
local args=("$@")
local root_lib=(${args[0]})
treated_libs["$root_lib"]=1
if program_exists 'realpath'; then
root_lib=$(realpath -m "$root_lib" 2> /dev/null)
fi
echo $root_lib
[ -x $root_lib ] || return
local nix_package_dep_libs=($(ldd $root_lib | grep '=>' | awk -F'=>' -F ' ' "/^.*/{print \$3}"))
[ ${#nix_package_dep_libs[@]} -eq 0 ] && return
local nix_package_dep_libs_dirs=$(echo ${nix_package_dep_libs[@]} | xargs dirname | xargs realpath | sort -u | uniq | grep "^/nix")
for packageLibDir in $nix_package_dep_libs_dirs; do
if ! [ ${treated_package_dirs[$packageLibDir]} ]; then
treated_package_dirs["$packageLibDir"]=1
for lib in $(ls $packageLibDir/*.so* | xargs realpath | sort | uniq); do
local type=$(file $lib | awk -F':' "/^.*/{print \$2}" | awk -F' ' "/^.*/{print \$1}")
if [ $type == 'ELF' ]; then
[ ${treated_libs[$lib]} ] || getRecursiveDependencies "$lib"
fi
done
fi
done
}
fi
function bundleLinux() {
local QTBIN=$(joinExistingPath "$QT_PATH" 'gcc_64/bin')
if [ ! -d "$QTBIN" ]; then
@ -292,24 +290,14 @@ function bundleLinux() {
popd
qmakePath="$(joinExistingPath "${QTBIN}" 'qmake')"
usrBinPath=$(joinPath "$WORKFOLDER" "AppDir/usr/bin")
usrBinPath="$(joinPath "$WORKFOLDER" "AppDir/usr/bin")"
cp -r ./deployment/linux/usr $WORKFOLDER/AppDir
cp ./.env $usrBinPath
cp ./desktop/bin/Status ./desktop/bin/reportApp $usrBinPath
if [ ! -f $DEPLOYQT ]; then
wget --output-document="$DEPLOYQT" --show-progress "https://desktop-app-files.ams3.digitaloceanspaces.com/$DEPLOYQTFNAME" # Versioned from https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage
chmod a+x $DEPLOYQT
fi
if [ ! -f $APPIMAGETOOL ]; then
wget --output-document="$APPIMAGETOOL" --show-progress "https://desktop-app-files.ams3.digitaloceanspaces.com/$APPIMAGETOOLFNAME" # Versioned from https://github.com/AppImage/AppImageKit/releases/download/10/appimagetool-x86_64.AppImage
chmod a+x $APPIMAGETOOL
fi
rm -f Application-x86_64.AppImage Status-x86_64.AppImage
[ $VERBOSE_LEVEL -ge 1 ] && ldd $(joinExistingPath "$usrBinPath" 'Status')
[ $VERBOSE_LEVEL -ge 1 ] && ldd $(joinExistingPath "$usrBinPath" 'Status')
desktopFilePath="$(joinExistingPath "$WORKFOLDER" 'AppDir/usr/share/applications/Status.desktop')"
pushd $WORKFOLDER
cp -r assets/share/assets $usrBinPath
@ -317,7 +305,17 @@ function bundleLinux() {
rm -f $usrBinPath/Status.AppImage
popd
$DEPLOYQT $APPIMAGE_OPTIONS \
# Tell linuxdeployqt about all the different lib folders in Nix's store
local all_deps=($(getRecursiveDependencies "$usrBinPath/Status"))
local unique_folders=($(echo "${all_deps[@]}" | xargs dirname | sort -u -r | uniq | grep "/nix"))
if [ ${#unique_folders[@]} -gt 0 ]; then
# Ensure the binary isn't using the interpreter in Nix's store
patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 "$usrBinPath/Status"
fi
LD_LIBRARY_PATH="$(join : ${unique_folders[@]})" \
linuxdeployqt \
$desktopFilePath \
-verbose=$VERBOSE_LEVEL -always-overwrite -no-strip \
-no-translations -bundle-non-qt-libs \
@ -330,7 +328,11 @@ function bundleLinux() {
pushd $WORKFOLDER
rm -f $usrBinPath/Status.AppImage
$APPIMAGETOOL $APPIMAGE_OPTIONS ./AppDir
appimagetool ./AppDir
if [ ${#unique_folders[@]} -gt 0 ]; then
# Ensure the AppImage isn't using the interpreter in Nix's store
patchelf --set-interpreter /lib64/ld-linux-x86-64.so.2 ./Status-x86_64.AppImage
fi
[ $VERBOSE_LEVEL -ge 1 ] && ldd $usrBinPath/Status
rm -rf Status.AppImage
popd
@ -339,36 +341,191 @@ function bundleLinux() {
echo ""
}
function bundleMacOS() {
# download prepared package with mac bundle files (it contains qt libraries, icon)
echo "Downloading skeleton of mac bundle..."
if is_macos; then
function getQtFullOutPathFromNixStore() {
local qtFullDerivationPath=$(nix show-derivation -f $STATUSREACTPATH/default.nix | jq -r '.[] | .inputDrvs | 'keys' | .[]' | grep qt-full)
echo $(nix show-derivation $qtFullDerivationPath | jq -r '.[] | .outputs.out.path')
}
function getQtBaseBinPathFromNixStore() {
local qtFullDerivationPath=$(nix show-derivation -f $STATUSREACTPATH/default.nix | jq -r '.[] | .inputDrvs | 'keys' | .[]' | grep qt-full)
local qtBaseDerivationPath=$(nix show-derivation $qtFullDerivationPath | jq -r '.[] | .inputDrvs | 'keys' | .[]' | grep qtbase)
echo $(nix show-derivation $qtBaseDerivationPath | jq -r '.[] | .outputs.bin.path')
}
function copyDylibNixDependenciesToPackage() {
local dylib="$1"
local contentsDir="$2"
local frameworksDir="$contentsDir/Frameworks"
local exeDir="$contentsDir/MacOS"
# Walk through the dependencies of $dylib
local dependencies=$(otool -L "$dylib" | grep -E "\s+/nix/" | awk -F "(" '{print $1}' | xargs)
local moduleDirPath=$(basename $dylib)
for depDylib in $dependencies; do
local targetDepDylib=$(joinPath "$frameworksDir" "$(basename $depDylib)")
# Copy any dependencies that: are not in the Frameworks directory, do not already exist in /usr/lib and are not a Qt5 module (will be handled by macdeployqt anyway)
if [ ! -f "$targetDepDylib" ] && [[ "$(basename $targetDepDylib)" != "libQt5"* ]] && [ ! -f "/usr/lib/$(basename $depDylib)" ]; then
[ $VERBOSE_LEVEL -ge 1 ] && echo " Copying $depDylib to $frameworksDir..."
cp -a -L "$depDylib" "$frameworksDir"
chmod 0755 "$targetDepDylib"
copyDylibNixDependenciesToPackage "$depDylib" "$contentsDir"
fi
done
}
function copyQtPlugInToPackage() {
local qtPath="$1"
local pluginName="$2"
local contentsPath="$3"
local filter=""
local targetPath="$contentsPath/PlugIns"
local pluginTargetPath="$targetPath/$pluginName"
[ "$pluginName" == 'platforms' ] && filter='libqcocoa.dylib'
mkdir -p $pluginTargetPath
local qtLibPath=$(find $qtPath/lib -maxdepth 1 -name qt-*)
local srcPath=$(readlink -f "$qtLibPath/plugins/$pluginName")
echo "Copying $srcPath to $targetPath"
if [ -z "$filter" ]; then
cp -a -f -L "$srcPath" "$targetPath"
else
cp -f $(readlink -f "$srcPath/$filter") "$pluginTargetPath"
fi
chmod 755 $pluginTargetPath
chmod 755 $pluginTargetPath/*
for dylib in `find $pluginTargetPath -name *.dylib`; do
copyDylibNixDependenciesToPackage "$dylib" "$contentsPath"
done
}
function fixupRPathsInDylib() {
local dylib="$1"
local contentsDir="$2"
local frameworksDir="$contentsDir/Frameworks"
local exeDir="$contentsDir/MacOS"
[ $VERBOSE_LEVEL -ge 1 ] && echo "Checking rpaths in ${dylib}"
# Walk through the dependencies of $dylib
local dependencies=$(otool -L "$dylib" | grep -E "\s+/nix/" | sed "s|@executable_path|$exeDir|" | awk -F "(" '{print $1}' | xargs)
local moduleDirPath=$(dirname $dylib)
for depDylib in $dependencies; do
# Fix rpath and copy library to target
local replacementTargetPath=""
local framework=$(echo $depDylib | sed -E "s|^\/nix\/.+\/Library\/Frameworks\/(.+)\.framework\/\1$|\1|" 2> /dev/null)
if [ -n "$framework" ] && [ "$framework" != "$depDylib" ]; then
# Handle macOS framework
local targetDepDylib=$(joinExistingPath "/System/Library/Frameworks" "${framework}.framework/${framework}")
if [ ! -f "$targetDepDylib" ]; then
echo -e "${RED}FATAL: system framework not found: ${targetDepDylib}${NC}"
exit 1
fi
# Change dependency rpath in $dylib to point to $targetDepDylib
replacementTargetPath=$targetDepDylib
else
# Handle other libraries
local targetDepDylib=$(joinPath "$frameworksDir" "$(basename $depDylib)")
if [ ! -f "$targetDepDylib" ]; then
echo -e "${RED}FATAL: macdeployqt should have copied the dependency to ${targetDepDylib}${NC}"
exit 1
fi
# Change dependency rpath in $dylib to point to $replacementTargetPath
local replacementPath=""
local targetDepModuleDirPath=$(dirname $targetDepDylib)
if [[ $targetDepModuleDirPath -ef $moduleDirPath ]]; then
replacementPath="@loader_path"
else
replacementPath="@executable_path/$(realpath --relative-to="$exeDir" "$targetDepModuleDirPath")"
fi
local modulePathRegExp="($(pwd)/)?$moduleDirPath"
replacementTargetPath=$(echo $targetDepDylib | sed -E "s|$modulePathRegExp|$replacementPath|")
fi
if [ -n "$replacementTargetPath" ]; then
[ $VERBOSE_LEVEL -ge 1 ] && echo "Updating $dylib to point to $replacementTargetPath"
install_name_tool -change "$depDylib" "$replacementTargetPath" "$dylib"
fi
done
}
function fixupRemainingRPaths() {
local searchRootPath="$1"
local contentsDir="$2"
for dylib in `find $searchRootPath -name *.dylib`; do
fixupRPathsInDylib "$dylib" "$contentsDir"
# Sanity check for absolute paths
local dependencies=$(otool -L "$dylib" | grep -E "\s+${STATUSREACTPATH}")
if [ -n "$dependencies" ]; then
echo "Absolute path detected in dependencies of $dylib. Aborting..."
echo "${dependencies[@]}"
exit 1
fi
done
}
fi
function bundleMacOS() {
pushd $WORKFOLDER
# download prepared package with mac bundle files (it contains qt libraries, icon)
echo "Downloading skeleton of mac bundle..."
rm -rf Status.app
# TODO this needs to be fixed: status-react/issues/5378
[ -f ./Status.app.zip ] || curl -L -o Status.app.zip https://desktop-app-files.ams3.digitaloceanspaces.com/Status_20181113.app.zip
echo -e "${GREEN}Downloading done.${NC}"
echo ""
unzip ./Status.app.zip
cp -r assets/share/assets Status.app/Contents/Resources
ln -sf ../Resources/assets ../Resources/ubuntu-server ../Resources/node_modules Status.app/Contents/MacOS
chmod +x Status.app/Contents/Resources/ubuntu-server
cp ../desktop/bin/Status Status.app/Contents/MacOS/Status
cp ../desktop/bin/reportApp Status.app/Contents/MacOS
cp ../.env Status.app/Contents/Resources
ln -sf ../Resources/.env Status.app/Contents/MacOS/.env
cp -f ../deployment/macos/qt-reportApp.conf Status.app/Contents/Resources
ln -sf ../Resources/qt-reportApp.conf Status.app/Contents/MacOS/qt.conf
install_name_tool -add_rpath "@executable_path/../Frameworks" \
-delete_rpath "${QT_PATH}/lib" \
'Status.app/Contents/MacOS/reportApp'
install_name_tool -add_rpath "@executable_path/../Frameworks" \
-delete_rpath "${QT_PATH}/lib" \
'Status.app/Contents/MacOS/Status'
cp -f ../deployment/macos/Info.plist Status.app/Contents
cp -f ../deployment/macos/status-icon.icns Status.app/Contents/Resources
$DEPLOYQT Status.app -verbose=$VERBOSE_LEVEL \
-qmldir="$STATUSREACTPATH/node_modules/react-native/ReactQt/runtime/src/qml/"
local contentsPath='Status.app/Contents'
local usrBinPath=$(joinExistingPath "$WORKFOLDER" "$contentsPath/MacOS")
cp -r assets/share/assets $contentsPath/Resources
ln -sf ../Resources/assets ../Resources/ubuntu-server ../Resources/node_modules $usrBinPath
chmod +x $contentsPath/Resources/ubuntu-server
cp ../desktop/bin/Status $usrBinPath/Status
cp ../desktop/bin/reportApp $usrBinPath
cp ../.env $contentsPath/Resources
ln -sf ../Resources/.env $usrBinPath/.env
cp -f ../deployment/macos/qt-reportApp.conf $contentsPath/Resources
ln -sf ../Resources/qt-reportApp.conf $usrBinPath/qt.conf
cp -f ../deployment/macos/Info.plist $contentsPath
cp -f ../deployment/macos/status-icon.icns $contentsPath/Resources
local qtbaseplugins=(bearer platforms printsupport styles)
local qtfullplugins=(iconengines imageformats webview)
if program_exists nix && [ -n "$IN_NIX_SHELL" ]; then
# Since in the Nix qt.full package the different Qt modules are spread across several directories,
# macdeployqt cannot find some qtbase plugins, so we copy them in its place
local qtbaseBinPath=$(getQtBaseBinPathFromNixStore)
local qtfullOutPath=$(getQtFullOutPathFromNixStore)
mkdir -p "$contentsPath/PlugIns"
for plugin in ${qtbaseplugins[@]}; do copyQtPlugInToPackage "$qtbaseBinPath" "$plugin" "$contentsPath"; done
for plugin in ${qtfullplugins[@]}; do copyQtPlugInToPackage "$qtfullOutPath" "$plugin" "$contentsPath"; done
fi
macdeployqt Status.app \
-verbose=$VERBOSE_LEVEL \
-executable="$(joinExistingPath "$usrBinPath" 'reportApp')" \
-qmldir="$(joinExistingPath "$STATUSREACTPATH" 'node_modules/react-native')" \
-qmldir="$(joinExistingPath "$STATUSREACTPATH" 'desktop/reportApp')"
# macdeployqt doesn't fix rpaths for all the libraries (although it copies them all), so we'll just walk through them and update rpaths to not point to /nix
echo "Fixing remaining rpaths in modules..."
fixupRemainingRPaths "$contentsPath/Frameworks" "$contentsPath"
fixupRemainingRPaths "$contentsPath/PlugIns" "$contentsPath"
echo "Done fixing rpaths in modules"
rm -f Status.app.zip
popd

View File

@ -38,17 +38,6 @@ function install_nix() {
fi
}
function install_nsis() {
! is_linux && return 0
# NSIS (Nullsoft Scriptable Install System) is a professional open source system to create Windows installers. It is designed to be as small and flexible as possible and is therefore very suitable for internet distribution.
if program_exists "apt"; then
apt_install "nsis"
else
echo "nsis is not supported in this Linux distro. Generating Windows setup executables will not be possible"
fi
}
function install_android_sdk() {
if [ -d "$ANDROID_SDK_ROOT" ]; then
cecho "@green[[Android SDK already installed.]]"

View File

@ -0,0 +1,117 @@
{ stdenv, fetchFromGitHub
, pkgconfig, cmake, autoconf, automake, libtool
, wget, xxd, desktop-file-utils, file
, glib, zlib, cairo, openssl, fuse, xz, squashfuse, inotify-tools, libarchive
, squashfsTools
, gtest
}:
let
appimagekit_src = fetchFromGitHub {
owner = "AppImage";
repo = "AppImageKit";
rev = "b0859501df61cde198b54a317c03b41dbafc98b1";
sha256 = "0qqg79jw9w9rs8c2w3lla4kz62ihafrf7jm370pp1dl8y2i81jzg";
};
# squashfuse adapted to nix from cmake experession in "${appimagekit_src}/cmake/dependencies.cmake"
appimagekit_squashfuse = squashfuse.overrideAttrs (attrs: rec {
name = "squashfuse-${version}";
version = "20161009";
src = fetchFromGitHub {
owner = "vasi";
repo = "squashfuse";
rev = "1f980303b89c779eabfd0a0fdd36d6a7a311bf92";
sha256 = "0lrw9ff8k15l34wjwyllw3i35hl0cms97jj2hpnr2q8ipgxpb5q5";
};
patches = [
"${appimagekit_src}/squashfuse.patch"
"${appimagekit_src}/squashfuse_dlopen.patch"
];
postPatch = ''
cp -v ${appimagekit_src}/squashfuse_dlopen.[hc] .
'';
preConfigure = ''
sed -i "/PKG_CHECK_MODULES.*/,/,:./d" configure
sed -i "s/typedef off_t sqfs_off_t/typedef int64_t sqfs_off_t/g" common.h
'';
configureFlags = [
"--disable-demo" "--disable-high-level" "--without-lzo" "--without-lz4"
];
postConfigure = ''
sed -i "s|XZ_LIBS = -llzma |XZ_LIBS = -Bstatic -llzma/|g" Makefile
'';
# only static libs and header files
installPhase = ''
mkdir -p $out/lib $out/include
cp -v ./.libs/*.a $out/lib
cp -v ./*.h $out/include
'';
});
in stdenv.mkDerivation rec {
name = "appimagekit-20180727";
src = appimagekit_src;
patches = [ ./nix.patch ];
nativeBuildInputs = [
pkgconfig cmake autoconf automake libtool wget xxd
desktop-file-utils
];
buildInputs = [
glib zlib cairo openssl fuse
xz inotify-tools libarchive
squashfsTools
];
preConfigure = ''
export HOME=$(pwd)
'';
cmakeFlags = [
"-DUSE_SYSTEM_XZ=ON"
"-DUSE_SYSTEM_SQUASHFUSE=ON"
"-DSQUASHFUSE=${appimagekit_squashfuse}"
"-DUSE_SYSTEM_INOTIFY_TOOLS=ON"
"-DUSE_SYSTEM_LIBARCHIVE=ON"
"-DUSE_SYSTEM_GTEST=ON"
"-DUSE_SYSTEM_MKSQUASHFS=ON"
"-DBUILD_TESTING=${if doCheck then "ON" else "OFF"}"
];
postInstall = ''
cp "${stdenv.lib.makeBinPath [ squashfsTools ]}/mksquashfs" "$out/lib/appimagekit/"
cp "${stdenv.lib.makeBinPath [ desktop-file-utils ]}/desktop-file-validate" "$out/bin"
'';
checkInputs = [ gtest ];
doCheck = false; # fails 1 out of 4 tests, I'm too lazy to debug why
# for debugging
passthru = {
squashfuse = appimagekit_squashfuse;
};
meta = with stdenv.lib; {
description = "A tool to package desktop applications as AppImages";
longDescription = ''
AppImageKit is an implementation of the AppImage format that
provides tools such as appimagetool and appimaged for handling
AppImages.
'';
license = licenses.mit;
homepage = src.meta.homepage;
platforms = platforms.linux;
};
}

View File

@ -0,0 +1,197 @@
diff --git a/cmake/dependencies.cmake b/cmake/dependencies.cmake
index ea133a3..916606c 100644
--- a/cmake/dependencies.cmake
+++ b/cmake/dependencies.cmake
@@ -224,21 +224,23 @@ if(NOT USE_SYSTEM_XZ)
LIBRARY_DIRS <INSTALL_DIR>/lib/
LIBRARIES "<INSTALL_DIR>/lib/liblzma.a"
INCLUDE_DIRS "<SOURCE_DIR>/src/liblzma/api/"
)
else()
message(STATUS "Using system xz")
import_pkgconfig_target(TARGET_NAME xz PKGCONFIG_TARGET liblzma STATIC)
endif()
+set(USE_SYSTEM_SQUASHFUSE OFF CACHE BOOL "Use system squashfuse instead of building our own")
+if(NOT USE_SYSTEM_SQUASHFUSE)
# as distros don't provide suitable squashfuse and squashfs-tools, those dependencies are bundled in, can, and should
# be used from this repository
# TODO: implement out-of-source builds for squashfuse, as for the other dependencies
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/src/patch-squashfuse.sh.in
${CMAKE_CURRENT_BINARY_DIR}/patch-squashfuse.sh
@ONLY
)
ExternalProject_Add(squashfuse-EXTERNAL
@@ -259,20 +261,34 @@ ExternalProject_Add(squashfuse-EXTERNAL
BUILD_IN_SOURCE ON
INSTALL_COMMAND ${MAKE} install
)
import_external_project(
TARGET_NAME squashfuse
EXT_PROJECT_NAME squashfuse-EXTERNAL
LIBRARIES "<SOURCE_DIR>/.libs/libsquashfuse.a;<SOURCE_DIR>/.libs/libsquashfuse_ll.a;<SOURCE_DIR>/.libs/libfuseprivate.a"
INCLUDE_DIRS "<SOURCE_DIR>"
)
+else()
+ message(STATUS "Using system squashfsfuse from ${SQUASHFUSE}")
+
+ add_library(squashfuse INTERFACE IMPORTED GLOBAL)
+
+ set(squashfuse_INCLUDE_DIRS "${SQUASHFUSE}/include")
+ set(squashfuse_LIBRARIES "${SQUASHFUSE}/lib/libsquashfuse.a;${SQUASHFUSE}/lib/libsquashfuse_ll.a;${SQUASHFUSE}/lib/libfuseprivate.a")
+
+ set_property(
+ TARGET squashfuse
+ PROPERTY INTERFACE_LINK_LIBRARIES ${squashfuse_LIBRARIES}
+ )
+ include_directories(${squashfuse_INCLUDE_DIRS})
+endif()
set(USE_SYSTEM_INOTIFY_TOOLS OFF CACHE BOOL "Use system libinotifytools instead of building our own")
if(NOT USE_SYSTEM_INOTIFY_TOOLS)
message(STATUS "Downloading and building inotify-tools")
# TODO: build out of source
ExternalProject_Add(inotify-tools-EXTERNAL
URL https://github.com/downloads/rvoicilas/inotify-tools/inotify-tools-3.14.tar.gz
@@ -345,20 +361,23 @@ if(NOT USE_SYSTEM_GTEST)
INCLUDE_DIRS "<INSTALL_DIR>/include/"
)
else()
message(STATUS "Using system GTest")
import_find_pkg_target(gtest GTest GTEST)
endif()
endif()
+set(USE_SYSTEM_MKSQUASHFS OFF CACHE BOOL "Use system mksquashfs instead of downloading and building our own")
+
+if(NOT USE_SYSTEM_MKSQUASHFS)
# TODO: allow using system wide mksquashfs
set(mksquashfs_cflags "-DXZ_SUPPORT ${CFLAGS}")
if(xz_LIBRARIES MATCHES "\\.a$")
set(mksquashfs_ldflags "${xz_LIBRARIES}")
else()
set(mksquashfs_ldflags "-l${xz_LIBRARIES}")
endif()
if(xz_INCLUDE_DIRS)
@@ -385,20 +404,25 @@ ExternalProject_Add(mksquashfs
INSTALL_COMMAND ${MAKE} -C squashfs-tools/ install INSTALL_DIR=<INSTALL_DIR>
)
ExternalProject_Get_Property(mksquashfs INSTALL_DIR)
set(mksquashfs_INSTALL_DIR "${INSTALL_DIR}")
mark_as_advanced(mksquashfs_INSTALL_DIR)
# for later use when packaging as an AppImage
set(mksquashfs_BINARY "${mksquashfs_INSTALL_DIR}/mksquashfs")
mark_as_advanced(mksquashfs_BINARY)
+else()
+ message(STATUS "Using system mksquashfs")
+
+ set(mksquashfs_BINARY "mksquashfs")
+endif()
#### build dependency configuration ####
# only have to build custom xz when not using system libxz
if(TARGET xz-EXTERNAL)
if(TARGET squashfuse-EXTERNAL)
ExternalProject_Add_StepDependencies(squashfuse-EXTERNAL configure xz-EXTERNAL)
endif()
if(TARGET mksquashfs)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 3f25442..974ed0e 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -197,27 +197,27 @@ target_include_directories(digest_md5
target_link_libraries(digest_md5
PRIVATE
libglib
)
# install binaries
if(AUXILIARY_FILES_DESTINATION)
install(
- PROGRAMS ${mksquashfs_INSTALL_DIR}/mksquashfs ${CMAKE_CURRENT_BINARY_DIR}/runtime
+ PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/runtime
DESTINATION ${AUXILIARY_FILES_DESTINATION}
COMPONENT applications
)
else()
install(
- PROGRAMS ${mksquashfs_INSTALL_DIR}/mksquashfs ${CMAKE_CURRENT_BINARY_DIR}/runtime
+ PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/runtime
DESTINATION bin
COMPONENT applications
)
endif()
install(
TARGETS AppRun appimagetool digest validate
RUNTIME DESTINATION bin COMPONENT applications
LIBRARY DESTINATION lib COMPONENT applications
ARCHIVE DESTINATION lib/static COMPONENT applications
diff --git a/src/shared.c b/src/shared.c
index cf5fd5c..4f48dbc 100644
--- a/src/shared.c
+++ b/src/shared.c
@@ -34,21 +34,21 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <dirent.h>
#include <errno.h>
#include <glib.h>
#include <glib/gprintf.h>
#include <glib/gstdio.h>
#include <gio/gio.h>
-#include "squashfuse.h"
+#include <squashfuse.h>
#include <squashfs_fs.h>
#include "getsection.h"
#include "elf.h"
#include "xdg-basedir.h"
// own header
#include "shared.h"
#if HAVE_LIBARCHIVE3 == 1 // CentOS
diff --git a/src/appimagetool.c b/src/appimagetool.c
index 69beaa1..c55d6b1 100644
--- a/src/appimagetool.c
+++ b/src/appimagetool.c
@@ -200,9 +200,6 @@ int sfs_mksquashfs(char *source, char *destination, int offset) {
args[i++] = exclude_file;
}
- args[i++] = "-mkfs-fixed-time";
- args[i++] = "0";
-
args[i++] = 0;
if (verbose) {
@@ -348,7 +345,7 @@ void extract_arch_from_text(gchar *archname, const gchar* sourcename, bool* arch
void guess_arch_of_file(const gchar *archfile, bool* archs) {
char line[PATH_MAX];
char command[PATH_MAX];
- sprintf(command, "/usr/bin/file -L -N -b %s", archfile);
+ sprintf(command, "file -L -N -b %s", archfile);
FILE* fp = popen(command, "r");
if (fp == NULL)
die("Failed to run file command");

View File

@ -0,0 +1,26 @@
{ stdenv, pkgs }:
with pkgs;
with stdenv;
let
windowsPlatform = callPackage ./windows { };
appimagekit = callPackage ./appimagekit { };
linuxdeployqt = callPackage ./linuxdeployqt { inherit appimagekit; };
in
{
buildInputs = [
cmake
extra-cmake-modules
file
gnupg # Used by appimagetool
go
qt5.full
] ++ lib.optional isLinux [ appimagekit linuxdeployqt patchelf ]
++ lib.optional isLinux windowsPlatform.buildInputs;
shellHook = ''
export QT_PATH="${qt5.full}"
export PATH="${stdenv.lib.makeBinPath [ qt5.full ]}:$PATH"
'';
}

View File

@ -0,0 +1,43 @@
{ pkgs, stdenv, fetchFromGitHub, appimagekit }:
with pkgs;
stdenv.mkDerivation rec {
name = "linuxdeployqt";
version = "20181215";
src =
if stdenv.hostPlatform.system == "x86_64-linux" then
fetchFromGitHub {
owner = "probonopd";
repo = "linuxdeployqt";
rev = "600fc20ea73ee937a402a2bb6b3663d93fcc1d4b";
sha256 = "05kvkfbhsyadlcggl63rhrw5s36d8qxs8gyihrjn2cjk42xx8r7j";
}
else throw "${name} is not supported on ${stdenv.hostPlatform.system}";
buildInputs = [ qt5.qtbase appimagekit ];
nativeBuildInputs = [ wget ];
buildPhase = ''
qmake
make
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
cp -r bin/linuxdeployqt $out/bin/
runHook postInstall
'';
meta = {
description = "Makes Linux applications self-contained by copying in the libraries and plugins that the application uses, and optionally generates an AppImage. Can be used for Qt and other applications";
homepage = https://github.com/probonopd/linuxdeployqt/;
license = stdenv.lib.licenses.gpl3;
maintainers = [ stdenv.lib.maintainers.pombeirp ];
platforms = stdenv.lib.platforms.linux;
};
}

View File

@ -0,0 +1,8 @@
{ stdenv, pkgs }:
with pkgs;
with stdenv;
{
buildInputs = lib.optional isLinux [ conan nsis ];
}

View File

@ -29,79 +29,3 @@ function program_version_exists() {
function toolversion() {
${GIT_ROOT}/scripts/toolversion "${1}"
}
###############
# Linux
###############
# FIXME This command assumes that package names in different package managers (apt, pacman) are same.
# At this moment, it works as expected because we only call it for installing maven and nodejs.
# If this list grows, please consider adding some sort of mapping mechanism.
function linux_install() {
! is_linux && return 0
if program_exists "apt"; then
apt_install "$@"
elif program_exists "pacman"; then
pacman_install "$@"
else
echo "Unsupported Linux distro."
exit 1;
fi
}
###############
# Aptitude
###############
function apt_update() {
sudo apt update
}
function apt_is_installed() {
local package=$1
dpkg -s "$package" >/dev/null 2>&1
}
function apt_install() {
local package=$1
if apt_is_installed "$package"; then
cecho "+ $package already installed... skipping."
else
sudo apt install -y "$package" || exit 1
fi
}
###############
# Pacman
###############
function pacman_update() {
sudo pacman -Syu
}
function pacman_is_installed() {
local package=$1
pacman -Qs $package >/dev/null 2>&1
}
function pacman_install() {
local package=$1
if pacman_is_installed "$package"; then
cecho "+ $package already installed... skipping."
else
sudo pacman -S --noconfirm "$package" || exit 1
fi
}
###############
# RVM
###############
function load_rvm_if_available() {
[ -f ~/.rvm/scripts/rvm ] && source ~/.rvm/scripts/rvm
}

View File

@ -22,18 +22,20 @@ else
PLATFORM=$1
fi
if ! program_version_exists node $EXPECTED_NODE_VERSION || ! program_version_exists yarn $EXPECTED_YARN_VERSION; then
echo -e "${YELLOW}********************************************************************************************"
if [ -z "$IN_NIX_SHELL" ]; then
if ! program_version_exists node $EXPECTED_NODE_VERSION || ! program_version_exists yarn $EXPECTED_YARN_VERSION; then
echo -e "${YELLOW}********************************************************************************************"
echo -e "The current environment doesn't contain the expected versions of node and/or yarn"
echo -e " - node:\texpected\t${EXPECTED_NODE_VERSION}"
echo -e " \t\tfound\t\t$(node -v) ($(which node))"
echo -e " - yarn:\texpected\t${EXPECTED_YARN_VERSION}"
echo -e " \t\tfound\t\t$(yarn -v) ($(which yarn))"
echo -e "Please open another console to reload the environment, and then run 'make setup' if necessary."
echo -e "The current environment doesn't contain the expected versions of node and/or yarn"
echo -e " - node:\texpected\t${EXPECTED_NODE_VERSION}"
echo -e " \t\tfound\t\t$(node -v) ($(which node))"
echo -e " - yarn:\texpected\t${EXPECTED_YARN_VERSION}"
echo -e " \t\tfound\t\t$(yarn -v) ($(which yarn))"
echo -e "Please open another console to reload the environment, and then run 'make setup' if necessary."
echo -e "**********************************************************************************************${NC}"
exit 1
echo -e "**********************************************************************************************${NC}"
exit 1
fi
fi
if [[ $PLATFORM == 'android' ]]; then

View File

@ -20,8 +20,6 @@ source_lib "installers.sh"
exit_unless_os_supported
load_rvm_if_available
####
setup_header "Checking prerequisites..."
@ -64,7 +62,6 @@ fi
setup_header "Installing requirements..."
install_nix && \
install_nsis && \
install_android_sdk && \
install_android_ndk || \
exit $?