aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--docs/find-module/FindGradle.rst1
-rw-r--r--docs/sphinx/ext/ecm.py2
-rw-r--r--find-modules/FindGradle.cmake90
-rw-r--r--find-modules/FindQtWaylandScanner.cmake4
-rw-r--r--find-modules/FindReuseTool.cmake6
-rw-r--r--find-modules/FindWaylandScanner.cmake3
-rw-r--r--find-modules/local.properties.cmake1
-rwxr-xr-xfind-modules/rules_engine.py3
-rwxr-xr-xfind-modules/run-sip.py3
-rw-r--r--find-modules/settings.gradle.cmake1
-rw-r--r--find-modules/sip_generator.py6
-rw-r--r--kde-modules/KDECMakeSettings.cmake11
-rw-r--r--kde-modules/KDEInstallDirs.cmake12
-rw-r--r--kde-modules/KDEPackageAppTemplates.cmake40
-rw-r--r--kde-modules/clang-format.cmake9
-rw-r--r--modules/ECMAddTests.cmake9
-rw-r--r--modules/ECMGenerateDBusServiceFile.cmake2
-rwxr-xr-xmodules/check-outbound-license.py6
-rw-r--r--tests/GenerateSipBindings/rules_SipTest.py3
-rw-r--r--tests/KDEFetchTranslations/CMakeLists.txt4
-rw-r--r--toolchain/Android.cmake4
-rw-r--r--toolchain/ECMAndroidDeployQt.cmake54
-rw-r--r--toolchain/deployment-file.json.in3
-rwxr-xr-xtoolchain/generate-fastlane-metadata.py343
-rw-r--r--toolchain/specifydependencies.cmake83
26 files changed, 608 insertions, 97 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 74c45ace..61fcd03c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -11,7 +11,7 @@ cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
# Preliminary setup
#
-set(VERSION "5.75.0") # handled by release scripts
+set(VERSION "5.78.0") # handled by release scripts
if (POLICY CMP0048)
cmake_policy(SET CMP0048 NEW)
diff --git a/docs/find-module/FindGradle.rst b/docs/find-module/FindGradle.rst
new file mode 100644
index 00000000..74e69411
--- /dev/null
+++ b/docs/find-module/FindGradle.rst
@@ -0,0 +1 @@
+.. ecm-module:: ../../find-modules/FindGradle.cmake
diff --git a/docs/sphinx/ext/ecm.py b/docs/sphinx/ext/ecm.py
index 2bab34a7..8667b367 100644
--- a/docs/sphinx/ext/ecm.py
+++ b/docs/sphinx/ext/ecm.py
@@ -76,7 +76,7 @@ class ECMModule(Directive):
settings.record_dependencies.add(path)
f = io.FileInput(source_path=path, encoding=encoding,
error_handler=e_handler)
- except UnicodeEncodeError as error:
+ except UnicodeEncodeError:
raise self.severe('Problems with "%s" directive path:\n'
'Cannot encode input file path "%s" '
'(wrong locale?).' %
diff --git a/find-modules/FindGradle.cmake b/find-modules/FindGradle.cmake
new file mode 100644
index 00000000..414ea661
--- /dev/null
+++ b/find-modules/FindGradle.cmake
@@ -0,0 +1,90 @@
+#.rst:
+# FindGradle
+# ----------
+#
+# Provides the ability to build Android AAR libraries using Gradle.
+#
+# This relies on the Qt provided Gradle, so a Qt for Android installation
+# is required.
+#
+# gradle_add_aar(<target>
+# BUIDLFILE build.gradle
+# NAME <aar-name>)
+#
+# This builds an Android AAR library using the given ``build.gradle`` file.
+#
+# gradle_install_aar(<target>
+# DESTINATION <dest>)
+#
+# Installs a Android AAR library that has been created with ``gradle_add_aar``.
+#
+# Since 5.76.0.
+
+#=============================================================================
+# SPDX-FileCopyrightText: 2019 Volker Krause <vkrause@kde.org>
+#
+# SPDX-License-Identifier: BSD-3-Clause
+#=============================================================================
+
+include(CMakeParseArguments)
+include(FindPackageHandleStandardArgs)
+
+find_package(Qt5Core REQUIRED)
+
+if (NOT WIN32)
+ set(Gradle_EXECUTABLE ${CMAKE_BINARY_DIR}/gradle/gradlew)
+else()
+ set(Gradle_EXECUTABLE ${CMAKE_BINARY_DIR}/gradle/gradlew.bat)
+endif()
+
+get_target_property(_qt_core_location Qt5::Core LOCATION)
+get_filename_component(_qt_install_root ${_qt_core_location} DIRECTORY)
+get_filename_component(_qt_install_root ${_qt_install_root}/../ ABSOLUTE)
+
+set(_gradle_template_dir ${CMAKE_CURRENT_LIST_DIR})
+
+add_custom_command(OUTPUT ${Gradle_EXECUTABLE}
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_BINARY_DIR}/gradle
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${_qt_install_root}/src/3rdparty/gradle ${CMAKE_BINARY_DIR}/gradle
+)
+add_custom_target(gradle DEPENDS ${Gradle_EXECUTABLE})
+
+find_package_handle_standard_args(Gradle DEFAULT_MSG Gradle_EXECUTABLE)
+
+function(gradle_add_aar target)
+ cmake_parse_arguments(ARG "" "BUILDFILE;NAME" "" ${ARGN})
+
+ set(_build_root ${CMAKE_CURRENT_BINARY_DIR}/gradle_build/${ARG_NAME})
+ configure_file(${_gradle_template_dir}/local.properties.cmake ${_build_root}/local.properties)
+ configure_file(${_gradle_template_dir}/settings.gradle.cmake ${_build_root}/settings.gradle)
+ configure_file(${ARG_BUILDFILE} ${_build_root}/build.gradle)
+
+ if (CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
+ set(_aar_suffix "-debug")
+ set(_aar_gradleCmd "assembleDebug")
+ else()
+ set(_aar_suffix "-release")
+ set(_aar_gradleCmd "assembleRelease")
+ endif()
+
+ file(GLOB_RECURSE _src_files CONFIGURE_DEPENDS "*")
+ add_custom_command(
+ OUTPUT ${_build_root}/build/outputs/aar/${ARG_NAME}${_aar_suffix}.aar
+ COMMAND ${Gradle_EXECUTABLE} ${_aar_gradleCmd}
+ # this allows make create-apk to work without installations for apps with AAR libs in the same repository
+ COMMAND ${CMAKE_COMMAND} -E copy ${_build_root}/build/outputs/aar/${ARG_NAME}${_aar_suffix}.aar ${CMAKE_BINARY_DIR}/jar/${ARG_NAME}.aar
+ DEPENDS ${Gradle_EXECUTABLE} ${_src_files}
+ DEPENDS gradle
+ WORKING_DIRECTORY ${_build_root}
+ )
+ add_custom_target(${target} ALL DEPENDS ${_build_root}/build/outputs/aar/${ARG_NAME}${_aar_suffix}.aar)
+ set_target_properties(${target} PROPERTIES LOCATION ${_build_root}/build/outputs/aar/${ARG_NAME}${_aar_suffix}.aar)
+ set_target_properties(${target} PROPERTIES OUTPUT_NAME ${ARG_NAME})
+endfunction()
+
+function(gradle_install_aar target)
+ cmake_parse_arguments(ARG "" "DESTINATION" "" ${ARGN})
+ get_target_property(_loc ${target} LOCATION)
+ get_target_property(_name ${target} OUTPUT_NAME)
+ install(FILES ${_loc} DESTINATION ${ARG_DESTINATION} RENAME ${_name}.aar)
+endfunction()
diff --git a/find-modules/FindQtWaylandScanner.cmake b/find-modules/FindQtWaylandScanner.cmake
index 65da5d2e..efbbe87a 100644
--- a/find-modules/FindQtWaylandScanner.cmake
+++ b/find-modules/FindQtWaylandScanner.cmake
@@ -117,8 +117,6 @@ function(ecm_add_qtwayland_client_protocol out_var)
BASENAME ${ARGS_BASENAME})
get_filename_component(_infile ${ARGS_PROTOCOL} ABSOLUTE)
- set(_ccode "${CMAKE_CURRENT_BINARY_DIR}/wayland-${ARGS_BASENAME}-client-protocol.c")
- set(_cheader "${CMAKE_CURRENT_BINARY_DIR}/wayland-${ARGS_BASENAME}-client-protocol.h")
set(_header "${CMAKE_CURRENT_BINARY_DIR}/qwayland-${ARGS_BASENAME}.h")
set(_code "${CMAKE_CURRENT_BINARY_DIR}/qwayland-${ARGS_BASENAME}.cpp")
@@ -132,7 +130,7 @@ function(ecm_add_qtwayland_client_protocol out_var)
COMMAND ${QtWaylandScanner_EXECUTABLE} client-code ${_infile} "" ${_prefix} > ${_code}
DEPENDS ${_infile} ${_header} VERBATIM)
- set_property(SOURCE ${_header} ${_code} ${_cheader} ${_ccode} PROPERTY SKIP_AUTOMOC ON)
+ set_property(SOURCE ${_header} ${_code} PROPERTY SKIP_AUTOMOC ON)
list(APPEND ${out_var} "${_code}")
set(${out_var} ${${out_var}} PARENT_SCOPE)
diff --git a/find-modules/FindReuseTool.cmake b/find-modules/FindReuseTool.cmake
index 9377f49e..adceeeb9 100644
--- a/find-modules/FindReuseTool.cmake
+++ b/find-modules/FindReuseTool.cmake
@@ -3,8 +3,8 @@
# Finds the REUSE Tool by FSFE: https://github.com/fsfe/reuse-tool
#
-# REUSE_TOOL_FOUND - True if REUSE tool is found.
-# REUSE_TOOL_EXECUTABLE - Path to executable
+# REUSETOOL_FOUND - True if REUSE tool is found.
+# REUSETOOL_EXECUTABLE - Path to executable
#=============================================================================
# SPDX-FileCopyrightText: 2020 Andreas Cord-Landwehr <cordlandwehr@kde.org>
@@ -19,5 +19,5 @@ find_package_handle_standard_args(ReuseTool
FOUND_VAR
REUSETOOL_FOUND
REQUIRED_VARS
- REUSE_TOOL_EXECUTABLE
+ REUSETOOL_EXECUTABLE
)
diff --git a/find-modules/FindWaylandScanner.cmake b/find-modules/FindWaylandScanner.cmake
index 61b4875e..08b0650b 100644
--- a/find-modules/FindWaylandScanner.cmake
+++ b/find-modules/FindWaylandScanner.cmake
@@ -134,7 +134,8 @@ function(ecm_add_wayland_server_protocol out_var)
get_filename_component(_infile ${ARGS_PROTOCOL} ABSOLUTE)
set(_server_header "${CMAKE_CURRENT_BINARY_DIR}/wayland-${ARGS_BASENAME}-server-protocol.h")
- set_property(SOURCE ${_server_header} PROPERTY SKIP_AUTOMOC ON)
+ set(_server_code "${CMAKE_CURRENT_BINARY_DIR}/wayland-${ARGS_BASENAME}-protocol.c")
+ set_property(SOURCE ${_server_header} ${_server_code} PROPERTY SKIP_AUTOMOC ON)
set_source_files_properties(${_server_header} GENERATED)
add_custom_command(OUTPUT "${_server_header}"
diff --git a/find-modules/local.properties.cmake b/find-modules/local.properties.cmake
new file mode 100644
index 00000000..4f14cc3f
--- /dev/null
+++ b/find-modules/local.properties.cmake
@@ -0,0 +1 @@
+sdk.dir=@ANDROID_SDK_ROOT@
diff --git a/find-modules/rules_engine.py b/find-modules/rules_engine.py
index 60611eeb..b9e9dedd 100755
--- a/find-modules/rules_engine.py
+++ b/find-modules/rules_engine.py
@@ -18,7 +18,6 @@ import os
import re
import sys
import textwrap
-import traceback
from copy import deepcopy
from clang.cindex import CursorKind
@@ -51,7 +50,7 @@ class Rule(object):
# Derive a useful name for diagnostic purposes.
#
caller = os.path.basename(inspect.stack()[3][1])
- self.name = "{}:{}[{}],{}".format(caller, type(db).__name__, rule_number, fn.__name__)
+ self.name = "{}:{}[{}],{}".format(caller, type(db).__name__, rule_number, fn.__name__)
self.rule_number = rule_number
self.fn = fn
self.usage = 0
diff --git a/find-modules/run-sip.py b/find-modules/run-sip.py
index fc8a5e2b..e745a607 100755
--- a/find-modules/run-sip.py
+++ b/find-modules/run-sip.py
@@ -1,6 +1,7 @@
#!/usr/bin/env python
-import os, sys
+import os
+import sys
import fnmatch
import subprocess
diff --git a/find-modules/settings.gradle.cmake b/find-modules/settings.gradle.cmake
new file mode 100644
index 00000000..6628d9e7
--- /dev/null
+++ b/find-modules/settings.gradle.cmake
@@ -0,0 +1 @@
+rootProject.name = '@ARG_NAME@'
diff --git a/find-modules/sip_generator.py b/find-modules/sip_generator.py
index 2dd2ef11..b8418649 100644
--- a/find-modules/sip_generator.py
+++ b/find-modules/sip_generator.py
@@ -12,12 +12,10 @@ import argparse
import gettext
import inspect
import logging
-import os
-import re
import sys
import traceback
from clang import cindex
-from clang.cindex import AccessSpecifier, AvailabilityKind, CursorKind, SourceRange, StorageClass, TokenKind, TypeKind, TranslationUnit
+from clang.cindex import AccessSpecifier, AvailabilityKind, CursorKind, SourceRange, TokenKind, TypeKind, TranslationUnit
import rules_engine
@@ -784,7 +782,7 @@ def main(argv=None):
body, includes = g.create_sip(args.source, args.include_filename)
with open(args.output, "w") as outputFile:
outputFile.write(body)
- except Exception as e:
+ except Exception:
tbk = traceback.format_exc()
print(tbk)
return -1
diff --git a/kde-modules/KDECMakeSettings.cmake b/kde-modules/KDECMakeSettings.cmake
index 0690a2ed..03d10d16 100644
--- a/kde-modules/KDECMakeSettings.cmake
+++ b/kde-modules/KDECMakeSettings.cmake
@@ -254,6 +254,13 @@ if(NOT KDE_SKIP_BUILD_SETTINGS)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
endif()
+ # For Android we need to put shared libraries into "lib" for androiddeployqt to work without prior installation.
+ # That fact that this conflicts with the above isn't really an issue, as we can't run things while cross-compiling
+ # for Android anyway.
+ if (ANDROID)
+ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
+ endif()
+
if (APPLE)
# Disable detection of X11 and related package on OS X because when using
# brew or macports, X11 can be installed and thus is detected.
@@ -300,7 +307,7 @@ function(_repository_name reponame dir)
WORKING_DIRECTORY "${dir}")
if(exitCode EQUAL 0)
- string(REGEX MATCHALL ".+[:\\/]([-A-Za-z0-9]+)(.git)?\\s*" "" ${giturl})
+ string(REGEX MATCHALL ".+kde\\.org[:\\/]([-A-Za-z0-9\\/]+)(.git)?\\s*" "" ${giturl})
set(${reponame} ${CMAKE_MATCH_1})
endif()
@@ -325,7 +332,7 @@ if(NOT EXISTS ${CMAKE_SOURCE_DIR}/po AND NOT TARGET fetch-translations)
_repository_name(_reponame "${CMAKE_SOURCE_DIR}")
set(releaseme_clone_commands
- COMMAND git clone --depth 1 https://anongit.kde.org/releaseme.git
+ COMMAND git clone --depth 1 https://invent.kde.org/sdk/releaseme.git
)
add_custom_command(
OUTPUT "${CMAKE_BINARY_DIR}/releaseme"
diff --git a/kde-modules/KDEInstallDirs.cmake b/kde-modules/KDEInstallDirs.cmake
index d739cf19..bba3a9c8 100644
--- a/kde-modules/KDEInstallDirs.cmake
+++ b/kde-modules/KDEInstallDirs.cmake
@@ -7,6 +7,10 @@
# Note that none of the variables defined by this module provide any
# information about the location of already-installed KDE software.
#
+# Also sets ``CMAKE_INSTALL_PREFIX`` to the installation prefix of ECM,
+# unless that variable has been already explicitly set by something else
+# (since 5.61 and with CMake >= 3.7).
+#
# Inclusion of this module defines the following variables:
#
# ``KDE_INSTALL_<dir>``
@@ -573,8 +577,12 @@ _define_relative(KNOTIFY5RCDIR DATAROOTDIR "knotifications5"
_define_relative(KXMLGUI5DIR DATAROOTDIR "kxmlgui5"
"kxmlgui .rc files"
KXMLGUI_INSTALL_DIR)
-_define_relative(KTEMPLATESDIR DATAROOTDIR "kdevappwizard/templates"
- "Kapptemplate and Kdevelop templates")
+_define_relative(KAPPTEMPLATESDIR DATAROOTDIR "kdevappwizard/templates"
+ "KAppTemplate and KDevelop templates"
+ KDE_INSTALL_KTEMPLATESDIR
+ )
+_define_relative(KFILETEMPLATESDIR DATAROOTDIR "kdevfiletemplates/templates"
+ "KDevelop file templates")
_define_relative(LOGGINGCATEGORIESDIR DATAROOTDIR "qlogging-categories5"
"Qt Logging categories files")
_define_relative(JARDIR "" "jar"
diff --git a/kde-modules/KDEPackageAppTemplates.cmake b/kde-modules/KDEPackageAppTemplates.cmake
index 7d2ddb3c..9403d63b 100644
--- a/kde-modules/KDEPackageAppTemplates.cmake
+++ b/kde-modules/KDEPackageAppTemplates.cmake
@@ -101,41 +101,39 @@ function(kde_package_app_templates)
endif()
foreach(_templateName ${ARG_TEMPLATES})
-
get_filename_component(_tmp_file ${_templateName} ABSOLUTE)
get_filename_component(_baseName ${_tmp_file} NAME_WE)
set(_template ${CMAKE_CURRENT_BINARY_DIR}/${_baseName}.tar.bz2)
- file(GLOB _files "${CMAKE_CURRENT_SOURCE_DIR}/${_templateName}/*")
- set(_deps)
- foreach(_file ${_files})
- get_filename_component(_fileName ${_file} NAME)
- string(COMPARE NOTEQUAL ${_fileName} .kdev_ignore _v1)
- string(REGEX MATCH "\\.svn" _v2 ${_fileName})
- if(WIN32)
- string(REGEX MATCH "_svn" _v3 ${_fileName})
- else(WIN32)
- set(_v3 FALSE)
- endif()
- if (_v1 AND NOT _v2 AND NOT _v3)
- set(_deps ${_deps} ${_file})
- endif ()
- endforeach()
-
+ # CONFIGURE_DEPENDS is only available for cmake >= 3.12
+ if(NOT CMAKE_VERSION VERSION_LESS "3.12.0")
+ # also enlist directories as deps to catch file removals
+ file(GLOB_RECURSE _subdirs_entries LIST_DIRECTORIES true CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${_templateName}/*")
+ else()
+ file(GLOB_RECURSE _subdirs_entries LIST_DIRECTORIES true "${CMAKE_CURRENT_SOURCE_DIR}/${_templateName}/*")
+ # custom code to implement CONFIGURE_DEPENDS
+ foreach(_direntry ${_subdirs_entries})
+ if(IS_DIRECTORY ${_direntry})
+ set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${_direntry})
+ endif()
+ endforeach()
+ endif()
add_custom_target(${_baseName} ALL DEPENDS ${_template})
if(GNU_TAR_FOUND)
# Make tar archive reproducible, the arguments are only available with GNU tar
add_custom_command(OUTPUT ${_template}
- COMMAND ${_tar_executable} ARGS -c ${CMAKE_CURRENT_SOURCE_DIR}/${_templateName}
- --exclude .kdev_ignore --exclude .svn --sort=name --mode=go=rX,u+rw,a-s --owner=root
- --group=root --numeric-owner -j -v -f ${_template} .
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_templateName}
+ COMMAND ${_tar_executable} ARGS -c ${CMAKE_CURRENT_SOURCE_DIR}/${_templateName}
+ --exclude .kdev_ignore --exclude .svn --sort=name --mode=go=rX,u+rw,a-s --owner=root
+ --group=root --numeric-owner -j -v -f ${_template} .
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_templateName}
+ DEPENDS ${_subdirs_entries}
)
else()
add_custom_command(OUTPUT ${_template}
COMMAND ${CMAKE_COMMAND} -E tar "cvfj" ${_template} .
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_templateName}
+ DEPENDS ${_subdirs_entries}
)
endif()
diff --git a/kde-modules/clang-format.cmake b/kde-modules/clang-format.cmake
index 9e7bbc71..c3e43485 100644
--- a/kde-modules/clang-format.cmake
+++ b/kde-modules/clang-format.cmake
@@ -32,9 +32,6 @@ PointerAlignment: Right
# horizontally aligns arguments after an open bracket.
AlignAfterOpenBracket: Align
-# align trailing comments
-AlignTrailingComments: true
-
# don't move all parameters to new line
AllowAllParametersOfDeclarationOnNextLine: false
@@ -56,6 +53,9 @@ BreakBeforeBinaryOperators: None
# format C++11 braced lists like function calls
Cpp11BracedListStyle: true
+# do not put a space before C++11 braced lists
+SpaceBeforeCpp11BracedList: false
+
# remove empty lines
KeepEmptyLinesAtTheStartOfBlocks: false
@@ -67,3 +67,6 @@ SpaceAfterTemplateKeyword: false
# macros for which the opening brace stays attached.
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH, forever, Q_FOREVER, QBENCHMARK, QBENCHMARK_ONCE ]
+
+# keep lambda formatting multi-line if not empty
+AllowShortLambdasOnASingleLine: Empty
diff --git a/modules/ECMAddTests.cmake b/modules/ECMAddTests.cmake
index 4bc7fb8b..7e518212 100644
--- a/modules/ECMAddTests.cmake
+++ b/modules/ECMAddTests.cmake
@@ -94,13 +94,14 @@ function(ecm_add_test)
target_link_libraries(${_targetname} ${ARG_LINK_LIBRARIES})
ecm_mark_as_test(${_targetname})
if (CMAKE_LIBRARY_OUTPUT_DIRECTORY)
- if(CMAKE_HOST_SYSTEM MATCHES "Windows")
- set(PATHSEP ";")
+ if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
+ # https://stackoverflow.com/questions/59862894/how-do-i-make-a-list-in-cmake-with-the-semicolon-value
+ set(PATHSEP "\\\;") # Don't want cmake to treat it like a list
else() # e.g. Linux
set(PATHSEP ":")
endif()
- set(_plugin_path $ENV{QT_PLUGIN_PATH})
- set_property(TEST ${_testname} PROPERTY ENVIRONMENT QT_PLUGIN_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}${PATHSEP}${_plugin_path})
+ set(_plugin_path "$ENV{QT_PLUGIN_PATH}")
+ set_property(TEST ${_testname} PROPERTY ENVIRONMENT "QT_PLUGIN_PATH=${CMAKE_LIBRARY_OUTPUT_DIRECTORY}${PATHSEP}${_plugin_path}")
endif()
if (ARG_TARGET_NAME_VAR)
set(${ARG_TARGET_NAME_VAR} "${_targetname}" PARENT_SCOPE)
diff --git a/modules/ECMGenerateDBusServiceFile.cmake b/modules/ECMGenerateDBusServiceFile.cmake
index eabc1b42..12c37c7b 100644
--- a/modules/ECMGenerateDBusServiceFile.cmake
+++ b/modules/ECMGenerateDBusServiceFile.cmake
@@ -12,7 +12,7 @@
# EXECUTABLE <executable>
# [SYSTEMD_SERVICE <systemd service>]
# DESTINATION <install_path>
-# [RENAME <dbus service filename>]
+# [RENAME <dbus service filename>] # Since 5.75
# )
#
# A D-Bus service file ``<service name>.service`` will be generated and installed
diff --git a/modules/check-outbound-license.py b/modules/check-outbound-license.py
index b8c1ef23..2657e628 100755
--- a/modules/check-outbound-license.py
+++ b/modules/check-outbound-license.py
@@ -125,15 +125,15 @@ if __name__ == '__main__':
spdxDictionary[fileName] = licenses
fileName = ""
licenses = []
- f.close();
+ f.close()
# read file with list of test files
f = open(args.input, "r")
testfiles = f.readlines()
f.close()
- if check_outbound_license(args.license, testfiles, spdxDictionary) == True:
- sys.exit(0);
+ if check_outbound_license(args.license, testfiles, spdxDictionary) is True:
+ sys.exit(0)
# in any other case, return error code
sys.exit(1)
diff --git a/tests/GenerateSipBindings/rules_SipTest.py b/tests/GenerateSipBindings/rules_SipTest.py
index c570a039..a75a5826 100644
--- a/tests/GenerateSipBindings/rules_SipTest.py
+++ b/tests/GenerateSipBindings/rules_SipTest.py
@@ -1,5 +1,6 @@
-import os, sys
+import os
+import sys
import rules_engine
sys.path.append(os.path.dirname(os.path.dirname(rules_engine.__file__)))
diff --git a/tests/KDEFetchTranslations/CMakeLists.txt b/tests/KDEFetchTranslations/CMakeLists.txt
index e68c7966..8b07c30d 100644
--- a/tests/KDEFetchTranslations/CMakeLists.txt
+++ b/tests/KDEFetchTranslations/CMakeLists.txt
@@ -18,8 +18,8 @@ foreach(module ${all_kde_modules})
endforeach()
_repository_name(name "${CMAKE_CURRENT_SOURCE_DIR}/../../")
-if (NOT ${name} STREQUAL "extra-cmake-modules")
- message(FATAL_ERROR "Wrong repository name: ${name}, should be 'extra-cmake-modules'")
+if (NOT ${name} STREQUAL "frameworks/extra-cmake-modules")
+ message(FATAL_ERROR "Wrong repository name: ${name}, should be 'frameworks/extra-cmake-modules'")
endif()
add_executable(dummy ../ExecuteKDEModules/main.c)
ecm_mark_nongui_executable(dummy)
diff --git a/toolchain/Android.cmake b/toolchain/Android.cmake
index 80720711..182fa0ac 100644
--- a/toolchain/Android.cmake
+++ b/toolchain/Android.cmake
@@ -19,7 +19,7 @@
#
# .. note::
#
-# This module requires CMake 3.7.
+# This module requires CMake 3.18.
#
# Since 1.7.0.
#
@@ -118,7 +118,7 @@
#
# SPDX-License-Identifier: BSD-3-Clause
-cmake_minimum_required(VERSION "3.7")
+cmake_minimum_required(VERSION "3.18")
macro(set_deprecated_variable actual_variable deprecated_variable default_value)
set(${deprecated_variable} "${default_value}" CACHE STRING "Deprecated. Use ${actual_variable}")
diff --git a/toolchain/ECMAndroidDeployQt.cmake b/toolchain/ECMAndroidDeployQt.cmake
index b04b5dd7..65b68c67 100644
--- a/toolchain/ECMAndroidDeployQt.cmake
+++ b/toolchain/ECMAndroidDeployQt.cmake
@@ -1,5 +1,36 @@
-cmake_minimum_required (VERSION 3.7 FATAL_ERROR)
+cmake_minimum_required (VERSION 3.19 FATAL_ERROR)
find_package(Qt5Core REQUIRED)
+find_package(Python3 COMPONENTS Interpreter REQUIRED)
+
+# Taken from https://stackoverflow.com/a/62311397
+function(_ecm_get_all_targets var)
+ set(targets)
+ _ecm_get_all_targets_recursive(targets ${CMAKE_CURRENT_SOURCE_DIR})
+ set(${var} ${targets} PARENT_SCOPE)
+endfunction()
+
+macro(_ecm_get_all_targets_recursive targets dir)
+ get_property(subdirectories DIRECTORY ${dir} PROPERTY SUBDIRECTORIES)
+ foreach(subdir ${subdirectories})
+ _ecm_get_all_targets_recursive(${targets} ${subdir})
+ endforeach()
+
+ get_property(current_targets DIRECTORY ${dir} PROPERTY BUILDSYSTEM_TARGETS)
+ list(APPEND ${targets} ${current_targets})
+endmacro()
+
+function(_ecm_deferred_androiddeployqt)
+ _ecm_get_all_targets(all_targets)
+ set(module_targets)
+ foreach(tgt ${all_targets})
+ get_target_property(tgt_type ${tgt} TYPE)
+ if(tgt_type STREQUAL "MODULE_LIBRARY")
+ list(APPEND module_targets "$<TARGET_FILE:${tgt}>")
+ endif()
+ endforeach()
+ file(GENERATE OUTPUT "module-plugins" CONTENT "${module_targets}")
+endfunction()
+cmake_language(DEFER DIRECTORY "${CMAKE_SOURCE_DIR}" CALL _ecm_deferred_androiddeployqt)
function(ecm_androiddeployqt QTANDROID_EXPORTED_TARGET ECM_ADDITIONAL_FIND_ROOT_PATH)
set(EXPORT_DIR "${CMAKE_BINARY_DIR}/${QTANDROID_EXPORTED_TARGET}_build_apk/")
@@ -9,6 +40,10 @@ function(ecm_androiddeployqt QTANDROID_EXPORTED_TARGET ECM_ADDITIONAL_FIND_ROOT_
set(EXECUTABLE_DESTINATION_PATH "${EXPORT_DIR}/libs/${CMAKE_ANDROID_ARCH_ABI}/lib${QTANDROID_EXPORTED_TARGET}_${CMAKE_ANDROID_ARCH_ABI}.so")
endif()
set(QML_IMPORT_PATHS "")
+ # add build directory to the search path as well, so this works without installation
+ if (EXISTS ${CMAKE_BINARY_DIR}/lib)
+ set(QML_IMPORT_PATHS ${CMAKE_BINARY_DIR}/lib)
+ endif()
foreach(prefix ${ECM_ADDITIONAL_FIND_ROOT_PATH})
# qmlimportscanner chokes on symlinks, so we need to resolve those first
get_filename_component(qml_path "${prefix}/lib/qml" REALPATH)
@@ -24,13 +59,9 @@ function(ecm_androiddeployqt QTANDROID_EXPORTED_TARGET ECM_ADDITIONAL_FIND_ROOT_
set(DEFINE_QML_IMPORT_PATHS "\"qml-import-paths\": \"${QML_IMPORT_PATHS}\",")
endif()
- set(EXTRA_PREFIX_DIRS "")
+ set(EXTRA_PREFIX_DIRS "\"${CMAKE_BINARY_DIR}\"")
foreach(prefix ${ECM_ADDITIONAL_FIND_ROOT_PATH})
- if (EXTRA_PREFIX_DIRS)
- set(EXTRA_PREFIX_DIRS "${EXTRA_PREFIX_DIRS}, \"${prefix}\"")
- else()
- set(EXTRA_PREFIX_DIRS "\"${prefix}\"")
- endif()
+ set(EXTRA_PREFIX_DIRS "${EXTRA_PREFIX_DIRS}, \"${prefix}\"")
endforeach()
if (Qt5Core_VERSION VERSION_LESS 5.14.0)
@@ -64,6 +95,12 @@ function(ecm_androiddeployqt QTANDROID_EXPORTED_TARGET ECM_ADDITIONAL_FIND_ROOT_
if (NOT TARGET create-apk)
add_custom_target(create-apk)
+ if (NOT DEFINED ANDROID_FASTLANE_METADATA_OUTPUT_DIR)
+ set(ANDROID_FASTLANE_METADATA_OUTPUT_DIR ${CMAKE_BINARY_DIR}/fastlane)
+ endif()
+ add_custom_target(create-fastlane
+ COMMAND Python3::Interpreter ${CMAKE_CURRENT_LIST_DIR}/generate-fastlane-metadata.py --output ${ANDROID_FASTLANE_METADATA_OUTPUT_DIR} --source ${CMAKE_SOURCE_DIR}
+ )
endif()
if (NOT DEFINED ANDROID_APK_OUTPUT_DIR)
@@ -77,7 +114,7 @@ function(ecm_androiddeployqt QTANDROID_EXPORTED_TARGET ECM_ADDITIONAL_FIND_ROOT_
COMMAND cmake -E copy_directory "$<TARGET_PROPERTY:create-apk-${QTANDROID_EXPORTED_TARGET},ANDROID_APK_DIR>" "${EXPORT_DIR}"
COMMAND cmake -E copy "$<TARGET_FILE:${QTANDROID_EXPORTED_TARGET}>" "${EXECUTABLE_DESTINATION_PATH}"
COMMAND LANG=C cmake "-DTARGET=$<TARGET_FILE:${QTANDROID_EXPORTED_TARGET}>" -P ${_CMAKE_ANDROID_DIR}/hasMainSymbol.cmake
- COMMAND LANG=C cmake -DINPUT_FILE="${QTANDROID_EXPORTED_TARGET}-deployment.json.in2" -DOUTPUT_FILE="${QTANDROID_EXPORTED_TARGET}-deployment.json" "-DTARGET=$<TARGET_FILE:${QTANDROID_EXPORTED_TARGET}>" "-DOUTPUT_DIR=$<TARGET_FILE_DIR:${QTANDROID_EXPORTED_TARGET}>" "-DEXPORT_DIR=${CMAKE_INSTALL_PREFIX}" "-DECM_ADDITIONAL_FIND_ROOT_PATH=\"${ECM_ADDITIONAL_FIND_ROOT_PATH}\"" "-DANDROID_EXTRA_LIBS=\"${ANDROID_EXTRA_LIBS}\"" -P ${_CMAKE_ANDROID_DIR}/specifydependencies.cmake
+ COMMAND LANG=C cmake -DINPUT_FILE="${QTANDROID_EXPORTED_TARGET}-deployment.json.in2" -DOUTPUT_FILE="${QTANDROID_EXPORTED_TARGET}-deployment.json" "-DTARGET=$<TARGET_FILE:${QTANDROID_EXPORTED_TARGET}>" "-DOUTPUT_DIR=$<TARGET_FILE_DIR:${QTANDROID_EXPORTED_TARGET}>" "-DEXPORT_DIR=${CMAKE_INSTALL_PREFIX}" "-DECM_ADDITIONAL_FIND_ROOT_PATH=\"${ECM_ADDITIONAL_FIND_ROOT_PATH}\"" "-DANDROID_EXTRA_LIBS=\"${ANDROID_EXTRA_LIBS}\"" "-DUSE_LLVM=\"${USE_LLVM}\"" -P ${_CMAKE_ANDROID_DIR}/specifydependencies.cmake
COMMAND $<TARGET_FILE_DIR:Qt5::qmake>/androiddeployqt --gradle --input "${QTANDROID_EXPORTED_TARGET}-deployment.json" --apk "${ANDROID_APK_OUTPUT_DIR}/${QTANDROID_EXPORTED_TARGET}-${CMAKE_ANDROID_ARCH_ABI}.apk" --output "${EXPORT_DIR}" --android-platform android-${ANDROID_SDK_COMPILE_API} --deployment bundled ${arguments}
)
# --android-platform above is only available as a command line option
@@ -88,4 +125,5 @@ function(ecm_androiddeployqt QTANDROID_EXPORTED_TARGET ECM_ADDITIONAL_FIND_ROOT_
COMMAND adb install -r "${ANDROID_APK_OUTPUT_DIR}/${QTANDROID_EXPORTED_TARGET}-${CMAKE_ANDROID_ARCH_ABI}.apk"
)
add_dependencies(create-apk ${CREATEAPK_TARGET_NAME})
+ add_dependencies(${CREATEAPK_TARGET_NAME} create-fastlane)
endfunction()
diff --git a/toolchain/deployment-file.json.in b/toolchain/deployment-file.json.in
index 206e069d..c870b5f4 100644
--- a/toolchain/deployment-file.json.in
+++ b/toolchain/deployment-file.json.in
@@ -17,5 +17,6 @@
"sdkBuildToolsRevision": "@ANDROID_SDK_BUILD_TOOLS_REVISION@",
"android-min-sdk-version": "@ANDROID_API_LEVEL@",
"android-target-sdk-version": "@ANDROID_SDK_COMPILE_API@",
- "extraPrefixDirs": [ @EXTRA_PREFIX_DIRS@ ]
+ "extraPrefixDirs": [ @EXTRA_PREFIX_DIRS@ ],
+ "useLLVM": ##USE_LLVM##
}
diff --git a/toolchain/generate-fastlane-metadata.py b/toolchain/generate-fastlane-metadata.py
new file mode 100755
index 00000000..30d16927
--- /dev/null
+++ b/toolchain/generate-fastlane-metadata.py
@@ -0,0 +1,343 @@
+#!/usr/bin/env python3
+#
+# SPDX-FileCopyrightText: 2018-2020 Aleix Pol Gonzalez <aleixpol@kde.org>
+# SPDX-FileCopyrightText: 2019-2020 Ben Cooksley <bcooksley@kde.org>
+# SPDX-FileCopyrightText: 2020 Volker Krause <vkrause@kde.org>
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+#
+# Generates fastlane metadata for Android apps from appstream files.
+#
+
+import argparse
+import glob
+import io
+import os
+import re
+import requests
+import shutil
+import subprocess
+import sys
+import tempfile
+import xdg.DesktopEntry
+import xml.etree.ElementTree as ET
+import yaml
+import zipfile
+
+# Constants used in this script
+languageMap = {
+ None: "en-US",
+ "ca": "ca-ES"
+}
+
+# see https://f-droid.org/en/docs/All_About_Descriptions_Graphics_and_Screenshots/
+supportedRichTextTags = { 'li', 'ul', 'ol', 'li', 'b', 'u', 'i' }
+
+# Android appdata.xml textual item parser
+# This function handles reading standard text entries within an Android appdata.xml file
+# In particular, it handles splitting out the various translations, and converts some HTML to something which F-Droid can make use of
+def readText(elem, found):
+ # Determine the language this entry is in
+ lang = elem.get('{http://www.w3.org/XML/1998/namespace}lang')
+ if lang == 'x-test':
+ return
+
+ # Do we have any text for this language yet?
+ # If not, get everything setup
+ if not lang in found:
+ found[lang] = ""
+
+ # If there is text available, we'll want to extract it
+ # Additionally, if this element has any children, make sure we read those as well
+ # It isn't clear if it is possible for an item to not have text, but to have children which do have text
+ # The code will currently skip these if they're encountered
+ if elem.text:
+ if elem.tag in supportedRichTextTags:
+ found[lang] += '<' + elem.tag + '>'
+ found[lang] += elem.text
+ for child in elem:
+ readText(child, found)
+ if elem.tag in supportedRichTextTags:
+ found[lang] += '</' + elem.tag + '>'
+
+ # Finally, if this element is a HTML Paragraph (p) or HTML List Item (li) make sure we add a new line for presentation purposes
+ if elem.tag == 'li' or elem.tag == 'p':
+ found[lang] += "\n"
+
+
+# Create the various Fastlane format files per the information we've previously extracted
+# These files are laid out following the Fastlane specification (links below)
+# https://github.com/fastlane/fastlane/blob/2.28.7/supply/README.md#images-and-screenshots
+# https://docs.fastlane.tools/actions/supply/
+def createFastlaneFile( applicationName, filenameToPopulate, fileContent ):
+ # Go through each language and content pair we've been given
+ for lang, text in fileContent.items():
+ # First, do we need to amend the language id, to turn the Android language ID into something more F-Droid/Fastlane friendly?
+ languageCode = languageMap.get(lang, lang)
+
+ # Next we need to determine the path to the directory we're going to be writing the data into
+ repositoryBasePath = arguments.output
+ path = os.path.join( repositoryBasePath, 'metadata', applicationName, languageCode )
+
+ # Make sure the directory exists
+ os.makedirs(path, exist_ok=True)
+
+ # Now write out file contents!
+ with open(path + '/' + filenameToPopulate, 'w') as f:
+ f.write(text)
+
+# Create the summary appname.yml file used by F-Droid to summarise this particular entry in the repository
+# see https://f-droid.org/en/docs/Build_Metadata_Reference/
+def createYml(appname, data):
+ # Prepare to retrieve the existing information
+ info = {}
+
+ # Determine the path to the appname.yml file
+ repositoryBasePath = arguments.output
+ path = os.path.join( repositoryBasePath, 'metadata', appname + '.yml' )
+
+ # Update the categories first
+ # Now is also a good time to add 'KDE' to the list of categories as well
+ if 'categories' in data:
+ info['Categories'] = data['categories'][None] + ['KDE']
+ else:
+ info['Categories'] = ['KDE']
+
+ # Update the general sumamry as well
+ info['Summary'] = data['summary'][None]
+
+ # Check to see if we have a Homepage...
+ if 'url-homepage' in data:
+ info['WebSite'] = data['url-homepage'][None]
+
+ # What about a bug tracker?
+ if 'url-bugtracker' in data:
+ info['IssueTracker'] = data['url-bugtracker'][None]
+
+ if 'project_license' in data:
+ info["License"] = data['project_license'][None]
+
+ if 'source-repo' in data:
+ info['SourceCode'] = data['source-repo']
+
+ # static data
+ info['Donate'] = 'https://kde.org/community/donations/'
+ info['Translation'] = 'https://l10n.kde.org/'
+
+ # Finally, with our updates completed, we can save the updated appname.yml file back to disk
+ with open(path, 'w') as output:
+ yaml.dump(info, output, default_flow_style=False)
+
+# Download screenshots referenced in the appstream data
+# see https://f-droid.org/en/docs/All_About_Descriptions_Graphics_and_Screenshots/
+def downloadScreenshots(applicationName, data):
+ if not 'screenshots' in data:
+ return
+
+ basePath = arguments.output
+ path = os.path.join(basePath, 'metadata', applicationName, 'en-US', 'images', 'phoneScreenshots')
+ shutil.rmtree(path, ignore_errors=True)
+ os.makedirs(path, exist_ok=True)
+
+ i = 0
+ for screenshot in data['screenshots']:
+ fileName = str(i) + '-' + screenshot[screenshot.rindex('/') + 1:]
+ r = requests.get(screenshot)
+ if r.status_code < 400:
+ with open(os.path.join(path, fileName), 'wb') as f:
+ f.write(r.content)
+ i += 1
+
+# Put all metadata for the given application name into an archive
+# We need this to easily transfer the entire metadata to the signing machine for integration
+# into the F-Droid nightly repository
+def createMetadataArchive(applicationName):
+ srcPath = os.path.join(arguments.output, 'metadata')
+ zipFileName = os.path.join(srcPath, 'fastlane-' + applicationName + '.zip')
+ if os.path.exists(zipFileName):
+ os.unlink(zipFileName)
+ archive = zipfile.ZipFile(zipFileName, 'w')
+ archive.write(os.path.join(srcPath, applicationName + '.yml'), applicationName + '.yml')
+
+ oldcwd = os.getcwd()
+ os.chdir(srcPath)
+ for file in glob.iglob(applicationName + '/**', recursive=True):
+ archive.write(file, file)
+ os.chdir(oldcwd)
+
+# Main function for extracting metadata from APK files
+def processApkFile(apkFilepath):
+ # First, determine the name of the application we have here
+ # This is needed in order to locate the metadata files within the APK that have the information we need
+
+ # Prepare the aapt (Android SDK command) to inspect the provided APK
+ commandToRun = "aapt dump badging %s" % (apkFilepath)
+ manifest = subprocess.check_output( commandToRun, shell=True ).decode('utf-8')
+ # Search through the aapt output for the name of the application
+ result = re.search(' name=\'([^\']*)\'', manifest)
+ applicationName = result.group(1)
+
+ # Attempt to look within the APK provided for the metadata information we will need
+ with zipfile.ZipFile(apkFilepath, 'r') as contents:
+ appdataFile = contents.open("assets/share/metainfo/%s.appdata.xml" % applicationName)
+ desktopFileContent = None
+ try:
+ desktopFileContent = contents.read("assets/share/applications/%s.desktop" % applicationName)
+ except:
+ None
+ processAppstreamData(applicationName, appdataFile.read(), desktopFileContent)
+
+# Extract meta data from appstream/desktop file contents
+def processAppstreamData(applicationName, appstreamData, desktopData):
+ data = {}
+ # Within this file we look at every entry, and where possible try to export it's content so we can use it later
+ root = ET.fromstring(appstreamData)
+ for child in root:
+ # Make sure we start with a blank slate for this entry
+ output = {}
+
+ # Grab the name of this particular attribute we're looking at
+ # Within the Fastlane specification, it is possible to have several items with the same name but as different types
+ # We therefore include this within our extracted name for the attribute to differentiate them
+ tag = child.tag
+ if 'type' in child.attrib:
+ tag += '-' + child.attrib['type']
+
+ # Have we found some information already for this particular attribute?
+ if tag in data:
+ output = data[tag]
+
+ # Are we dealing with category information here?
+ # If so, then we need to look into this items children to find out all the categories this APK belongs in
+ if tag == 'categories':
+ cats = []
+ for x in child:
+ cats.append(x.text)
+ output = { None: cats }
+
+ # screenshot links
+ elif tag == 'screenshots':
+ output = []
+ for screenshot in child:
+ if screenshot.tag == 'screenshot':
+ for image in screenshot:
+ if image.tag == 'image':
+ output.append(image.text)
+
+ # Otherwise this is just textual information we need to extract
+ else:
+ readText(child, output)
+
+ # Save the information we've gathered!
+ data[tag] = output
+
+ # Did we find any categories?
+ # Sometimes we don't find any within the Fastlane information, but without categories the F-Droid store isn't of much use
+ # In the event this happens, fallback to the *.desktop file for the application to see if it can provide any insight.
+ if not 'categories' in data and desktopData:
+ # The Python XDG extension/wrapper requires that it be able to read the file itself
+ # To ensure it is able to do this, we transfer the content of the file from the APK out to a temporary file to keep it happy
+ (fd, path) = tempfile.mkstemp(suffix=applicationName + ".desktop")
+ handle = open(fd, "wb")
+ handle.write(desktopData)
+ handle.close()
+ # Parse the XDG format *.desktop file, and extract the categories within it
+ desktopFile = xdg.DesktopEntry.DesktopEntry(path)
+ data['categories'] = { None: desktopFile.getCategories() }
+
+ # Try to figure out the source repository
+ if arguments.source and os.path.exists(os.path.join(arguments.source, '.git')):
+ output = subprocess.check_output('git remote show -n origin', shell=True, cwd = arguments.source).decode('utf-8')
+ result = re.search(' Fetch URL: (.*)\n', output)
+ data['source-repo'] = result.group(1)
+
+ # write meta data
+ createFastlaneFile( applicationName, "title.txt", data['name'] )
+ createFastlaneFile( applicationName, "short_description.txt", data['summary'] )
+ createFastlaneFile( applicationName, "full_description.txt", data['description'] )
+ createYml(applicationName, data)
+ downloadScreenshots(applicationName, data)
+ createMetadataArchive(applicationName)
+
+# Generate metadata for the given appstream and desktop files
+def processAppstreamFile(appstreamFileName, desktopFileName):
+ appstreamFile = open(appstreamFileName, "rb")
+ desktopData = None
+ if desktopFileName and os.path.exists(desktopFileName):
+ desktopFile = open(desktopFileName, "rb")
+ desktopData = desktopFile.read()
+ applicationName = os.path.basename(appstreamFileName)[:-12]
+ processAppstreamData(applicationName, appstreamFile.read(), desktopData)
+
+# scan source directory for manifests/metadata we can work with
+def scanSourceDir():
+ files = glob.iglob(arguments.source + "/**/AndroidManifest.xml*", recursive=True)
+ for file in files:
+ # third-party libraries might contain AndroidManifests which we are not interested in
+ if "3rdparty" in file:
+ continue
+
+ # find application id from manifest files
+ root = ET.parse(file)
+ appname = root.getroot().attrib['package']
+ is_app = False
+ prefix = '{http://schemas.android.com/apk/res/android}'
+ for md in root.findall("application/activity/meta-data"):
+ if md.attrib[prefix + 'name'] == 'android.app.lib_name':
+ is_app = True
+
+ if not appname or not is_app:
+ continue
+
+ # now that we have the app id, look for matching appdata/desktop files
+ appdataFiles = glob.iglob(arguments.source + "/**/" + appname + ".appdata.xml", recursive=True)
+ appdataFile = None
+ for f in appdataFiles:
+ appdataFile = f
+ break
+ if not appdataFile:
+ continue
+
+ desktopFiles = glob.iglob(arguments.source + "/**/" + appname + ".desktop", recursive=True)
+ desktopFile = None
+ for f in desktopFiles:
+ desktopFile = f
+ break
+
+ processAppstreamFile(appdataFile, desktopFile)
+
+
+### Script Commences
+
+# Parse the command line arguments we've been given
+parser = argparse.ArgumentParser(description='Generate fastlane metadata for Android apps from appstream metadata')
+parser.add_argument('--apk', type=str, required=False, help='APK file to extract metadata from')
+parser.add_argument('--appstream', type=str, required=False, help='Appstream file to extract metadata from')
+parser.add_argument('--desktop', type=str, required=False, help='Desktop file to extract additional metadata from')
+parser.add_argument('--source', type=str, required=False, help='Source directory to find metadata in')
+parser.add_argument('--output', type=str, required=True, help='Path to which the metadata output should be written to')
+arguments = parser.parse_args()
+
+# ensure the output path exists
+os.makedirs(arguments.output, exist_ok=True)
+
+# if we have an appstream file explicitly specified, let's use that one
+if arguments.appstream and os.path.exists(arguments.appstream):
+ processAppstreamFile(arguments.appstream, arguments.desktop)
+ sys.exit(0)
+
+# else, if we have an APK, try to find the appstream file in there
+# this ensures compatibility with the old metadata generation
+if arguments.apk and os.path.exists(arguments.apk):
+ processApkFile(arguments.apk)
+ sys.exit(0)
+
+# else, look in the source dir for appstream/desktop files
+# this follows roughly what get-apk-args from binary factory does
+if arguments.source and os.path.exists(arguments.source):
+ scanSourceDir()
+ sys.exit(0)
+
+# else: missing arguments
+print("Either one of --appstream, --apk or --source have to be provided!")
+sys.exit(1)
diff --git a/toolchain/specifydependencies.cmake b/toolchain/specifydependencies.cmake
index d21250c1..69a7f534 100644
--- a/toolchain/specifydependencies.cmake
+++ b/toolchain/specifydependencies.cmake
@@ -1,25 +1,31 @@
-execute_process(COMMAND readelf --wide --dynamic ${TARGET} ERROR_VARIABLE readelf_errors OUTPUT_VARIABLE out RESULT_VARIABLE result)
-if (NOT result EQUAL 0)
- message(FATAL_ERROR "readelf failed on ${TARGET} exit(${result}): ${readelf_errors}")
-endif()
+function(list_dependencies target libs)
+ execute_process(COMMAND readelf --wide --dynamic ${target} ERROR_VARIABLE readelf_errors OUTPUT_VARIABLE out RESULT_VARIABLE result)
-string(REPLACE "\n" ";" lines "${out}")
-set(extralibs)
-foreach(line ${lines})
- string(REGEX MATCH ".*\\(NEEDED\\) +Shared library: +\\[(.+)\\]$" matched ${line})
- set(currentLib ${CMAKE_MATCH_1})
+ if (NOT result EQUAL 0)
+ message(FATAL_ERROR "readelf failed on ${target} exit(${result}): ${readelf_errors}")
+ endif()
- if(NOT ${currentLib} MATCHES "libQt5.*" AND matched)
- find_file(ourlib-${currentLib} ${currentLib} HINTS ${OUTPUT_DIR} ${EXPORT_DIR} ${ECM_ADDITIONAL_FIND_ROOT_PATH} NO_DEFAULT_PATH PATH_SUFFIXES lib)
+ string(REPLACE "\n" ";" lines "${out}")
+ set(extralibs ${${libs}})
+ foreach(line ${lines})
+ string(REGEX MATCH ".*\\(NEEDED\\) +Shared library: +\\[(.+)\\]$" matched ${line})
+ set(currentLib ${CMAKE_MATCH_1})
- if(ourlib-${currentLib})
- list(APPEND extralibs "${ourlib-${currentLib}}")
- else()
- message(STATUS "could not find ${currentLib} in ${OUTPUT_DIR} ${EXPORT_DIR}/lib/ ${ECM_ADDITIONAL_FIND_ROOT_PATH}")
+ if(NOT ${currentLib} MATCHES "libQt5.*" AND matched)
+ find_file(ourlib-${currentLib} ${currentLib} HINTS ${OUTPUT_DIR} ${EXPORT_DIR} ${ECM_ADDITIONAL_FIND_ROOT_PATH} NO_DEFAULT_PATH PATH_SUFFIXES lib)
+
+ if(ourlib-${currentLib})
+ list(APPEND extralibs "${ourlib-${currentLib}}")
+ else()
+ message(STATUS "could not find ${currentLib} in ${OUTPUT_DIR} ${EXPORT_DIR}/lib/ " ${ECM_ADDITIONAL_FIND_ROOT_PATH})
+ endif()
endif()
- endif()
-endforeach()
+ endforeach()
+ set(${libs} ${extralibs} PARENT_SCOPE)
+endfunction()
+
+list_dependencies(${TARGET} extralibs)
function(contains_library libpath IS_EQUAL)
get_filename_component (name ${libpath} NAME)
@@ -47,23 +53,29 @@ if (ANDROID_EXTRA_LIBS)
endforeach()
endif()
-if(extralibs)
- string(REPLACE ";" "," libs "${extralibs}")
- set(extralibs "\"android-extra-libs\": \"${libs}\",")
-endif()
-
set(extraplugins)
-foreach(folder "share" "lib/qml") #now we check for folders with extra stuff
+foreach(folder "plugins" "share" "lib/qml") #now we check for folders with extra stuff
set(plugin "${EXPORT_DIR}/${folder}")
if(EXISTS "${plugin}")
- if(extraplugins)
- set(extraplugins "${extraplugins},${plugin}")
- else()
- set(extraplugins "${plugin}")
- endif()
+ list(APPEND extraplugins "${plugin}")
endif()
endforeach()
+
+if(EXISTS "module-plugins")
+ file(READ "module-plugins" moduleplugins)
+ foreach(module ${moduleplugins})
+ list_dependencies(${module} extralibs)
+ endforeach()
+ list(REMOVE_DUPLICATES extralibs)
+endif()
+
+if(extralibs)
+ string(REPLACE ";" "," extralibs "${extralibs}")
+ set(extralibs "\"android-extra-libs\": \"${extralibs}\",")
+endif()
+
if(extraplugins)
+ string(REPLACE ";" "," extraplugins "${extraplugins}")
set(extraplugins "\"android-extra-plugins\": \"${extraplugins}\",")
endif()
@@ -73,9 +85,18 @@ file(READ "stl" stl_contents)
file(READ "ranlib" ranlib_contents)
string(REGEX MATCH ".+/toolchains/(.+)-([^\\-]+)/prebuilt/.*/bin/(.*)-ranlib" x ${ranlib_contents})
-string(REPLACE "##ANDROID_TOOL_PREFIX##" "${CMAKE_MATCH_1}" NEWCONTENTS "${CONTENTS}")
-string(REPLACE "##ANDROID_TOOLCHAIN_VERSION##" "${CMAKE_MATCH_2}" NEWCONTENTS "${NEWCONTENTS}")
-string(REPLACE "##ANDROID_COMPILER_PREFIX##" "${CMAKE_MATCH_3}" NEWCONTENTS "${NEWCONTENTS}")
+if (USE_LLVM)
+ string(REPLACE "##ANDROID_TOOL_PREFIX##" "llvm" NEWCONTENTS "${CONTENTS}")
+ string(REPLACE "##ANDROID_COMPILER_PREFIX##" "llvm" NEWCONTENTS "${NEWCONTENTS}")
+ string(REPLACE "##USE_LLVM##" true NEWCONTENTS "${NEWCONTENTS}")
+else()
+ string(REPLACE "##ANDROID_TOOL_PREFIX##" "${CMAKE_MATCH_1}" NEWCONTENTS "${CONTENTS}")
+ string(REPLACE "##ANDROID_COMPILER_PREFIX##" "${CMAKE_MATCH_3}" NEWCONTENTS "${NEWCONTENTS}")
+ string(REPLACE "##USE_LLVM##" false NEWCONTENTS "${NEWCONTENTS}")
+endif()
+
+string(REPLACE "##ANDROID_TOOLCHAIN_VERSION##" "${CMAKE_MATCH_2}" NEWCONTENTS "${NEWCONTENTS}") # not used when USE_LLVM is set
+
string(REPLACE "##EXTRALIBS##" "${extralibs}" NEWCONTENTS "${NEWCONTENTS}")
string(REPLACE "##EXTRAPLUGINS##" "${extraplugins}" NEWCONTENTS "${NEWCONTENTS}")
string(REPLACE "##CMAKE_CXX_STANDARD_LIBRARIES##" "${stl_contents}" NEWCONTENTS "${NEWCONTENTS}")