From d0911d0a92f47996fcba5520a8a91fe47e10f4a6 Mon Sep 17 00:00:00 2001 From: Joerg Bornemann Date: Wed, 26 Feb 2020 11:41:20 +0100 Subject: [PATCH] CMake: Port the 'separate_debug_info' feature For this, we have to uninline the separate_debug_info configure test, because supporting the conversion of this in configurejson2cmake is not worth the hassle. Separate debug information can be turned on for a target by calling the function qt_enable_separate_debug_info. For Qt's shared libraries and tools separate debug information is generated if the 'separate_debug_info' feature is manually turned on. Change-Id: Ic2ffc15efef3794dc0aa42f3d853ef6d651a751c Reviewed-by: Leander Beernaert Reviewed-by: Alexandru Croitor --- cmake/QtBaseGlobalTargets.cmake | 2 + cmake/QtBuild.cmake | 9 +++ cmake/QtSeparateDebugInfo.Info.plist.in | 16 ++++ cmake/QtSeparateDebugInfo.cmake | 73 +++++++++++++++++++ .../separate_debug_info/CMakeLists.txt | 10 +++ config.tests/separate_debug_info/main.cpp | 1 + .../separate_debug_info.pro | 7 ++ configure.cmake | 10 +++ configure.json | 12 +-- util/cmake/configurejson2cmake.py | 2 - 10 files changed, 129 insertions(+), 13 deletions(-) create mode 100644 cmake/QtSeparateDebugInfo.Info.plist.in create mode 100644 cmake/QtSeparateDebugInfo.cmake create mode 100644 config.tests/separate_debug_info/CMakeLists.txt create mode 100644 config.tests/separate_debug_info/main.cpp create mode 100644 config.tests/separate_debug_info/separate_debug_info.pro diff --git a/cmake/QtBaseGlobalTargets.cmake b/cmake/QtBaseGlobalTargets.cmake index a788392bad..32f0fa8c5f 100644 --- a/cmake/QtBaseGlobalTargets.cmake +++ b/cmake/QtBaseGlobalTargets.cmake @@ -234,6 +234,8 @@ qt_copy_or_install(FILES cmake/QtPlatformSupport.cmake cmake/QtPlatformAndroid.cmake cmake/QtPostProcess.cmake + cmake/QtSeparateDebugInfo.Info.plist.in + cmake/QtSeparateDebugInfo.cmake cmake/QtSetup.cmake cmake/QtModuleConfig.cmake.in cmake/QtModuleDependencies.cmake.in diff --git a/cmake/QtBuild.cmake b/cmake/QtBuild.cmake index 8de0abf25f..defbe066d3 100644 --- a/cmake/QtBuild.cmake +++ b/cmake/QtBuild.cmake @@ -1,4 +1,5 @@ include(CMakePackageConfigHelpers) +include(QtSeparateDebugInfo) # Install locations: set(INSTALL_BINDIR "bin" CACHE STRING "Executables [PREFIX/bin]") @@ -1611,6 +1612,10 @@ function(qt_add_module target) endif() endif() + if(QT_FEATURE_separate_debug_info AND is_shared_lib AND (UNIX OR MINGW)) + qt_enable_separate_debug_info(${target} ${INSTALL_LIBDIR}) + endif() + if (ANDROID) qt_android_apply_arch_suffix("${target}") endif() @@ -3339,6 +3344,10 @@ function(qt_add_tool name) EXPORT "${INSTALL_CMAKE_NAMESPACE}${arg_TOOLS_TARGET}ToolsTargets" DESTINATION ${INSTALL_TARGETS_DEFAULT_ARGS}) endif() + + if(QT_FEATURE_separate_debug_info AND (UNIX OR MINGW)) + qt_enable_separate_debug_info(${name} ${INSTALL_BINDIR}) + endif() endfunction() function(qt_create_tracepoints name tracePointsFile) diff --git a/cmake/QtSeparateDebugInfo.Info.plist.in b/cmake/QtSeparateDebugInfo.Info.plist.in new file mode 100644 index 0000000000..d3e8dfbe7f --- /dev/null +++ b/cmake/QtSeparateDebugInfo.Info.plist.in @@ -0,0 +1,16 @@ + + + + + CFBundleIdentifier + com.apple.xcode.dsym.${BUNDLE_ID} + CFBundlePackageType + dSYM + CFBundleSignature + ???? + CFBundleShortVersionString + ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR} + CFBundleVersion + ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} + + diff --git a/cmake/QtSeparateDebugInfo.cmake b/cmake/QtSeparateDebugInfo.cmake new file mode 100644 index 0000000000..5e71775431 --- /dev/null +++ b/cmake/QtSeparateDebugInfo.cmake @@ -0,0 +1,73 @@ +include(CMakeFindBinUtils) + +set(QtSeparateDebugInfo_cmake_DIR ${CMAKE_CURRENT_LIST_DIR}) + +# Enable separate debug information for the given target +function(qt_enable_separate_debug_info target installDestination) + unset(commands) + if(APPLE) + find_program(DSYMUTIL_PROGRAM dsymutil) + set(copy_bin ${DSYMUTIL_PROGRAM}) + set(strip_bin ${CMAKE_STRIP}) + set(debug_info_suffix dSYM) + set(copy_bin_out_arg --flat -o) + set(strip_args -S) + else() + set(copy_bin ${CMAKE_OBJCOPY}) + set(strip_bin ${CMAKE_OBJCOPY}) + if(QNX) + set(debug_info_suffix sym) + set(debug_info_keep --keep-file-symbols) + set(strip_args "--strip-debug -R.ident") + else() + set(debug_info_suffix debug) + set(debug_info_keep --only-keep-debug) + set(strip_args --strip-debug) + endif() + endif() + if(APPLE) + get_target_property(is_framework ${target} FRAMEWORK) + if(is_framework) + set(debug_info_bundle_dir "$.${debug_info_suffix}") + set(BUNDLE_ID Qt${target}) + else() + set(debug_info_bundle_dir "$.${debug_info_suffix}") + set(BUNDLE_ID ${target}) + endif() + set(debug_info_contents_dir "${debug_info_bundle_dir}/Contents") + set(debug_info_target_dir "${debug_info_contents_dir}/Resources/DWARF") + configure_file( + "${QtSeparateDebugInfo_cmake_DIR}/QtSeparateDebugInfo.Info.plist.in" + "Info.dSYM.plist" + ) + list(APPEND commands + COMMAND ${CMAKE_COMMAND} -E make_directory ${debug_info_target_dir} + COMMAND ${CMAKE_COMMAND} -E copy "Info.dSYM.plist" "${debug_info_contents_dir}/Info.plist" + ) + set(debug_info_target "${debug_info_target_dir}/$") + qt_install(DIRECTORY ${debug_info_bundle_dir} DESTINATION ${installDestination}) + else() + set(debug_info_target "$/$.${debug_info_suffix}") + qt_install(FILES ${debug_info_target} DESTINATION ${installDestination}) + endif() + list(APPEND commands + COMMAND ${copy_bin} ${debug_info_keep} $ + ${copy_bin_out_arg} ${debug_info_target} + COMMAND ${strip_bin} ${strip_args} $ + ) + if(NOT APPLE) + list(APPEND commands + COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=${debug_info_target} $ + ) + endif() + if(NOT CMAKE_HOST_WIN32) + list(APPEND commands + COMMAND chmod -x ${debug_info_target} + ) + endif() + add_custom_command( + TARGET ${target} + POST_BUILD + ${commands} + ) +endfunction() diff --git a/config.tests/separate_debug_info/CMakeLists.txt b/config.tests/separate_debug_info/CMakeLists.txt new file mode 100644 index 0000000000..757374a34a --- /dev/null +++ b/config.tests/separate_debug_info/CMakeLists.txt @@ -0,0 +1,10 @@ +cmake_minimum_required(VERSION 3.14.0) +project(objcopytest LANGUAGES CXX) +include(CMakeFindBinUtils) +add_executable(objcopytest main.cpp) +add_custom_command( + TARGET objcopytest + POST_BUILD + COMMAND ${CMAKE_OBJCOPY} --only-keep-debug $ objcopytest.debug + COMMAND ${CMAKE_OBJCOPY} --strip-debug $ + COMMAND ${CMAKE_OBJCOPY} --add-gnu-debuglink=objcopytest.debug $) diff --git a/config.tests/separate_debug_info/main.cpp b/config.tests/separate_debug_info/main.cpp new file mode 100644 index 0000000000..237c8ce181 --- /dev/null +++ b/config.tests/separate_debug_info/main.cpp @@ -0,0 +1 @@ +int main() {} diff --git a/config.tests/separate_debug_info/separate_debug_info.pro b/config.tests/separate_debug_info/separate_debug_info.pro new file mode 100644 index 0000000000..577aa734d6 --- /dev/null +++ b/config.tests/separate_debug_info/separate_debug_info.pro @@ -0,0 +1,7 @@ +TARGET = objcopytest +SOURCES += main.cpp +load(resolve_target) +QMAKE_POST_LINK += \ + $$QMAKE_OBJCOPY --only-keep-debug $$QMAKE_RESOLVED_TARGET objcopytest.debug && \ + $$QMAKE_OBJCOPY --strip-debug $$QMAKE_RESOLVED_TARGET && \ + $$QMAKE_OBJCOPY --add-gnu-debuglink=objcopytest.debug $$QMAKE_RESOLVED_TARGET diff --git a/configure.cmake b/configure.cmake index 2fc01379fa..5701bcef4b 100644 --- a/configure.cmake +++ b/configure.cmake @@ -127,6 +127,10 @@ int main(int argc, char **argv) "# FIXME: qmake: ['TEMPLATE = lib', 'CONFIG += dll bsymbolic_functions', 'isEmpty(QMAKE_LFLAGS_BSYMBOLIC_FUNC): error("Nope")'] ) + +qt_config_compile_test("separate_debug_info" + LABEL "separate debug information support" + PROJECT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/config.tests/separate_debug_info") # signaling_nan qt_config_compile_test(signaling_nan LABEL "Signaling NaN for doubles" @@ -367,6 +371,12 @@ qt_feature("force_debug_info" AUTODETECT CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo OR RelWithDebInfo IN_LIST CMAKE_CONFIGURATION_TYPES ) qt_feature_config("force_debug_info" QMAKE_PRIVATE_CONFIG) +qt_feature("separate_debug_info" PUBLIC + LABEL "Split off debug information" + AUTODETECT OFF + CONDITION ( QT_FEATURE_shared ) AND ( QT_FEATURE_debug OR QT_FEATURE_debug_and_release OR QT_FEATURE_force_debug_info ) AND ( APPLE OR TEST_separate_debug_info ) +) +qt_feature_config("separate_debug_info" QMAKE_PUBLIC_QT_CONFIG) qt_feature("appstore-compliant" PUBLIC LABEL "App store compliance" PURPOSE "Disables code that is not allowed in platform app stores" diff --git a/configure.json b/configure.json index cf123602c2..bb4813e308 100644 --- a/configure.json +++ b/configure.json @@ -460,17 +460,7 @@ }, "separate_debug_info": { "label": "separate debug information support", - "type": "compile", - "test": { - "qmake": [ - "TARGET = objcopytest", - "load(resolve_target)", - "QMAKE_POST_LINK += \\", - " $$QMAKE_OBJCOPY --only-keep-debug $$QMAKE_RESOLVED_TARGET objcopytest.debug && \\", - " $$QMAKE_OBJCOPY --strip-debug $$QMAKE_RESOLVED_TARGET && \\", - " $$QMAKE_OBJCOPY --add-gnu-debuglink=objcopytest.debug $$QMAKE_RESOLVED_TARGET" - ] - } + "type": "compile" }, "gc_binaries": { "label": "support for split sections and linker garbage collection", diff --git a/util/cmake/configurejson2cmake.py b/util/cmake/configurejson2cmake.py index b024c76459..ad183c1906 100755 --- a/util/cmake/configurejson2cmake.py +++ b/util/cmake/configurejson2cmake.py @@ -696,7 +696,6 @@ def parseTest(ctx, test, data, cm_fh): "sun-iconv", "precomile_header", "reduce_exports", - "separate_debug_info", # FIXME: see if cmake can do this "gc_binaries", "libinput_axis_api", "wayland-scanner", @@ -827,7 +826,6 @@ def parseFeature(ctx, feature, data, cm_fh): "sanitizer": None, "sanitize_thread": None, "sanitize_undefined": None, - "separate_debug_info": None, "shared": {"condition": "BUILD_SHARED_LIBS"}, "silent": None, "sql-sqlite": {"condition": "QT_FEATURE_datestring AND SQLite3_FOUND"},