From 90aeb4c8d9835d31c4247bb92ca63ed153907d50 Mon Sep 17 00:00:00 2001 From: Stefan Granitz Date: Fri, 4 Jan 2019 12:46:30 +0000 Subject: [PATCH] [CMake] Streamline code signing for debugserver #2 Summary: Major fixes after D54476 (use Diff1 as base for comparison to see only recent changes): * In standalone builds target directory for debugserver must be LLDB's bin, not LLVM's bin * Default identity for code signing must not force-override LLVM_CODESIGNING_IDENTITY globally We have a lot of cases, make them explicit: * ID used for code signing (debugserver and in tests): ** `LLDB_CODESIGN_IDENTITY` if set explicitly, or otherwise ** `LLVM_CODESIGNING_IDENTITY` if set explicitly, or otherwise ** `lldb_codesign` as the default * On Darwin we have a debugserver target that: * On other systems, the debugserver target is not defined, which is equivalent to **[3A]** Common configurations on Darwin: * **[1A]** `cmake -GNinja ../llvm` builds debugserver from source and signs with `lldb_codesign`, no code signing for other binaries (prints status: //lldb debugserver: /path/to/bin/debugserver//) * **[1A]** `cmake -GNinja -DLLVM_CODESIGNING_IDENTITY=- -DLLDB_CODESIGN_IDENTITY=lldb_codesign ../llvm` builds debugserver from source and signs with `lldb_codesign`, ad-hoc code signing for other binaries (prints status: //lldb debugserver: /path/to/bin/debugserver//) * **[2A]** `cmake -GNinja -DLLVM_CODESIGNING_IDENTITY=- -DLLDB_USE_SYSTEM_DEBUGSERVER=ON ../llvm` copies debugserver from system, ad-hoc code signing for other binaries (prints status: //Copy system debugserver from: /path/to/system/debugserver//) * **[2B]** `cmake -GNinja -DLLVM_CODESIGNING_IDENTITY=- ../llvm` same, but prints additional warning: //Cannot code sign debugserver with identity '-'. Will fall back to system's debugserver. Pass -DLLDB_CODESIGN_IDENTITY=lldb_codesign to override the LLVM value for debugserver.// * **[3A]** `cmake -GNinja -DLLVM_CODESIGNING_IDENTITY=- -DLLDB_NO_DEBUGSERVER=ON ../llvm` debugserver not available (prints status: //lldb debugserver will not be available)// Reviewers: JDevlieghere, beanz, davide, vsk, aprantl, labath Reviewed By: JDevlieghere, labath Subscribers: mgorny, #lldb, lldb-commits Differential Revision: https://reviews.llvm.org/D55013 llvm-svn: 350388 --- lldb/CMakeLists.txt | 4 +- lldb/cmake/modules/AddLLDB.cmake | 4 +- lldb/cmake/modules/LLDBConfig.cmake | 2 + lldb/test/CMakeLists.txt | 8 +- lldb/tools/debugserver/CMakeLists.txt | 2 + lldb/tools/debugserver/source/CMakeLists.txt | 199 +++++++++++------- lldb/unittests/tools/CMakeLists.txt | 2 +- .../tools/lldb-server/CMakeLists.txt | 2 +- 8 files changed, 140 insertions(+), 83 deletions(-) diff --git a/lldb/CMakeLists.txt b/lldb/CMakeLists.txt index 48751ec834e0..e0af678cbfbb 100644 --- a/lldb/CMakeLists.txt +++ b/lldb/CMakeLists.txt @@ -138,9 +138,7 @@ if(LLDB_INCLUDE_TESTS) endif() if(TARGET debugserver) - if(NOT CMAKE_HOST_APPLE OR LLDB_CODESIGN_IDENTITY) - list(APPEND LLDB_TEST_DEPS debugserver) - endif() + list(APPEND LLDB_TEST_DEPS debugserver) endif() if(TARGET lldb-mi) diff --git a/lldb/cmake/modules/AddLLDB.cmake b/lldb/cmake/modules/AddLLDB.cmake index 0e26db55e970..89f59568fe71 100644 --- a/lldb/cmake/modules/AddLLDB.cmake +++ b/lldb/cmake/modules/AddLLDB.cmake @@ -100,13 +100,13 @@ endfunction(add_lldb_library) function(add_lldb_executable name) cmake_parse_arguments(ARG "INCLUDE_IN_SUITE;GENERATE_INSTALL" - "" + "ENTITLEMENTS" "LINK_LIBS;LINK_COMPONENTS" ${ARGN} ) list(APPEND LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS}) - add_llvm_executable(${name} ${ARG_UNPARSED_ARGUMENTS}) + add_llvm_executable(${name} ${ARG_UNPARSED_ARGUMENTS} ENTITLEMENTS ${ARG_ENTITLEMENTS}) target_link_libraries(${name} PRIVATE ${ARG_LINK_LIBS}) set_target_properties(${name} PROPERTIES diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake index 98710f13b7bd..fc3913943e73 100644 --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -50,6 +50,8 @@ if (LLDB_DISABLE_CURSES) add_definitions( -DLLDB_DISABLE_CURSES ) endif() +option(LLDB_USE_ENTITLEMENTS "When code signing, use entitlements if available" ON) + # On Windows, we can't use the normal FindPythonLibs module that comes with CMake, # for a number of reasons. # 1) Prior to MSVC 2015, it is only possible to embed Python if python itself was diff --git a/lldb/test/CMakeLists.txt b/lldb/test/CMakeLists.txt index bf7b21e5d870..2efd99acc449 100644 --- a/lldb/test/CMakeLists.txt +++ b/lldb/test/CMakeLists.txt @@ -74,8 +74,8 @@ if ( CMAKE_SYSTEM_NAME MATCHES "Windows" ) endif() endif() -if(LLDB_CODESIGN_IDENTITY) - list(APPEND LLDB_TEST_COMMON_ARGS --codesign-identity "${LLDB_CODESIGN_IDENTITY}") +if(LLDB_CODESIGN_IDENTITY_USED) + list(APPEND LLDB_TEST_COMMON_ARGS --codesign-identity "${LLDB_CODESIGN_IDENTITY_USED}") endif() if(LLDB_BUILD_FRAMEWORK) @@ -93,11 +93,11 @@ if (NOT "${LLDB_LIT_TOOLS_DIR}" STREQUAL "") endif() endif() -if(CMAKE_HOST_APPLE) +if(CMAKE_HOST_APPLE AND DEBUGSERVER_PATH) list(APPEND LLDB_TEST_COMMON_ARGS --server ${DEBUGSERVER_PATH}) endif() -if(SKIP_DEBUGSERVER) +if(SKIP_TEST_DEBUGSERVER) list(APPEND LLDB_TEST_COMMON_ARGS --out-of-tree-debugserver) endif() diff --git a/lldb/tools/debugserver/CMakeLists.txt b/lldb/tools/debugserver/CMakeLists.txt index 58231582909e..53f89fd5bdad 100644 --- a/lldb/tools/debugserver/CMakeLists.txt +++ b/lldb/tools/debugserver/CMakeLists.txt @@ -15,6 +15,8 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) set(LLDB_SOURCE_DIR "${CMAKE_SOURCE_DIR}/../../") include_directories(${LLDB_SOURCE_DIR}/include) + option(LLDB_USE_ENTITLEMENTS "When code signing, use entitlements if available" ON) + # lldb-suite is a dummy target that encompasses all the necessary tools and # libraries for building a fully-functioning liblldb. add_custom_target(lldb-suite) diff --git a/lldb/tools/debugserver/source/CMakeLists.txt b/lldb/tools/debugserver/source/CMakeLists.txt index 16369e46e547..d82178bd39ba 100644 --- a/lldb/tools/debugserver/source/CMakeLists.txt +++ b/lldb/tools/debugserver/source/CMakeLists.txt @@ -94,32 +94,121 @@ set(lldbDebugserverCommonSources add_library(lldbDebugserverCommon ${lldbDebugserverCommonSources}) +# LLDB-specific identity, currently used for code signing debugserver. +set(LLDB_CODESIGN_IDENTITY "" CACHE STRING + "Override code sign identity for debugserver and for use in tests; falls back to LLVM_CODESIGNING_IDENTITY if set or lldb_codesign otherwise (Darwin only)") -set(LLDB_CODESIGN_IDENTITY "lldb_codesign" - CACHE STRING "Identity used for code signing. Set to empty string to skip the signing step.") - -if(NOT LLDB_CODESIGN_IDENTITY STREQUAL "") - set(DEBUGSERVER_PATH ${LLVM_RUNTIME_OUTPUT_INTDIR}/debugserver${CMAKE_EXECUTABLE_SUFFIX} CACHE PATH "Path to debugserver.") - set(SKIP_DEBUGSERVER OFF CACHE BOOL "Skip building the in-tree debug server") +# Determine which identity to use and store it in the separate cache entry. +# We will query it later for LLDB_TEST_COMMON_ARGS. +if(LLDB_CODESIGN_IDENTITY) + set(LLDB_CODESIGN_IDENTITY_USED ${LLDB_CODESIGN_IDENTITY} CACHE INTERNAL "" FORCE) +elseif(LLVM_CODESIGNING_IDENTITY) + set(LLDB_CODESIGN_IDENTITY_USED ${LLVM_CODESIGNING_IDENTITY} CACHE INTERNAL "" FORCE) else() + set(LLDB_CODESIGN_IDENTITY_USED lldb_codesign CACHE INTERNAL "" FORCE) +endif() + +# Override locally, so the identity is used for targets created in this scope. +set(LLVM_CODESIGNING_IDENTITY ${LLDB_CODESIGN_IDENTITY_USED}) + +option(LLDB_NO_DEBUGSERVER "Disable the debugserver target" OFF) +option(LLDB_USE_SYSTEM_DEBUGSERVER "Use the system's debugserver instead of building it from source (Darwin only)." OFF) + +# Incompatible options +if(LLDB_NO_DEBUGSERVER AND LLDB_USE_SYSTEM_DEBUGSERVER) + message(FATAL_ERROR "Inconsistent options: LLDB_NO_DEBUGSERVER and LLDB_USE_SYSTEM_DEBUGSERVER") +endif() + +# Try to locate the system debugserver. +# Subsequent feasibility checks depend on it. +if(APPLE AND CMAKE_HOST_APPLE) execute_process( COMMAND xcode-select -p - OUTPUT_VARIABLE XCODE_DEV_DIR) - string(STRIP ${XCODE_DEV_DIR} XCODE_DEV_DIR) - if(EXISTS "${XCODE_DEV_DIR}/../SharedFrameworks/LLDB.framework/") - set(DEBUGSERVER_PATH - "${XCODE_DEV_DIR}/../SharedFrameworks/LLDB.framework/Resources/debugserver" CACHE PATH "Path to debugserver.") - elseif(EXISTS "${XCODE_DEV_DIR}/Library/PrivateFrameworks/LLDB.framework/") - set(DEBUGSERVER_PATH - "${XCODE_DEV_DIR}/Library/PrivateFrameworks/LLDB.framework/Resources/debugserver" CACHE PATH "Path to debugserver.") - else() - message(SEND_ERROR "Cannot find debugserver on system.") - endif() - set(SKIP_DEBUGSERVER ON CACHE BOOL "Skip building the in-tree debug server") -endif() -message(STATUS "Path to the lldb debugserver: ${DEBUGSERVER_PATH}") + OUTPUT_VARIABLE xcode_dev_dir) + string(STRIP ${xcode_dev_dir} xcode_dev_dir) -if (APPLE) + set(debugserver_rel_path "LLDB.framework/Resources/debugserver") + set(debugserver_shared "${xcode_dev_dir}/../SharedFrameworks/${debugserver_rel_path}") + set(debugserver_private "${xcode_dev_dir}/Library/PrivateFrameworks/${debugserver_rel_path}") + + if(EXISTS ${debugserver_shared}) + set(system_debugserver ${debugserver_shared}) + elseif(EXISTS ${debugserver_private}) + set(system_debugserver ${debugserver_private}) + endif() +endif() + +# Handle unavailability +if(LLDB_USE_SYSTEM_DEBUGSERVER) + if(system_debugserver) + set(use_system_debugserver ON) + elseif(APPLE AND CMAKE_HOST_APPLE) + # Binary not found on system. Keep cached variable, to try again on reconfigure. + message(SEND_ERROR + "LLDB_USE_SYSTEM_DEBUGSERVER option set, but no debugserver found in:\ + ${debugserver_shared}\ + ${debugserver_private}") + else() + # Non-Apple target platform or non-Darwin host. Reset invalid cached variable. + message(WARNING "Reverting invalid option LLDB_USE_SYSTEM_DEBUGSERVER (Darwin only)") + set(LLDB_USE_SYSTEM_DEBUGSERVER OFF CACHE BOOL "" FORCE) + endif() +elseif(NOT LLDB_NO_DEBUGSERVER) + # Default case: on Darwin we need the right code signing ID. + # See lldb/docs/code-signing.txt for details. + if(CMAKE_HOST_APPLE AND NOT LLVM_CODESIGNING_IDENTITY STREQUAL "lldb_codesign") + set(problem "Cannot code sign debugserver with LLVM_CODESIGNING_IDENTITY '${LLVM_CODESIGNING_IDENTITY}'.") + set(advice "Pass -DLLDB_CODESIGN_IDENTITY=lldb_codesign to override the LLVM value for debugserver.") + if(system_debugserver) + set(effect "Will fall back to system's debugserver.") + set(use_system_debugserver ON) + else() + set(effect "debugserver will not be available.") + endif() + message(WARNING "${problem} ${effect} ${advice}") + else() + set(build_and_sign_debugserver ON) + endif() +endif() + +# TODO: We don't use the $ generator expression here, +# because the value of DEBUGSERVER_PATH is used to build LLDB_DOTEST_ARGS, +# which is used for configuring lldb-dotest.in, which does not have a generator +# step at the moment. +set(default_debugserver_path "${LLVM_RUNTIME_OUTPUT_INTDIR}/debugserver${CMAKE_EXECUTABLE_SUFFIX}") + +# Remember where debugserver binary goes and whether or not we have to test it. +set(DEBUGSERVER_PATH "" CACHE FILEPATH "Path to debugserver") +set(SKIP_TEST_DEBUGSERVER OFF CACHE BOOL "Building the in-tree debugserver was skipped") + +# Reset values in all cases in order to correctly support reconfigurations. +if(use_system_debugserver) + add_custom_target(debugserver + COMMAND ${CMAKE_COMMAND} -E copy_if_different + ${system_debugserver} ${LLVM_RUNTIME_OUTPUT_INTDIR} + COMMENT "Copying the system debugserver to LLDB's binaries directory.") + + # Don't test debugserver itself. + # Tests that require debugserver will use the copy. + set(DEBUGSERVER_PATH ${default_debugserver_path} CACHE FILEPATH "" FORCE) + set(SKIP_TEST_DEBUGSERVER ON CACHE BOOL "" FORCE) + + message(STATUS "Copy system debugserver from: ${system_debugserver}") +elseif(build_and_sign_debugserver) + # Build, sign and test debugserver (below) + set(DEBUGSERVER_PATH ${default_debugserver_path} CACHE FILEPATH "" FORCE) + set(SKIP_TEST_DEBUGSERVER OFF CACHE BOOL "" FORCE) + + message(STATUS "lldb debugserver: ${DEBUGSERVER_PATH}") +else() + # No tests for debugserver, no tests that require it. + set(DEBUGSERVER_PATH "" CACHE FILEPATH "" FORCE) + set(SKIP_TEST_DEBUGSERVER ON CACHE BOOL "" FORCE) + + message(STATUS "lldb debugserver will not be available.") +endif() + +if(APPLE) if(IOS) find_library(BACKBOARD_LIBRARY BackBoardServices PATHS ${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks) @@ -132,7 +221,7 @@ if (APPLE) find_library(LOCKDOWN_LIBRARY lockdown) if(NOT BACKBOARD_LIBRARY) - set(SKIP_DEBUGSERVER ON CACHE BOOL "Skip building the in-tree debug server" FORCE) + set(SKIP_TEST_DEBUGSERVER ON CACHE BOOL "" FORCE) endif() else() find_library(COCOA_LIBRARY Cocoa) @@ -143,7 +232,16 @@ if(HAVE_LIBCOMPRESSION) set(LIBCOMPRESSION compression) endif() -if(NOT SKIP_DEBUGSERVER) +if(LLDB_USE_ENTITLEMENTS) + if(IOS) + set(entitlements ${CMAKE_CURRENT_SOURCE_DIR}/debugserver-entitlements.plist) + else() + # Same entitlements file as used for lldb-server + set(entitlements ${LLDB_SOURCE_DIR}/resources/debugserver-macosx-entitlements.plist) + endif() +endif() + +if(build_and_sign_debugserver) target_link_libraries(lldbDebugserverCommon INTERFACE ${COCOA_LIBRARY} ${CORE_FOUNDATION_LIBRARY} @@ -166,6 +264,9 @@ if(NOT SKIP_DEBUGSERVER) LINK_LIBS lldbDebugserverCommon + + ENTITLEMENTS + ${entitlements} ) if(IOS) set_property(TARGET lldbDebugserverCommon APPEND PROPERTY COMPILE_DEFINITIONS @@ -203,54 +304,8 @@ if(IOS) LINK_LIBS lldbDebugserverCommon_NonUI + + ENTITLEMENTS + ${entitlements} ) endif() - -set(entitlements_xml ${CMAKE_CURRENT_SOURCE_DIR}/debugserver-macosx-entitlements.plist) -if(IOS) - set(entitlements_xml ${CMAKE_CURRENT_SOURCE_DIR}/debugserver-entitlements.plist) -else() - set(entitlements_xml ${CMAKE_CURRENT_SOURCE_DIR}/../../../resources/debugserver-macosx-entitlements.plist) -endif() - -set(LLDB_USE_ENTITLEMENTS_Default On) -option(LLDB_USE_ENTITLEMENTS "Use entitlements when codesigning (Defaults Off when using lldb_codesign identity, otherwise On)" ${LLDB_USE_ENTITLEMENTS_Default}) - -if (SKIP_DEBUGSERVER) - if (CMAKE_HOST_APPLE) - # If we haven't built a signed debugserver, copy the one from the system. - add_custom_target(debugserver - COMMAND ${CMAKE_COMMAND} -E copy_if_different ${DEBUGSERVER_PATH} ${CMAKE_BINARY_DIR}/bin - VERBATIM - COMMENT "Copying the system debugserver to LLDB's binaries directory.") - endif() -else() - if(LLDB_USE_ENTITLEMENTS) - set(entitlements_flags --entitlements ${entitlements_xml}) - endif() - execute_process( - COMMAND xcrun -f codesign_allocate - OUTPUT_STRIP_TRAILING_WHITESPACE - OUTPUT_VARIABLE CODESIGN_ALLOCATE - ) - add_custom_command(TARGET debugserver - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E env CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} - codesign --force --sign ${LLDB_CODESIGN_IDENTITY} - ${entitlements_flags} - $ - ) - if(IOS) - add_custom_command(TARGET debugserver-nonui - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E env CODESIGN_ALLOCATE=${CODESIGN_ALLOCATE} - codesign --force --sign ${LLDB_CODESIGN_IDENTITY} - ${entitlements_flags} - $ - ) - endif() -endif() - - - - diff --git a/lldb/unittests/tools/CMakeLists.txt b/lldb/unittests/tools/CMakeLists.txt index bce076ee91ec..d180ebe8987d 100644 --- a/lldb/unittests/tools/CMakeLists.txt +++ b/lldb/unittests/tools/CMakeLists.txt @@ -1,5 +1,5 @@ if(CMAKE_SYSTEM_NAME MATCHES "Android|Darwin|Linux|NetBSD") - if ((CMAKE_SYSTEM_NAME MATCHES "Darwin" AND SKIP_DEBUGSERVER) OR (NOT CMAKE_SYSTEM_NAME MATCHES "Darwin" AND SKIP_LLDB_SERVER_BUILD)) + if ((CMAKE_SYSTEM_NAME MATCHES "Darwin" AND SKIP_TEST_DEBUGSERVER) OR (NOT CMAKE_SYSTEM_NAME MATCHES "Darwin" AND SKIP_LLDB_SERVER_BUILD)) # These tests are meant to test lldb-server/debugserver in isolation, and # don't provide any value if run against a server copied from somewhere. else() diff --git a/lldb/unittests/tools/lldb-server/CMakeLists.txt b/lldb/unittests/tools/lldb-server/CMakeLists.txt index dcbd9bed529f..60616c93153f 100644 --- a/lldb/unittests/tools/lldb-server/CMakeLists.txt +++ b/lldb/unittests/tools/lldb-server/CMakeLists.txt @@ -12,7 +12,7 @@ endfunction() add_lldb_test_executable(thread_inferior inferior/thread_inferior.cpp) add_lldb_test_executable(environment_check inferior/environment_check.cpp) -if (CMAKE_SYSTEM_NAME MATCHES "Darwin") +if(DEBUGSERVER_PATH) add_definitions(-DLLDB_SERVER="${DEBUGSERVER_PATH}" -DLLDB_SERVER_IS_DEBUGSERVER=1) else() add_definitions(-DLLDB_SERVER="$" -DLLDB_SERVER_IS_DEBUGSERVER=0)