diff --git a/lldb/CMakeLists.txt b/lldb/CMakeLists.txt --- a/lldb/CMakeLists.txt +++ b/lldb/CMakeLists.txt @@ -15,6 +15,13 @@ include(LLDBConfig) include(AddLLDB) +if(LLDB_BUILD_FRAMEWORK) + # Cleanup the build-tree before installing the framework. Install actions run + # in configure order. We add this early, so that cleanup runs first. + install(SCRIPT cmake/modules/LLDBFrameworkInstall.cmake + CODE "lldb_framework_prepare_install()") +endif() + # Define the LLDB_CONFIGURATION_xxx matching the build type if( uppercase_CMAKE_BUILD_TYPE STREQUAL "DEBUG" ) add_definitions( -DLLDB_CONFIGURATION_DEBUG ) @@ -151,6 +158,10 @@ list(APPEND LLDB_TEST_DEPS dsymutil) endif() + if(TARGET lldb-framework) + list(APPEND LLDB_TEST_DEPS lldb-framework) + endif() + add_custom_target(lldb-test-deps) add_dependencies(lldb-test-deps ${LLDB_TEST_DEPS}) @@ -214,3 +225,13 @@ COMMENT "Copying Python DLL to LLDB binaries directory.") endif () endif () + +if(LLDB_BUILD_FRAMEWORK) + # Expand generator expressions in the list of files to be removed from the + # framework bundle before installation. We run this late, because it requires + # the respective targets to exist. + file(GENERATE + OUTPUT ${CMAKE_BINARY_DIR}/lldb_framework_cleanup_list_paths.txt + INPUT ${CMAKE_BINARY_DIR}/lldb_framework_cleanup_list_raw.txt + ) +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 @@ -59,17 +59,9 @@ ${pass_NO_INSTALL_RPATH} ) - if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "liblldb") + if (NOT LLDB_BUILD_FRAMEWORK AND (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ${name} STREQUAL "liblldb")) if (PARAM_SHARED) - if(${name} STREQUAL "liblldb" AND LLDB_BUILD_FRAMEWORK) - if(LLDB_FRAMEWORK_INSTALL_DIR) - set(install_dir ${LLDB_FRAMEWORK_INSTALL_DIR}) - else() - set(install_dir ".") - endif() - else() - set(install_dir lib${LLVM_LIBDIR_SUFFIX}) - endif() + set(install_dir lib${LLVM_LIBDIR_SUFFIX}) install(TARGETS ${name} COMPONENT ${name} RUNTIME DESTINATION bin @@ -129,7 +121,7 @@ target_link_libraries(${name} PRIVATE ${ARG_LINK_LIBS}) set_target_properties(${name} PROPERTIES FOLDER "lldb executables") - if(ARG_GENERATE_INSTALL) + if(ARG_GENERATE_INSTALL AND NOT LLDB_BUILD_FRAMEWORK) install(TARGETS ${name} COMPONENT ${name} RUNTIME DESTINATION bin) @@ -204,3 +196,54 @@ add_dependencies(${name} lldb-framework) endfunction() + +# Unified handling for executable LLDB.framework resources. Given the name of an +# executable target, this function will: set the target's destination in the +# install-tree, copy it to the framework in the build-tree and remove the copy +# before installing the framework. The target's default build directory remains +# unchanged. +function(lldb_add_to_framework name) + # Same subdirectory in both cases, build-tree and install-tree. + set(subdir "LLDB.framework/Versions/${LLDB_FRAMEWORK_VERSION}/Resources") + + # Destination for the copy in the build-tree. While the framework may not exist + # yet, it will exist when the generator expression gets expanded. + set(copy_dest "$/../../../${subdir}") + + # Copy into the framework's Resources directory for testing. + add_custom_command(TARGET ${name} POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy $ ${copy_dest} + COMMENT "Copy ${name} to ${copy_dest}" + ) + + # Before installing, remove the copy from the build-tree framework, so it + # won't be installed together with the framework bundle and accidentally + # replace the target's already installed binary. + lldb_add_framework_cleanup_entry("remove ${copy_dest}/$") + + # Install into the framework bundle in the install-tree. + install(TARGETS ${name} COMPONENT ${name} + DESTINATION ${LLDB_FRAMEWORK_INSTALL_DIR}/${subdir} + ) +endfunction() + +# Add an entry to the list of things we clean up before running install. +# Generator expressions are expanded to actual paths at the end of the +# configuration process. Entries consist of a command and a path, +# e.g.: remove /path/to/file +# remove_directory /path/to/directory +function(lldb_add_framework_cleanup_entry entry) + file(APPEND ${CMAKE_BINARY_DIR}/lldb_framework_cleanup_list_raw.txt "${entry}\n") +endfunction() + +# CMake's set_target_properties() doesn't allow to pass lists for RPATH +# properties directly (error: "called with incorrect number of arguments"). +# Instead of defining two list variables each time, use this helper function. +function(lldb_setup_rpaths name) + cmake_parse_arguments(LIST "" "" "BUILD_RPATH;INSTALL_RPATH" ${ARGN}) + set_target_properties(${name} PROPERTIES + BUILD_WITH_INSTALL_RPATH OFF + BUILD_RPATH "${LIST_BUILD_RPATH}" + INSTALL_RPATH "${LIST_INSTALL_RPATH}" + ) +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 @@ -64,8 +64,6 @@ set(LLDB_FRAMEWORK_VERSION A CACHE STRING "LLDB.framework version (default is A)") set(LLDB_FRAMEWORK_BUILD_DIR bin CACHE STRING "Output directory for LLDB.framework") set(LLDB_FRAMEWORK_INSTALL_DIR Library/Frameworks CACHE STRING "Install directory for LLDB.framework") - set(LLDB_FRAMEWORK_TOOLS darwin-debug;debugserver;lldb-argdumper;lldb-server CACHE STRING - "List of tools to include in LLDB.framework/Resources") # Set designated directory for all dSYMs. Essentially, this emits the # framework's dSYM outside of the framework directory. diff --git a/lldb/cmake/modules/LLDBFramework.cmake b/lldb/cmake/modules/LLDBFramework.cmake --- a/lldb/cmake/modules/LLDBFramework.cmake +++ b/lldb/cmake/modules/LLDBFramework.cmake @@ -26,6 +26,11 @@ MACOSX_FRAMEWORK_INFO_PLIST ${LLDB_SOURCE_DIR}/resources/LLDB-Info.plist.in ) +# Install in framework location +install(TARGETS liblldb COMPONENT liblldb + FRAMEWORK DESTINATION ${LLDB_FRAMEWORK_INSTALL_DIR} +) + # Affects the layout of the framework bundle (default is macOS layout). if(IOS) set_target_properties(liblldb PROPERTIES @@ -36,22 +41,9 @@ endif() # Target to capture extra steps for a fully functional framework bundle. -add_custom_target(lldb-framework) +add_custom_target(lldb-framework ALL) add_dependencies(lldb-framework liblldb) -# Dependencies are defined once tools are added (see AddLLDB.cmake) -if(LLDB_FRAMEWORK_TOOLS) - message(STATUS "LLDB.framework: adding tools ${LLDB_FRAMEWORK_TOOLS}") - foreach(tool ${LLDB_FRAMEWORK_TOOLS}) - add_custom_command(TARGET lldb-framework POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ $/Resources - COMMENT "LLDB.framework: copy additional tool ${tool}" - ) - endforeach() -else() - message(WARNING "LLDB.framework: no additional tools configured (set via LLDB_FRAMEWORK_TOOLS)") -endif() - # Apart from this one, CMake creates all required symlinks in the framework bundle. add_custom_command(TARGET lldb-framework POST_BUILD COMMAND ${CMAKE_COMMAND} -E create_symlink diff --git a/lldb/cmake/modules/LLDBFrameworkInstall.cmake b/lldb/cmake/modules/LLDBFrameworkInstall.cmake new file mode 100644 --- /dev/null +++ b/lldb/cmake/modules/LLDBFrameworkInstall.cmake @@ -0,0 +1,20 @@ +# If LLDB_BUILD_FRAMEWORK is enabled, this CMake script is included from cmake_install.cmake + +# Runs as first action of the install target, removing all files and directories +# that were copied into the framework for testing. +function(lldb_framework_prepare_install) + # Framework tools must install themselves, instead of being copied over inside + # the framework bundle. Affected files were added via lldb_add_to_framework() + # and logged in a text file in the build directory. Read all entries now. + file(STRINGS ${CMAKE_BINARY_DIR}/lldb_framework_cleanup_list_paths.txt cleanup_commands) + + # Multiple cmake invocations may have added duplicates. + list(REMOVE_DUPLICATES cleanup_commands) + + # Dump and delete each file/folder. + foreach(cmd ${cleanup_commands}) + message(STATUS "Cleanup: ${cmd}") + separate_arguments(cmd) + execute_process(COMMAND ${CMAKE_COMMAND} -E ${cmd}) + endforeach() +endfunction() diff --git a/lldb/tools/argdumper/CMakeLists.txt b/lldb/tools/argdumper/CMakeLists.txt --- a/lldb/tools/argdumper/CMakeLists.txt +++ b/lldb/tools/argdumper/CMakeLists.txt @@ -4,3 +4,7 @@ LINK_LIBS lldbUtility ) + +if(LLDB_BUILD_FRAMEWORK) + lldb_add_to_framework(lldb-argdumper) +endif() diff --git a/lldb/tools/darwin-debug/CMakeLists.txt b/lldb/tools/darwin-debug/CMakeLists.txt --- a/lldb/tools/darwin-debug/CMakeLists.txt +++ b/lldb/tools/darwin-debug/CMakeLists.txt @@ -1,3 +1,7 @@ add_lldb_tool(darwin-debug darwin-debug.cpp ) + +if(LLDB_BUILD_FRAMEWORK) + lldb_add_to_framework(darwin-debug) +endif() 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 @@ -264,6 +264,10 @@ ${entitlements} ) + if(LLDB_BUILD_FRAMEWORK) + lldb_add_to_framework(debugserver) + endif() + if(IOS) set_property(TARGET lldbDebugserverCommon APPEND PROPERTY COMPILE_DEFINITIONS WITH_LOCKDOWN diff --git a/lldb/tools/driver/CMakeLists.txt b/lldb/tools/driver/CMakeLists.txt --- a/lldb/tools/driver/CMakeLists.txt +++ b/lldb/tools/driver/CMakeLists.txt @@ -24,5 +24,18 @@ ) if(LLDB_BUILD_FRAMEWORK) - lldb_setup_framework_rpaths_in_tool(lldb) + # Framework builds disable default install targets + install(TARGETS lldb COMPONENT lldb DESTINATION bin) + + # In the build-tree, we know the exact path to the framework directory. + # The installed framework can be in different locations. + get_target_property(framework_build_dir liblldb LIBRARY_OUTPUT_DIRECTORY) + lldb_setup_rpaths(lldb + BUILD_RPATH + "${framework_build_dir}" + INSTALL_RPATH + "@loader_path/../../../SharedFrameworks" + "@loader_path/../../System/Library/PrivateFrameworks" + "@loader_path/../../Library/PrivateFrameworks" + ) endif() diff --git a/lldb/tools/lldb-mi/CMakeLists.txt b/lldb/tools/lldb-mi/CMakeLists.txt --- a/lldb/tools/lldb-mi/CMakeLists.txt +++ b/lldb/tools/lldb-mi/CMakeLists.txt @@ -93,7 +93,3 @@ LINK_COMPONENTS Support ) - -if(LLDB_BUILD_FRAMEWORK) - lldb_setup_framework_rpaths_in_tool(lldb-mi) -endif() diff --git a/lldb/tools/lldb-server/CMakeLists.txt b/lldb/tools/lldb-server/CMakeLists.txt --- a/lldb/tools/lldb-server/CMakeLists.txt +++ b/lldb/tools/lldb-server/CMakeLists.txt @@ -77,3 +77,7 @@ ) target_link_libraries(lldb-server PRIVATE ${LLDB_SYSTEM_LIBS}) + +if(LLDB_BUILD_FRAMEWORK) + lldb_add_to_framework(lldb-server) +endif() diff --git a/lldb/tools/lldb-vscode/CMakeLists.txt b/lldb/tools/lldb-vscode/CMakeLists.txt --- a/lldb/tools/lldb-vscode/CMakeLists.txt +++ b/lldb/tools/lldb-vscode/CMakeLists.txt @@ -29,7 +29,3 @@ LINK_COMPONENTS Support ) - -if(LLDB_BUILD_FRAMEWORK) - lldb_setup_framework_rpaths_in_tool(lldb-vscode) -endif()