blob: 621b31f46be79331fede1bc89991fcd99ab7ce1c [file]
include(GNUInstallDirs)
function(lldb_tablegen)
# Syntax:
# lldb_tablegen output-file [tablegen-arg ...] SOURCE source-file
# [[TARGET cmake-target-name] [DEPENDS extra-dependency ...]]
#
# Generates a custom command for invoking tblgen as
#
# tblgen source-file -o=output-file tablegen-arg ...
#
# and, if cmake-target-name is provided, creates a custom target for
# executing the custom command depending on output-file. It is
# possible to list more files to depend after DEPENDS.
cmake_parse_arguments(LTG "" "SOURCE;TARGET" "" ${ARGN})
if(NOT LTG_SOURCE)
message(FATAL_ERROR "SOURCE source-file required by lldb_tablegen")
endif()
set(LLVM_TARGET_DEFINITIONS ${LTG_SOURCE})
if (LLVM_USE_SANITIZER MATCHES ".*Address.*")
list(APPEND LTG_UNPARSED_ARGUMENTS -DLLDB_SANITIZED)
endif()
string(TOUPPER "${CMAKE_BUILD_TYPE}" LTG_BUILD_TYPE)
if (NOT LLVM_ENABLE_ASSERTIONS AND NOT LTG_BUILD_TYPE STREQUAL "DEBUG")
list(APPEND LTG_UNPARSED_ARGUMENTS -DNDEBUG)
endif()
tablegen(LLDB ${LTG_UNPARSED_ARGUMENTS})
if(LTG_TARGET)
add_public_tablegen_target(${LTG_TARGET})
set_property(GLOBAL APPEND PROPERTY LLDB_TABLEGEN_TARGETS ${LTG_TARGET})
endif()
if("-dump-json" IN_LIST ARGN)
set_property(GLOBAL APPEND PROPERTY LLDB_DOCS_JSON_OUTPUTS "${TABLEGEN_OUTPUT}")
endif()
endfunction(lldb_tablegen)
# Returns TRUE in `out_var` if any of `libs` is `liblldb` or already carries
# the LLDB_LINKS_LIBLLDB property.
function(_lldb_links_liblldb_check out_var libs)
set(${out_var} FALSE PARENT_SCOPE)
foreach(lib ${libs})
if("${lib}" STREQUAL "liblldb")
set(${out_var} TRUE PARENT_SCOPE)
return()
endif()
if(TARGET "${lib}")
get_target_property(_p "${lib}" LLDB_LINKS_LIBLLDB)
if(_p)
set(${out_var} TRUE PARENT_SCOPE)
return()
endif()
endif()
endforeach()
endfunction()
function(_lldb_propagate_links_liblldb name libs)
_lldb_links_liblldb_check(_links_liblldb "${libs}")
set_target_properties(${name} PROPERTIES LLDB_LINKS_LIBLLDB ${_links_liblldb})
endfunction()
# Records a target's undefined LLDB symbols for re-export by liblldb.
# The output path is appended to the LLDB_DYNAMIC_SCRIPTINTERPRETER_SYMBOL_FILES
# global property.
function(lldb_record_dynamic_script_interpreter_exports target)
set(symbol_file
"${CMAKE_CURRENT_BINARY_DIR}/${target}.undefined.symbols")
# llvm-nm is registered as a CMake target after the LLDB subdirectory is
# processed, so a forward target reference is required. LLVM_NM, when set,
# points to a prebuilt host tool for cross-compiled builds.
if(LLVM_NM)
set(nm_exe "${LLVM_NM}")
set(nm_dep)
else()
set(nm_exe "$<TARGET_FILE:llvm-nm>")
set(nm_dep llvm-nm)
endif()
set(extra_args)
if(APPLE)
list(APPEND extra_args --mach-o)
endif()
add_custom_command(
OUTPUT ${symbol_file}
COMMAND "${Python3_EXECUTABLE}"
${LLDB_SOURCE_DIR}/scripts/extract-dynamic-script-interpreter-exports.py
--nm ${nm_exe}
${extra_args}
-o ${symbol_file}
$<TARGET_OBJECTS:${target}>
DEPENDS
${LLDB_SOURCE_DIR}/scripts/extract-dynamic-script-interpreter-exports.py
$<TARGET_OBJECTS:${target}>
${nm_dep}
COMMAND_EXPAND_LISTS
VERBATIM
COMMENT "Extracting LLDB symbols required by ${target}"
)
add_custom_target(${target}-exports DEPENDS ${symbol_file})
set_target_properties(${target}-exports PROPERTIES FOLDER "LLDB/API")
set_property(GLOBAL APPEND PROPERTY
LLDB_DYNAMIC_SCRIPTINTERPRETER_SYMBOL_FILES ${symbol_file})
endfunction()
# Applies an exports file to a target's link without inserting the
# order-only edge that add_llvm_symbol_exports normally adds. That edge
# propagates through CMake's compile-order graph and forms a cycle when
# the exports list is itself derived from a target that links the same
# library. LINK_DEPENDS still triggers a relink when the file's content
# changes (Ninja and Makefile generators only).
function(lldb_apply_exports_file target export_file)
add_llvm_symbol_exports(${target} ${export_file}
NO_TARGET_DEPENDENCY
OUTPUT_FILE_VAR native_export_file)
set_property(TARGET ${target} APPEND PROPERTY LINK_DEPENDS
${native_export_file})
endfunction()
# Configure-time scan: every #include "lldb/<Module>/..." in <SOURCES> and in
# PUBLIC_HEADER_DIR (recursive) must reference OWN_MODULE or a name in
# ALLOWED_MODULES, otherwise FATAL_ERROR. Catches accidental cross-module
# includes that succeed at link time (e.g. on macOS) without a corresponding
# CMake LINK_LIBS dependency.
function(lldb_check_header_layering target)
cmake_parse_arguments(HC "" "PUBLIC_HEADER_DIR;OWN_MODULE"
"SOURCES;ALLOWED_MODULES" ${ARGN})
set(_files)
foreach(src ${HC_SOURCES})
if(NOT IS_ABSOLUTE "${src}")
set(src "${CMAKE_CURRENT_SOURCE_DIR}/${src}")
endif()
# PARAM_UNPARSED_ARGUMENTS in add_lldb_library carries source files
# alongside llvm_add_library keywords like ADDITIONAL_HEADER_DIRS or
# LINK_COMPONENTS. Skip anything that isn't an existing file.
if(EXISTS "${src}" AND NOT IS_DIRECTORY "${src}")
list(APPEND _files "${src}")
endif()
endforeach()
if(HC_PUBLIC_HEADER_DIR AND EXISTS "${HC_PUBLIC_HEADER_DIR}")
file(GLOB_RECURSE _public_hdrs
"${HC_PUBLIC_HEADER_DIR}/*.h" "${HC_PUBLIC_HEADER_DIR}/*.hpp")
list(APPEND _files ${_public_hdrs})
endif()
set(_allowed ${HC_ALLOWED_MODULES} ${HC_OWN_MODULE})
foreach(file ${_files})
file(STRINGS "${file}" _includes
REGEX "^[ \t]*#[ \t]*include[ \t]+\"lldb/[A-Za-z_][A-Za-z0-9_]*/")
foreach(line ${_includes})
# Allow Windows system-header wrapper.
if(line MATCHES "\"lldb/Host/windows/windows\\.h\"")
continue()
endif()
string(REGEX MATCH
"^[ \t]*#[ \t]*include[ \t]+\"lldb/([A-Za-z_][A-Za-z0-9_]*)/"
_m "${line}")
if(NOT CMAKE_MATCH_1 IN_LIST _allowed)
message(FATAL_ERROR
"LLDB layering: target '${target}' includes a header from "
"module 'lldb/${CMAKE_MATCH_1}/' which is not in its allowlist.\n"
" File: ${file}\n"
" Include: ${line}\n"
" Own module: ${HC_OWN_MODULE}\n"
" Allowed modules: ${HC_ALLOWED_MODULES}\n"
"Either remove the include or add 'lldb${CMAKE_MATCH_1}' to "
"ALLOWED_INTERNAL_DEPENDENCIES.")
endif()
endforeach()
endforeach()
endfunction()
function(add_lldb_library name)
include_directories(BEFORE
${CMAKE_CURRENT_BINARY_DIR}
)
cmake_parse_arguments(PARAM
"MODULE;SHARED;STATIC;OBJECT;PLUGIN;FRAMEWORK;NO_INTERNAL_DEPENDENCIES;NO_PLUGIN_DEPENDENCIES"
"INSTALL_PREFIX"
"LINK_LIBS;CLANG_LIBS;ALLOWED_INTERNAL_DEPENDENCIES"
${ARGN})
foreach(link_lib ${PARAM_LINK_LIBS})
# May not be a target yet.
if (NOT TARGET ${link_lib})
continue()
endif()
if (link_lib MATCHES "^clang")
message(FATAL_ERROR "Library ${name} links against clang library ${link_lib} via LINK_LIBS but must be added via CLANG_LIBS")
endif()
get_target_property(_is_llvm_component ${link_lib} LLVM_COMPONENT)
if (link_lib MATCHES "^LLVM" AND ${_is_llvm_component})
message(FATAL_ERROR "Library ${name} links against LLVM library ${link_lib} via LINK_LIBS but must be added via LINK_COMPONENTS")
endif()
endforeach()
set(_check_internal_deps FALSE)
if(PARAM_NO_INTERNAL_DEPENDENCIES)
set(_allowed_internal_deps "")
set(_check_internal_deps TRUE)
elseif(DEFINED PARAM_ALLOWED_INTERNAL_DEPENDENCIES)
set(_allowed_internal_deps "${PARAM_ALLOWED_INTERNAL_DEPENDENCIES}")
set(_check_internal_deps TRUE)
endif()
if(_check_internal_deps)
foreach(link_lib ${PARAM_LINK_LIBS})
if(link_lib MATCHES "^lldb" AND NOT link_lib IN_LIST _allowed_internal_deps)
message(FATAL_ERROR
"LLDB layering: target '${name}' has a forbidden internal dependency on '${link_lib}'.\n"
" Allowed internal deps: ${_allowed_internal_deps}\n"
"Add '${link_lib}' to ALLOWED_INTERNAL_DEPENDENCIES on the "
"add_lldb_library(${name} ...) call, or remove it from LINK_LIBS.")
endif()
endforeach()
# Also scan sources and public headers for forbidden cross-module
# #include directives. Catches accidental layering breaks that succeed
# at link time on macOS due to static linking, even without a
# corresponding LINK_LIBS entry.
# Map a target name to its module directory under
# ${LLDB_INCLUDE_DIR}/lldb/. Top-level libraries map directly
# (lldbCore -> Core); sub-libraries fold into their parent module by
# longest-prefix match (lldbHostMacOSXObjCXX -> Host).
macro(_lldb_module_for target_name out_var)
string(REGEX REPLACE "^lldb" "" _stripped "${target_name}")
if(IS_DIRECTORY "${LLDB_INCLUDE_DIR}/lldb/${_stripped}")
set(${out_var} "${_stripped}")
else()
set(${out_var} "${_stripped}")
foreach(candidate Utility Host Core Symbol Target Breakpoint
Expression Interpreter API DataFormatters Commands
Initialization ValueObject Version)
string(LENGTH "${candidate}" _clen)
string(SUBSTRING "${_stripped}" 0 ${_clen} _prefix)
if(_prefix STREQUAL candidate)
set(${out_var} "${candidate}")
break()
endif()
endforeach()
endif()
endmacro()
_lldb_module_for("${name}" _own_module)
set(_allowed_modules)
foreach(dep ${_allowed_internal_deps})
_lldb_module_for("${dep}" _m)
list(APPEND _allowed_modules "${_m}")
endforeach()
list(REMOVE_DUPLICATES _allowed_modules)
# PUBLIC_HEADER_DIR uses the unfolded name so sub-libraries
# (e.g. lldbHostMacOSXObjCXX) don't redundantly scan their parent
# module's headers — those are scanned by the parent's own check.
string(REGEX REPLACE "^lldb" "" _own_dir "${name}")
lldb_check_header_layering(${name}
SOURCES ${PARAM_UNPARSED_ARGUMENTS}
PUBLIC_HEADER_DIR "${LLDB_INCLUDE_DIR}/lldb/${_own_dir}"
OWN_MODULE ${_own_module}
ALLOWED_MODULES ${_allowed_modules})
endif()
if(PARAM_NO_PLUGIN_DEPENDENCIES)
foreach(link_lib ${PARAM_LINK_LIBS})
if (link_lib MATCHES "^lldbPlugin")
message(FATAL_ERROR
"Library ${name} cannot depend on a plugin (Found ${link_lib} in "
"LINK_LIBS)")
endif()
endforeach()
endif()
if(PARAM_PLUGIN)
set_property(GLOBAL APPEND PROPERTY LLDB_PLUGINS ${name})
endif()
if (PARAM_MODULE)
set(libkind MODULE)
elseif (PARAM_SHARED)
set(libkind SHARED)
elseif (PARAM_OBJECT)
# Pass STATIC alongside OBJECT so that under BUILD_SHARED_LIBS=ON the
# secondary library variant llvm_add_library produces is a STATIC archive
# rather than a SHARED library. OBJECT consumers in LLDB carry no LINK_LIBS
# of their own (consumers add them), so a SHARED variant would fail to link.
set(libkind "OBJECT;STATIC")
else ()
# PARAM_STATIC or library type unspecified. BUILD_SHARED_LIBS
# does not control the kind of libraries created for LLDB,
# only whether or not they link to shared/static LLVM/Clang
# libraries.
set(libkind STATIC)
endif()
if(LLDB_NO_INSTALL_DEFAULT_RPATH)
set(pass_NO_INSTALL_RPATH NO_INSTALL_RPATH)
endif()
llvm_add_library(${name} ${libkind}
${PARAM_UNPARSED_ARGUMENTS}
LINK_LIBS ${PARAM_LINK_LIBS}
${pass_NO_INSTALL_RPATH}
)
# Mark whether this library transitively pulls in liblldb.
_lldb_propagate_links_liblldb(${name} "${PARAM_LINK_LIBS}")
if(CLANG_LINK_CLANG_DYLIB)
target_link_libraries(${name} PRIVATE clang-cpp)
else()
target_link_libraries(${name} PRIVATE ${PARAM_CLANG_LIBS})
endif()
# A target cannot be changed to a FRAMEWORK after calling install() because
# this may result in the wrong install DESTINATION. The FRAMEWORK property
# must be set earlier.
if(PARAM_FRAMEWORK)
set_target_properties(${name} PROPERTIES FRAMEWORK ON)
endif()
if(PARAM_SHARED)
set(install_dest lib${LLVM_LIBDIR_SUFFIX})
if(PARAM_INSTALL_PREFIX)
set(install_dest ${PARAM_INSTALL_PREFIX})
endif()
# RUNTIME is relevant for DLL platforms, FRAMEWORK for macOS
install(TARGETS ${name} COMPONENT ${name}
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION ${install_dest}
ARCHIVE DESTINATION ${install_dest}
FRAMEWORK DESTINATION ${install_dest})
if (NOT CMAKE_CONFIGURATION_TYPES)
add_llvm_install_targets(install-${name}
DEPENDS ${name}
COMPONENT ${name})
endif()
endif()
# Hack: only some LLDB libraries depend on the clang autogenerated headers,
# but it is simple enough to make all of LLDB depend on some of those
# headers without negatively impacting much of anything.
if(NOT LLDB_BUILT_STANDALONE)
add_dependencies(${name} clang-tablegen-targets)
endif()
if(PARAM_PLUGIN)
get_property(parent_dir DIRECTORY PROPERTY PARENT_DIRECTORY)
if(EXISTS ${parent_dir})
get_filename_component(category ${parent_dir} NAME)
set_target_properties(${name} PROPERTIES FOLDER "LLDB/Plugins/${category}")
endif()
else()
set_target_properties(${name} PROPERTIES FOLDER "LLDB/Libraries")
endif()
# When liblldb re-exports private symbols (due to LLDB_EXPORT_ALL_SYMBOLS
# and/or LLDB_ENABLE_DYNAMIC_SCRIPTINTERPRETERS) those symbols must keep
# default visibility in the contributing libraries, even if a global
# `CMAKE_CXX_VISIBILITY_PRESET=hidden` is present. A linker version script
# cannot re-export a symbol that was hidden at compile time.
if (LLDB_EXPORT_ALL_SYMBOLS OR LLDB_ENABLE_DYNAMIC_SCRIPTINTERPRETERS)
set_target_properties(${name} PROPERTIES CXX_VISIBILITY_PRESET default)
endif()
endfunction(add_lldb_library)
function(add_lldb_executable name)
cmake_parse_arguments(ARG
"GENERATE_INSTALL"
"INSTALL_PREFIX"
"LINK_LIBS;CLANG_LIBS;LINK_COMPONENTS;BUILD_RPATH;INSTALL_RPATH"
${ARGN}
)
if(LLDB_NO_INSTALL_DEFAULT_RPATH)
set(pass_NO_INSTALL_RPATH NO_INSTALL_RPATH)
endif()
list(APPEND LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS})
add_llvm_executable(${name}
${pass_NO_INSTALL_RPATH}
${ARG_UNPARSED_ARGUMENTS}
)
target_link_libraries(${name} PRIVATE ${ARG_LINK_LIBS})
if(WIN32)
list(FIND ARG_LINK_LIBS liblldb LIBLLDB_INDEX)
if(NOT LIBLLDB_INDEX EQUAL -1)
if (MSVC)
target_link_options(${name} PRIVATE
"LINKER:/DELAYLOAD:$<TARGET_FILE_NAME:liblldb>")
target_link_libraries(${name} PRIVATE delayimp)
elseif (MINGW AND LINKER_IS_LLD)
# LLD can delay load just by passing a --delayload flag, as long as the import
# library is a short type import library (which LLD and MS link.exe produce).
# With ld.bfd, with long import libraries (as produced by GNU binutils), one
# has to generate a separate delayload import library with dlltool.
target_link_options(${name} PRIVATE "-Wl,--delayload=$<TARGET_FILE_NAME:liblldb>")
elseif (DEFINED LLDB_PYTHON_DLL_RELATIVE_PATH)
# If liblldb can't be delayloaded, then LLDB_PYTHON_DLL_RELATIVE_PATH will not
# have any effect.
message(WARNING "liblldb is not delay loaded, LLDB_PYTHON_DLL_RELATIVE_PATH has no effect")
endif()
endif()
endif()
if(CLANG_LINK_CLANG_DYLIB)
target_link_libraries(${name} PRIVATE clang-cpp)
else()
target_link_libraries(${name} PRIVATE ${ARG_CLANG_LIBS})
endif()
if (ARG_BUILD_RPATH)
set_target_properties(${name} PROPERTIES BUILD_RPATH "${ARG_BUILD_RPATH}")
endif()
if (ARG_INSTALL_RPATH)
set_target_properties(${name} PROPERTIES
BUILD_WITH_INSTALL_RPATH OFF
INSTALL_RPATH "${ARG_INSTALL_RPATH}")
endif()
if(ARG_GENERATE_INSTALL)
set(install_dest bin)
if(ARG_INSTALL_PREFIX)
set(install_dest ${ARG_INSTALL_PREFIX})
endif()
install(TARGETS ${name} COMPONENT ${name}
RUNTIME DESTINATION ${install_dest}
LIBRARY DESTINATION ${install_dest}
BUNDLE DESTINATION ${install_dest}
FRAMEWORK DESTINATION ${install_dest})
if (NOT CMAKE_CONFIGURATION_TYPES)
add_llvm_install_targets(install-${name}
DEPENDS ${name}
COMPONENT ${name})
# An installed tool that links liblldb won't run without liblldb
# installed alongside it. Record it on a global list so other
# runtime components (e.g. the Python/Lua script packages) can
# attach themselves to the same install targets.
_lldb_links_liblldb_check(_links_liblldb "${ARG_LINK_LIBS}")
if(_links_liblldb)
set_property(GLOBAL APPEND PROPERTY LLDB_TOOLS_LINKING_LIBLLDB ${name})
if(TARGET install-liblldb)
add_dependencies(install-${name} install-liblldb)
if(TARGET install-${name}-stripped AND TARGET install-liblldb-stripped)
add_dependencies(install-${name}-stripped install-liblldb-stripped)
endif()
endif()
endif()
endif()
if(APPLE AND ARG_INSTALL_PREFIX)
lldb_add_post_install_steps_darwin(${name} ${ARG_INSTALL_PREFIX})
endif()
endif()
endfunction()
macro(add_lldb_tool_subdirectory name)
add_llvm_subdirectory(LLDB TOOL ${name})
endmacro()
function(add_lldb_tool name)
cmake_parse_arguments(ARG "ADD_TO_FRAMEWORK" "" "" ${ARGN})
if(LLDB_BUILD_FRAMEWORK AND ARG_ADD_TO_FRAMEWORK)
set(subdir LLDB.framework/Versions/${LLDB_FRAMEWORK_VERSION}/Resources)
add_lldb_executable(${name}
GENERATE_INSTALL
INSTALL_PREFIX ${LLDB_FRAMEWORK_INSTALL_DIR}/${subdir}
${ARG_UNPARSED_ARGUMENTS}
)
lldb_add_to_buildtree_lldb_framework(${name} ${subdir})
return()
endif()
add_lldb_executable(${name} GENERATE_INSTALL ${ARG_UNPARSED_ARGUMENTS})
set_target_properties(${name} PROPERTIES XCODE_GENERATE_SCHEME ON)
endfunction()
# liblldb statically absorbs lldbHost, lldbUtility, and every plugin. A tool
# that links the shared liblldb while also linking those archives statically
# carries a second copy of their object code. On ELF, if the tool re-exports
# the archive symbols through its own .dynsym, the dynamic linker can bind the
# shared liblldb's internal references to the tool's copy instead of its own,
# breaking shared state such as the HostInfo singletons. --exclude-libs,ALL
# keeps the archive symbols out of the tool's .dynsym. Only ELF is affected:
# Mach-O uses two-level namespaces and PE/COFF does not export symbols by
# default.
function(lldb_prevent_liblldb_symbol_interposition name)
if(UNIX AND NOT APPLE)
target_link_options(${name} PRIVATE "LINKER:--exclude-libs,ALL")
endif()
endfunction()
# The test suite relies on finding LLDB.framework binary resources in the
# build-tree. Remove them before installing to avoid collisions with their
# own install targets.
function(lldb_add_to_buildtree_lldb_framework name subdir)
# The rpaths needed to find the LLVM dylib in the buildtree differ from installation rpaths.
if (LLVM_LINK_LLVM_DYLIB)
set_target_properties(${name} PROPERTIES
BUILD_WITH_INSTALL_RPATH OFF
)
endif()
# Destination for the copy in the build-tree. While the framework target may
# not exist yet, it will exist when the generator expression gets expanded.
set(copy_dest "${LLDB_FRAMEWORK_ABSOLUTE_BUILD_DIR}/${subdir}/$<TARGET_FILE_NAME:${name}>")
# Copy into the given subdirectory for testing.
add_custom_command(TARGET ${name} POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${name}> ${copy_dest}
COMMENT "Copy ${name} to ${copy_dest}"
)
# Create a custom target to remove the copy again from LLDB.framework in the
# build tree.
add_custom_target(${name}-cleanup
COMMAND ${CMAKE_COMMAND} -E remove ${copy_dest}
COMMENT "Removing ${name} from LLDB.framework")
add_dependencies(lldb-framework-cleanup
${name}-cleanup)
endfunction()
# PluginManager discovers dynamic script interpreter plugins at runtime by
# scanning the directory that holds liblldb, so a plugin is loaded only when it
# sits beside it. A framework build moves liblldb into the bundle, so the plugin
# must move with it and carry an rpath that reaches liblldb from its new
# location.
function(lldb_add_scriptinterpreter_plugin_to_framework name)
if(NOT LLDB_BUILD_FRAMEWORK)
return()
endif()
# The rpaths needed to find the LLVM dylib in the buildtree differ from installation rpaths.
if (LLVM_LINK_LLVM_DYLIB)
set_target_properties(${name} PROPERTIES
BUILD_WITH_INSTALL_RPATH OFF
)
endif()
set_property(TARGET ${name} APPEND PROPERTY
INSTALL_RPATH "@loader_path/../../..")
# Copy under the unversioned name: PluginManager derives a plugin's
# initializer symbol from it. A versioned copy would load but never
# initialize.
set(plugin_in_framework
"${LLDB_FRAMEWORK_ABSOLUTE_BUILD_DIR}/LLDB.framework/Versions/${LLDB_FRAMEWORK_VERSION}/$<TARGET_LINKER_FILE_NAME:${name}>")
add_custom_command(TARGET ${name} POST_BUILD VERBATIM
COMMAND ${CMAKE_COMMAND} -E copy "$<TARGET_FILE:${name}>" "${plugin_in_framework}"
COMMENT "Copy ${name} into LLDB.framework")
add_custom_target(${name}-framework-cleanup
COMMAND ${CMAKE_COMMAND} -E remove "${plugin_in_framework}"
COMMENT "Removing ${name} from LLDB.framework")
add_dependencies(lldb-framework-cleanup ${name}-framework-cleanup)
endfunction()
# Add extra install steps for dSYM creation and stripping for the given target.
function(lldb_add_post_install_steps_darwin name install_prefix)
if(NOT APPLE)
message(WARNING "Darwin-specific functionality; not currently available on non-Apple platforms.")
return()
endif()
get_target_property(output_name ${name} OUTPUT_NAME)
if(NOT output_name)
set(output_name ${name})
endif()
get_target_property(is_framework ${name} FRAMEWORK)
if(is_framework)
get_target_property(buildtree_dir ${name} LIBRARY_OUTPUT_DIRECTORY)
if(buildtree_dir)
set(bundle_subdir ${output_name}.framework/Versions/${LLDB_FRAMEWORK_VERSION}/)
else()
message(SEND_ERROR "Framework target ${name} missing property for output directory. Cannot generate post-install steps.")
return()
endif()
else()
get_target_property(target_type ${name} TYPE)
if(target_type STREQUAL "EXECUTABLE")
set(buildtree_dir ${LLVM_RUNTIME_OUTPUT_INTDIR})
else()
# Only ever install shared libraries.
set(output_name "lib${output_name}.dylib")
set(buildtree_dir ${LLVM_LIBRARY_OUTPUT_INTDIR})
endif()
endif()
# Generate dSYM
if(NOT LLDB_SKIP_DSYM)
set(dsym_name ${output_name}.dSYM)
if(is_framework)
set(dsym_name ${output_name}.framework.dSYM)
endif()
if(LLDB_DEBUGINFO_INSTALL_PREFIX)
# This makes the path absolute, so we must respect DESTDIR.
set(dsym_name "\$ENV\{DESTDIR\}${LLDB_DEBUGINFO_INSTALL_PREFIX}/${dsym_name}")
endif()
set(buildtree_name ${buildtree_dir}/${bundle_subdir}${output_name})
install(CODE "message(STATUS \"Externalize debuginfo: ${dsym_name}\")" COMPONENT ${name})
install(CODE "execute_process(COMMAND xcrun dsymutil -o=${dsym_name} ${buildtree_name})"
COMPONENT ${name})
endif()
if(NOT LLDB_SKIP_STRIP)
# Strip distribution binary with -ST (removing debug symbol table entries and
# Swift symbols). Avoid CMAKE_INSTALL_DO_STRIP and llvm_externalize_debuginfo()
# as they can't be configured sufficiently.
set(installtree_name "\$ENV\{DESTDIR\}${install_prefix}/${bundle_subdir}${output_name}")
install(CODE "message(STATUS \"Stripping: ${installtree_name}\")" COMPONENT ${name})
install(CODE "execute_process(COMMAND xcrun strip -ST ${installtree_name})"
COMPONENT ${name})
endif()
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()
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
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(exit_code)
message(WARNING "`xcode-select -p` failed:\n${error_msg}")
else()
set(subpath "LLDB.framework/Resources/debugserver")
set(path_shared "${xcode_dev_dir}/../SharedFrameworks/${subpath}")
set(path_private "${xcode_dev_dir}/Library/PrivateFrameworks/${subpath}")
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()
function(lldb_find_python_module module)
set(MODULE_FOUND PY_${module}_FOUND)
if (${MODULE_FOUND})
return()
endif()
execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "import ${module}"
RESULT_VARIABLE status
ERROR_QUIET)
if (status)
set(${MODULE_FOUND} OFF PARENT_SCOPE)
message(STATUS "Could NOT find Python module '${module}'")
else()
set(${MODULE_FOUND} ON PARENT_SCOPE)
message(STATUS "Found Python module '${module}'")
endif()
endfunction()
# Removes all module flags from the current CMAKE_CXX_FLAGS. Used for
# the Objective-C++ code in lldb which we don't want to build with modules.
# Reasons for this are that modules with Objective-C++ would require that
# all LLVM/Clang modules are Objective-C++ compatible (which they are likely
# not) and we would have rebuild a second set of modules just for the few
# Objective-C++ files in lldb (which slows down the build process).
macro(remove_module_flags)
string(REGEX REPLACE "-fmodules-cache-path=[^ ]+" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "-fmodules-local-submodule-visibility" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "-fmodules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "-gmodules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "-fcxx-modules" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
endmacro()