diff --git a/lldb/CMakeLists.txt b/lldb/CMakeLists.txt --- a/lldb/CMakeLists.txt +++ b/lldb/CMakeLists.txt @@ -88,10 +88,6 @@ list(APPEND LLDB_TEST_DEPS lldb-server) endif() - if(TARGET debugserver) - list(APPEND LLDB_TEST_DEPS debugserver) - endif() - if(TARGET lldb-mi) list(APPEND LLDB_TEST_DEPS lldb-mi) endif() diff --git a/lldb/cmake/modules/AddLLDB.cmake b/lldb/cmake/modules/AddLLDB.cmake --- a/lldb/cmake/modules/AddLLDB.cmake +++ b/lldb/cmake/modules/AddLLDB.cmake @@ -275,3 +275,27 @@ INSTALL_RPATH "${LIST_INSTALL_RPATH}" ) endfunction() + +function(lldb_find_system_debugserver path) + execute_process(COMMAND xcode-select -p + RESULT_VARIABLE exit_code + OUTPUT_VARIABLE xcode_dev_dir + ERROR_VARIABLE error_msg) + if(exit_code) + message(WARNING "`xcode-select -p` failed:\n${error_msg}") + else() + string(STRIP ${xcode_dev_dir} xcode_dev_dir) + set(subdir "LLDB.framework/Resources/debugserver") + set(path_shared "${xcode_dev_dir}/../SharedFrameworks/${subdir}") + set(path_private "${xcode_dev_dir}/Library/PrivateFrameworks/${subdir}") + + if(EXISTS ${path_shared}) + set(${path} ${path_shared} PARENT_SCOPE) + elseif(EXISTS ${path_private}) + set(${path} ${path_private} PARENT_SCOPE) + else() + message(WARNING "System debugserver requested, but not found. " + "Candidates don't exist: ${path_shared}\n${path_private}") + endif() + endif() +endfunction() diff --git a/lldb/cmake/modules/LLDBConfig.cmake b/lldb/cmake/modules/LLDBConfig.cmake --- a/lldb/cmake/modules/LLDBConfig.cmake +++ b/lldb/cmake/modules/LLDBConfig.cmake @@ -50,6 +50,7 @@ option(LLDB_USE_ENTITLEMENTS "When codesigning, use entitlements if available" ON) option(LLDB_BUILD_FRAMEWORK "Build LLDB.framework (Darwin only)" OFF) option(LLDB_NO_INSTALL_DEFAULT_RPATH "Disable default RPATH settings in binaries" OFF) +option(LLDB_USE_SYSTEM_DEBUGSERVER "Use the system's debugserver for testing (Darwin only)." OFF) if(LLDB_BUILD_FRAMEWORK) if(NOT APPLE) diff --git a/lldb/test/CMakeLists.txt b/lldb/test/CMakeLists.txt --- a/lldb/test/CMakeLists.txt +++ b/lldb/test/CMakeLists.txt @@ -74,15 +74,6 @@ endif() endif() -if(LLDB_CODESIGN_IDENTITY_USED) - list(APPEND LLDB_TEST_COMMON_ARGS --codesign-identity "${LLDB_CODESIGN_IDENTITY_USED}") -endif() - -if(LLDB_BUILD_FRAMEWORK) - get_target_property(framework_target_dir liblldb LIBRARY_OUTPUT_DIRECTORY) - list(APPEND LLDB_TEST_COMMON_ARGS --framework ${framework_target_dir}/LLDB.framework) -endif() - if (NOT ${CMAKE_SYSTEM_NAME} MATCHES "Windows|Darwin") list(APPEND LLDB_TEST_COMMON_ARGS --env ARCHIVER=${CMAKE_AR} --env OBJCOPY=${CMAKE_OBJCOPY}) @@ -94,12 +85,29 @@ endif() endif() -if(CMAKE_HOST_APPLE AND DEBUGSERVER_PATH) - list(APPEND LLDB_TEST_COMMON_ARGS --server ${DEBUGSERVER_PATH}) -endif() +if(CMAKE_HOST_APPLE) + if(LLDB_BUILD_FRAMEWORK) + get_target_property(framework_build_dir liblldb LIBRARY_OUTPUT_DIRECTORY) + list(APPEND LLDB_TEST_COMMON_ARGS --framework ${framework_build_dir}/LLDB.framework) + endif() + + # Use the same identity for testing + get_property(code_sign_identity_used GLOBAL PROPERTY LLDB_DEBUGSERVER_CODESIGN_IDENTITY) + if(code_sign_identity_used) + list(APPEND LLDB_TEST_COMMON_ARGS --codesign-identity "${code_sign_identity_used}") + endif() + + if(LLDB_USE_SYSTEM_DEBUGSERVER) + lldb_find_system_debugserver(debugserver_path) + message(STATUS "LLDB tests use out-of-tree debugserver: ${debugserver_path}") + list(APPEND LLDB_TEST_COMMON_ARGS --out-of-tree-debugserver) + else() + set(debugserver_path ${LLVM_RUNTIME_OUTPUT_INTDIR}/debugserver) + message(STATUS "LLDB Tests use just-built debugserver: ${debugserver_path}") + add_dependencies(lldb-test-deps debugserver) + endif() -if(SKIP_TEST_DEBUGSERVER) - list(APPEND LLDB_TEST_COMMON_ARGS --out-of-tree-debugserver) + list(APPEND LLDB_TEST_COMMON_ARGS --server ${debugserver_path}) endif() set(LLDB_DOTEST_ARGS ${LLDB_TEST_COMMON_ARGS};${LLDB_TEST_USER_ARGS}) diff --git a/lldb/tools/debugserver/source/CMakeLists.txt b/lldb/tools/debugserver/source/CMakeLists.txt --- a/lldb/tools/debugserver/source/CMakeLists.txt +++ b/lldb/tools/debugserver/source/CMakeLists.txt @@ -6,6 +6,58 @@ include_directories(MacOSX) +function(check_certificate identity result_valid) + execute_process( + COMMAND security find-certificate -Z -p -c ${identity} /Library/Keychains/System.keychain + RESULT_VARIABLE exit_code OUTPUT_QUIET ERROR_QUIET) + if(exit_code) + set(${result_valid} FALSE PARENT_SCOPE) + else() + set(${result_valid} TRUE PARENT_SCOPE) + endif() +endfunction() + +function(get_debugserver_codesign_identity result) + string(CONCAT not_found_help + "This will cause failures in the test suite." + "Pass '-DLLDB_USE_SYSTEM_DEBUGSERVER=ON' to use the system one instead." + "See 'Code Signing on macOS' in the documentation." + ) + + # Explicit override: always use it, but warn if unavailable and used for testing + if(LLDB_CODESIGN_IDENTITY) + set(${result} ${LLDB_CODESIGN_IDENTITY} PARENT_SCOPE) + check_certificate(${LLDB_CODESIGN_IDENTITY} available) + if(NOT available AND NOT LLDB_USE_SYSTEM_DEBUGSERVER) + message(WARNING "LLDB_CODESIGN_IDENTITY not found: '${LLDB_CODESIGN_IDENTITY}' ${not_found_help}") + endif() + return() + endif() + + # Development signing identity: use if available + check_certificate(lldb_codesign available) + if(available) + set(${result} lldb_codesign PARENT_SCOPE) + return() + endif() + + if(NOT LLDB_USE_SYSTEM_DEBUGSERVER) + message(WARNING "Development code sign identiy not found: 'lldb_codesign' ${not_found_help}") + endif() + + # LLVM pendant: fallback if available + if(LLVM_CODESIGNING_IDENTITY) + check_certificate(${LLVM_CODESIGNING_IDENTITY} available) + if(available) + set(${result} ${LLVM_CODESIGNING_IDENTITY} PARENT_SCOPE) + return() + endif() + endif() + + # Ad-hoc signing: last resort + set(${result} "-" PARENT_SCOPE) +endfunction() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -stdlib=libc++ -Wl,-sectcreate,__TEXT,__info_plist,${CMAKE_CURRENT_SOURCE_DIR}/../resources/lldb-debugserver-Info.plist") check_cxx_compiler_flag("-Wno-gnu-zero-variadic-macro-arguments" @@ -30,132 +82,17 @@ add_subdirectory(MacOSX) -# 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)") - -# 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() + "Identity override for debugserver; see 'Code Signing on macOS' in the documentation (Darwin only)") -# 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) +get_debugserver_codesign_identity(debugserver_codesign_identity) -# 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) - - 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") - message(WARNING "Codesigning debugserver with identity ${LLVM_CODESIGNING_IDENTITY}. " - "The usual setup uses the \"lldb_codesign\" identity created with " - "scripts/macos-setup-codesign.sh. As a result your debugserver might " - "not be able to attach to processes.\n" - "Pass -DLLDB_CODESIGN_IDENTITY=lldb_codesign to use the development " - "signing identity.") - endif() - set(build_and_sign_debugserver ON) -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.") - - set_target_properties(debugserver PROPERTIES FOLDER "lldb libraries/debugserver") - - # 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() +# Override locally, so the identity is used for targets created in this scope. +set(LLVM_CODESIGNING_IDENTITY ${debugserver_codesign_identity}) -# On MacOS, debugserver needs to be codesigned when built. Check if we have -# a certificate instead of failing in the middle of the build. -if(build_and_sign_debugserver) - execute_process( - COMMAND security find-certificate -Z -p -c ${LLDB_CODESIGN_IDENTITY_USED} /Library/Keychains/System.keychain - RESULT_VARIABLE cert_return - OUTPUT_QUIET - ERROR_QUIET) - - if (cert_return) - message(FATAL_ERROR "Certificate for debugserver not found. Run scripts/macos-setup-codesign.sh or " - "use the system debugserver passing -DLLDB_USE_SYSTEM_DEBUGSERVER=ON to CMake") - endif() -endif() +# Use the same identity later in the test suite. +set_property(GLOBAL PROPERTY + LLDB_DEBUGSERVER_CODESIGN_IDENTITY ${debugserver_codesign_identity}) if(APPLE) if(IOS) @@ -190,7 +127,7 @@ endif() endif() -if(build_and_sign_debugserver) +#if(build_and_sign_debugserver) set(generated_mach_interfaces ${CMAKE_CURRENT_BINARY_DIR}/mach_exc.h ${CMAKE_CURRENT_BINARY_DIR}/mach_excServer.c @@ -318,4 +255,4 @@ ${entitlements} ) endif() -endif() +#endif() diff --git a/lldb/unittests/CMakeLists.txt b/lldb/unittests/CMakeLists.txt --- a/lldb/unittests/CMakeLists.txt +++ b/lldb/unittests/CMakeLists.txt @@ -78,6 +78,6 @@ add_subdirectory(UnwindAssembly) add_subdirectory(Utility) -if(LLDB_CAN_USE_DEBUGSERVER AND NOT SKIP_TEST_DEBUGSERVER) +if(LLDB_CAN_USE_DEBUGSERVER AND NOT LLDB_USE_SYSTEM_DEBUGSERVER) add_subdirectory(debugserver) endif() diff --git a/lldb/unittests/tools/lldb-server/CMakeLists.txt b/lldb/unittests/tools/lldb-server/CMakeLists.txt --- a/lldb/unittests/tools/lldb-server/CMakeLists.txt +++ b/lldb/unittests/tools/lldb-server/CMakeLists.txt @@ -13,10 +13,16 @@ add_lldb_test_executable(thread_inferior inferior/thread_inferior.cpp) add_lldb_test_executable(environment_check inferior/environment_check.cpp) -if(DEBUGSERVER_PATH) - add_definitions(-DLLDB_SERVER="${DEBUGSERVER_PATH}" -DLLDB_SERVER_IS_DEBUGSERVER=1) +if(LLDB_CAN_USE_LLDB_SERVER) + if(LLDB_USE_SYSTEM_DEBUGSERVER) + lldb_find_system_debugserver(system_debugserver_path) + add_definitions(-DLLDB_SERVER="${system_debugserver_path}") + else() + add_definitions(-DLLDB_SERVER="$") + endif() + add_definitions(-DLLDB_SERVER_IS_DEBUGSERVER=ON) else() - add_definitions(-DLLDB_SERVER="$" -DLLDB_SERVER_IS_DEBUGSERVER=0) + add_definitions(-DLLDB_SERVER="$" -DLLDB_SERVER_IS_DEBUGSERVER=OFF) endif() add_definitions(