| 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() |