Use cmake for linux DEPLOY build. (#2223)

* Add cmake script for building and installing translations.
* Improve APPIMAGE related path handling.
This commit is contained in:
karliss 2020-06-17 12:35:26 +03:00 committed by GitHub
parent 53da90625c
commit cd42adc832
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 205 additions and 50 deletions

1
.gitignore vendored
View File

@ -31,6 +31,7 @@ moc_*.h
ui_*.h
build*/
cmake-build-*/
/src-build/
# QtCreator
*.autosave

View File

@ -11,10 +11,10 @@ branches:
matrix:
include:
- name: Linux QMake + Deploy
- name: Linux QMake
os: linux
dist: xenial
env: BUILD_SYSTEM=qmake DEPLOY=1
env: BUILD_SYSTEM=qmake
addons:
apt:
packages:
@ -23,24 +23,34 @@ matrix:
- libgl1-mesa-dev
- libxkbcommon-x11-dev
- ninja-build/xenial-backports
before_install:
- pyenv global 3.7
- pip install meson
- name: Linux CMake
os: linux
env: BUILD_SYSTEM=cmake
env: BUILD_SYSTEM=cmake_nodep
addons:
apt:
packages:
- mesa-common-dev
- ninja-build
- libgraphviz-dev
before_install:
- pyenv global 3.7
- pip install meson
- qt5-default
- libqt5svg5-dev
- qttools5-dev
- name: Linux Ubuntu 16.04
- name: Linux CMake + Deploy
os: linux
env: BUILD_SYSTEM=cmake DEPLOY=1
dist: xenial
addons:
apt:
packages:
- mesa-common-dev
- libgl1-mesa-glx
- libgl1-mesa-dev
- libxkbcommon-x11-dev
- ninja-build/xenial-backports
- name: Linux Ubuntu 16.04 # test that Cutter can be built on an old distro using system libraries
os: linux
env: BUILD_SYSTEM=cmake_nodep PATH="/usr/bin:$PATH"
dist: xenial
@ -51,6 +61,8 @@ matrix:
- libgraphviz-dev
- qt5-default
- libqt5svg5-dev
- qttools5-dev
- qttools5-dev-tools
- cmake
before_install:
- pyenv install 3.5.2
@ -62,11 +74,13 @@ matrix:
os: osx
osx_image: xcode10.3
env: BUILD_SYSTEM=qmake DEPLOY=1
before_install: ~
- name: macOS CMake
os: osx
osx_image: xcode10.3
env: BUILD_SYSTEM=cmake
before_install: ~
- name: Documentation + Deploy
os: linux
@ -112,6 +126,10 @@ addons:
brewfile: scripts/Brewfile
update: true
before_install:
- pyenv global 3.7
- pip install meson
install:
- if [[ "$BUILD_SYSTEM" != "cmake_nodep" ]]; then
scripts/fetch_deps.sh;
@ -128,7 +146,7 @@ install:
before_script:
- cd radare2
- if [[ "$BUILD_SYSTEM" == "qmake" ]]; then
- if [[ "$BUILD_SYSTEM" == "qmake" ]] || ([[ "$BUILD_SYSTEM" == "cmake" ]] && [[ "$TRAVIS_OS_NAME" == "linux" ]]) ; then
if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
INSTALL_TARGET=install sys/install.sh /usr;
else
@ -148,19 +166,21 @@ script:
CUTTER_ENABLE_PYTHON_BINDINGS=true
CUTTER_ENABLE_CRASH_REPORTS=true
PREFIX=/usr
APPIMAGE=1
../src &&
make -j4;
elif [[ "$BUILD_SYSTEM" == "cmake" ]]; then
cmake
-DCMAKE_BUILD_TYPE=Release
-DCMAKE_PREFIX_PATH="$Qt5_ROOT"
-DPYTHON_LIBRARY="$CUTTER_DEPS_PYTHON_PREFIX/lib/libpython3.6m.so.1.0"
-DPYTHON_INCLUDE_DIR="$CUTTER_DEPS_PYTHON_PREFIX/include/python3.6m"
-DPYTHON_EXECUTABLE="$CUTTER_DEPS_PYTHON_PREFIX/bin/python3"
-DCUTTER_ENABLE_PYTHON=ON
-DCUTTER_ENABLE_PYTHON_BINDINGS=ON
-DCUTTER_ENABLE_CRASH_REPORTS=ON
-DCUTTER_USE_BUNDLED_RADARE2=ON
-DCUTTER_USE_BUNDLED_RADARE2=OFF
-DCUTTER_APPIMAGE_BUILD=ON
-DCMAKE_INSTALL_PREFIX=appdir/usr
../src &&
make -j4;
elif [[ "$BUILD_SYSTEM" == "cmake_nodep" ]]; then
@ -201,8 +221,8 @@ script:
after_success:
- export CUTTER_VERSION=$(python ../scripts/get_version.py)
- lrelease ../src/Cutter.pro
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
lrelease ../src/Cutter.pro &&
mkdir -p Cutter.app/Contents/Resources/translations &&
cp ../src/translations/*.qm Cutter.app/Contents/Resources/translations/ &&
macdeployqt Cutter.app -executable=Cutter.app/Contents/MacOS/Cutter -libpath="../Frameworks" &&
@ -231,20 +251,18 @@ after_success:
hdiutil convert "${DMG_TMP_FILE}" -format UDZO -imagekey zlib-level=9 -o "${DMG_FILE}" &&
export FILE_TO_UPLOAD="$DMG_FILE"
; fi
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
export VERSION=$CUTTER_VERSION
make INSTALL_ROOT=appdir install &&
- if [[ "$TRAVIS_OS_NAME" == "linux" ]] && [[ $DEPLOY == 1 ]]; then
export VERSION=$CUTTER_VERSION &&
make install &&
cp -r /usr/share/radare2 appdir/usr/share/ &&
mkdir -p appdir/usr/bin/translations &&
cp ../src/translations/*.qm appdir/usr/bin/translations/ &&
"$TRAVIS_BUILD_DIR/scripts/appimage_embed_python.sh" appdir &&
"$TRAVIS_BUILD_DIR/scripts/r2ghidra.sh" -DCMAKE_INSTALL_PREFIX="`pwd`/appdir/usr" -DBUILD_CUTTER_PLUGIN=ON -DCUTTER_SOURCE_DIR="$TRAVIS_BUILD_DIR" &&
"$TRAVIS_BUILD_DIR/scripts/r2dec.sh" --prefix=`pwd`/appdir/usr &&
wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/6/linuxdeployqt-6-x86_64.AppImage" &&
chmod a+x linuxdeployqt*.AppImage &&
rm -fv "$TRAVIS_BUILD_DIR/cutter-deps/qt/plugins/imageformats/libqjp2.so" &&
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -unsupported-allow-new-glibc -bundle-non-qt-libs -no-strip -exclude-libs=libnss3.so,libnssutil3.so,libqjp2.so -ignore-glob=usr/lib/python3.6/**/* -verbose=2 &&
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -unsupported-allow-new-glibc -appimage -no-strip -exclude-libs=libnss3.so,libnssutil3.so,libqjp2.so -ignore-glob=usr/lib/python3.6/**/* -verbose=2 &&
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -executable=./appdir/usr/bin/python3 -bundle-non-qt-libs -no-strip -exclude-libs=libnss3.so,libnssutil3.so,libqjp2.so -ignore-glob=usr/lib/python3.6/**/* -verbose=2 &&
./linuxdeployqt*.AppImage ./appdir/usr/share/applications/*.desktop -executable=./appdir/usr/bin/python3 -appimage -no-strip -exclude-libs=libnss3.so,libnssutil3.so,libqjp2.so -ignore-glob=usr/lib/python3.6/**/* -verbose=2 &&
find ./appdir -executable -type f -exec ldd {} \; | grep " => /usr" | cut -d " " -f 2-3 | sort | uniq &&
export APPIMAGE_FILE="Cutter-v$CUTTER_VERSION-x64.Linux.AppImage" &&
mv Cutter-*-x86_64.AppImage "$APPIMAGE_FILE" &&

View File

@ -30,13 +30,13 @@ On Debian-based Linux distributions, all of these packages can be installed with
::
sudo apt install git build-essential cmake meson libzip-dev zlib1g-dev qt5-default libqt5svg5-dev
sudo apt install git build-essential cmake meson libzip-dev zlib1g-dev qt5-default libqt5svg5-dev qttools5-dev qttools5-dev-tools
On Arch-based Linux distributions, build-essential should be replaced by base-devel:
::
sudo pacman -Syu git base-devel cmake meson qt5-base qt5-svg
sudo pacman -Syu git base-devel cmake meson qt5-base qt5-svg qt5-tools
Building steps
~~~~~~~~~~~~~~

View File

@ -16,6 +16,7 @@ option(CUTTER_USE_ADDITIONAL_RADARE2_PATHS "Search radare2 in additional paths w
option(CUTTER_ENABLE_PYTHON "Enable Python integration. Requires Python >= ${CUTTER_PYTHON_MIN}." OFF)
option(CUTTER_ENABLE_PYTHON_BINDINGS "Enable generating Python bindings with Shiboken2. Unused if CUTTER_ENABLE_PYTHON=OFF." OFF)
option(CUTTER_ENABLE_CRASH_REPORTS "Enable crash report system. Unused if CUTTER_ENABLE_CRASH_REPORTS=OFF" OFF)
option(CUTTER_APPIMAGE_BUILD "Enable Appimage specific changes. Doesn't cause building of Appimage itself." OFF)
tri_option(CUTTER_ENABLE_KSYNTAXHIGHLIGHTING "Use KSyntaxHighlighting" AUTO)
tri_option(CUTTER_ENABLE_GRAPHVIZ "Enable use of graphviz for graph layout" AUTO)
option (option SHIBOKEN_EXTRA_OPTIONS "Extra options for shiboken generator")
@ -242,6 +243,12 @@ if(TARGET KF5::SyntaxHighlighting)
target_compile_definitions(Cutter PRIVATE CUTTER_ENABLE_KSYNTAXHIGHLIGHTING)
endif()
if (CUTTER_APPIMAGE_BUILD)
target_compile_definitions(Cutter PRIVATE APPIMAGE)
endif()
include(Translations)
# Install files
install(TARGETS Cutter
EXPORT CutterTargets

View File

@ -427,7 +427,8 @@ SOURCES += \
common/SettingsUpgrade.cpp \
dialogs/LayoutManager.cpp \
common/CutterLayout.cpp \
widgets/GraphHorizontalAdapter.cpp
widgets/GraphHorizontalAdapter.cpp \
common/ResourcePaths.cpp
GRAPHVIZ_SOURCES = \
widgets/GraphvizLayout.cpp
@ -581,7 +582,8 @@ HEADERS += \
common/CutterLayout.h \
common/BinaryTrees.h \
common/LinkedListPool.h \
widgets/GraphHorizontalAdapter.h
widgets/GraphHorizontalAdapter.h \
common/ResourcePaths.h
GRAPHVIZ_HEADERS = widgets/GraphvizLayout.h

View File

@ -4,6 +4,7 @@
#include "plugins/PluginManager.h"
#include "CutterConfig.h"
#include "common/Decompiler.h"
#include "common/ResourcePaths.h"
#include <QApplication>
#include <QFileOpenEvent>
@ -255,7 +256,7 @@ bool CutterApplication::loadTranslations()
QTranslator *trQtBase = new QTranslator;
QTranslator *trQt = new QTranslator;
const QStringList &cutterTrPaths = Config()->getTranslationsDirectories();
const QStringList &cutterTrPaths = Cutter::getTranslationsDirectories();
for (const auto &trPath : cutterTrPaths) {
if (trCutter && trCutter->load(it, QLatin1String("cutter"), QLatin1String("_"), trPath)) {

View File

@ -1,10 +1,15 @@
set(CUTTER_DIR_NAME "RadareOrg/Cutter")
if(WIN32)
set(CMAKE_INSTALL_BINDIR "." CACHE PATH "Executable install directory")
set(CMAKE_INSTALL_INCLUDEDIR "include" CACHE PATH "Include install directory")
set(CMAKE_INSTALL_LIBDIR "lib" CACHE PATH "Library install directory")
set(CMAKE_INSTALL_DATAROOTDIR "./" CACHE PATH "Resource installation directory")
set(CUTTER_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}" CACHE PATH "Resource installation directory")
elseif(APPLE)
include(GNUInstallDirs) #TODO: use appropriate paths for macOS
set(CUTTER_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}/${CUTTER_DIR_NAME}" CACHE PATH "Resource installation directory")
else()
include(GNUInstallDirs)
set(CUTTER_INSTALL_DATADIR "${CMAKE_INSTALL_DATAROOTDIR}/${CUTTER_DIR_NAME}" CACHE PATH "Resource installation directory")
endif()
set(ConfigPackageLocation "${CMAKE_INSTALL_LIBDIR}/Cutter" CACHE PATH "Cmake file install location")
set(ConfigPackageLocation "${CMAKE_INSTALL_LIBDIR}/Cutter" CACHE PATH "Cmake file install location")

View File

@ -0,0 +1,28 @@
set(TS_FILES
translations/cutter_ar.ts
translations/cutter_ca.ts
translations/cutter_cn.ts
translations/cutter_de.ts
translations/cutter_es.ts
translations/cutter_fa.ts
translations/cutter_fr.ts
translations/cutter_it.ts
translations/cutter_nl.ts
translations/cutter_pt.ts
translations/cutter_ro.ts
translations/cutter_ru.ts
translations/cutter_tr.ts
)
set_source_files_properties(${TS_FILES} PROPERTIES OUTPUT_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/translations)
find_package(Qt5LinguistTools REQUIRED)
qt5_add_translation(qmFiles ${TS_FILES})
add_custom_target(translations ALL DEPENDS ${qmFiles} SOURCES ${TS_FILES})
install(FILES
${qmFiles}
# For Linux it might be more correct to use ${MAKE_INSTALL_LOCALEDIR}, but that
# uses share/locale_name/software_name layout instead of share/software_name/locale_files.
DESTINATION ${CUTTER_INSTALL_DATADIR}/translations
)

View File

@ -5,7 +5,6 @@
#include <QFontDatabase>
#include <QFile>
#include <QApplication>
#include <QLibraryInfo>
#ifdef CUTTER_ENABLE_KSYNTAXHIGHLIGHTING
#include <KSyntaxHighlighting/repository.h>
@ -15,6 +14,7 @@
#include "common/ColorThemeWorker.h"
#include "common/SyntaxHighlighter.h"
#include "common/ResourcePaths.h"
/* Map with names of themes associated with its color palette
* (Dark or Light), so for dark interface themes will be shown only Dark color themes
@ -652,7 +652,7 @@ void Configuration::setConfig(const QString &key, const QVariant &value)
*/
QStringList Configuration::getAvailableTranslations()
{
const auto &trDirs = getTranslationsDirectories();
const auto &trDirs = Cutter::getTranslationsDirectories();
QSet<QString> fileNamesSet;
for (const auto &trDir : trDirs) {
@ -704,21 +704,6 @@ bool Configuration::isFirstExecution()
}
}
QStringList Configuration::getTranslationsDirectories() const
{
static const QString cutterTranslationPath = QCoreApplication::applicationDirPath() +
QDir::separator()
+ QLatin1String("translations");
return {
cutterTranslationPath,
QLibraryInfo::location(QLibraryInfo::TranslationsPath),
#ifdef Q_OS_MAC
QStringLiteral("%1/../Resources/translations").arg(QCoreApplication::applicationDirPath()),
#endif // Q_OS_MAC
};
}
QString Configuration::getSelectedDecompiler()
{
return s.value("selectedDecompiler").toString();

View File

@ -154,12 +154,6 @@ public:
void setConfig(const QString &key, const QVariant &value);
bool isFirstExecution();
/**
* @brief Get list of available translation directories (depends on configuration and OS)
* @return list of directories
*/
QStringList getTranslationsDirectories() const;
/**
* @return id of the last selected decompiler (see CutterCore::getDecompilerById)
*/

View File

@ -0,0 +1,85 @@
#include "common/ResourcePaths.h"
#include <QLibraryInfo>
#include <QDir>
#include <QFileInfo>
#include <QApplication>
#include <QDebug>
#ifdef APPIMAGE
static QDir appimageRoot()
{
auto dir = QDir(QCoreApplication::applicationDirPath()); // appimage/usr/bin
dir.cdUp(); // /usr
dir.cdUp(); // /
return dir;
}
#endif
static QString substitutePath(QString path)
{
#ifdef APPIMAGE
if (path.startsWith("/usr")) {
return appimageRoot().absoluteFilePath("." + path);
}
#endif
return path;
}
/**
* @brief Substitute or filter paths returned by standardLocations based on Cutter package kind.
* @param paths list of paths to process
* @return
*/
static QStringList substitutePaths(const QStringList &paths)
{
QStringList result;
result.reserve(paths.size());
for (auto &path : paths) {
// consider ignoring some of system folders for portable packages here or standardLocations if it depends on path type
result.push_back(substitutePath(path));
}
return result;
}
QStringList Cutter::locateAll(QStandardPaths::StandardLocation type, const QString &fileName,
QStandardPaths::LocateOptions options)
{
// This function is reimplemented here instead of forwarded to Qt becauase existence check needs to be done
// after substitutions
QStringList result;
for (auto path : standardLocations(type)) {
QString filePath = path + QLatin1Char('/') + fileName;
bool exists = false;
qDebug() << "checking " << filePath;
if (options & QStandardPaths::LocateDirectory) {
exists = QDir(filePath).exists();
} else {
exists = QFileInfo(filePath).isFile();
}
if (exists) {
result.append(filePath);
}
}
return result;
}
QStringList Cutter::standardLocations(QStandardPaths::StandardLocation type)
{
return substitutePaths(QStandardPaths::standardLocations(type));
}
QString Cutter::writableLocation(QStandardPaths::StandardLocation type)
{
return substitutePath(QStandardPaths::writableLocation(type));
}
QStringList Cutter::getTranslationsDirectories()
{
auto result = locateAll(QStandardPaths::DataLocation, "translations",
QStandardPaths::LocateDirectory);
result << QLibraryInfo::location(QLibraryInfo::TranslationsPath);
return result;
}

View File

@ -0,0 +1,29 @@
#ifndef RESOURCE_PATHS_H
#define RESOURCE_PATHS_H
#include <QStandardPaths>
/**
* \file ResourcePaths.h
* Set of functions for obtaining various paths. Some of the functions are wrappers around
* QStandardPaths functions having the same name but with modifications specific to way
* Cutter is packaged.
*/
namespace Cutter {
QStringList locateAll(
QStandardPaths::StandardLocation type,
const QString &fileName,
QStandardPaths::LocateOptions options = QStandardPaths::LocateFile);
QStringList standardLocations(QStandardPaths::StandardLocation type);
QString writableLocation(QStandardPaths::StandardLocation type);
/**
* @brief Get list of available translation directories (depends on configuration and OS)
* @return list of directories
*/
QStringList getTranslationsDirectories();
}
#endif