1function(lldb_tablegen)
2  # Syntax:
3  # lldb_tablegen output-file [tablegen-arg ...] SOURCE source-file
4  # [[TARGET cmake-target-name] [DEPENDS extra-dependency ...]]
5  #
6  # Generates a custom command for invoking tblgen as
7  #
8  # tblgen source-file -o=output-file tablegen-arg ...
9  #
10  # and, if cmake-target-name is provided, creates a custom target for
11  # executing the custom command depending on output-file. It is
12  # possible to list more files to depend after DEPENDS.
13
14  cmake_parse_arguments(LTG "" "SOURCE;TARGET" "" ${ARGN})
15
16  if(NOT LTG_SOURCE)
17    message(FATAL_ERROR "SOURCE source-file required by lldb_tablegen")
18  endif()
19
20  set(LLVM_TARGET_DEFINITIONS ${LTG_SOURCE})
21  tablegen(LLDB ${LTG_UNPARSED_ARGUMENTS})
22
23  if(LTG_TARGET)
24    add_public_tablegen_target(${LTG_TARGET})
25    set_target_properties( ${LTG_TARGET} PROPERTIES FOLDER "LLDB tablegenning")
26    set_property(GLOBAL APPEND PROPERTY LLDB_TABLEGEN_TARGETS ${LTG_TARGET})
27  endif()
28endfunction(lldb_tablegen)
29
30function(add_lldb_test_dependency)
31  foreach(dependency ${ARGN})
32    add_dependencies(lldb-test-deps ${dependency})
33  endforeach()
34endfunction(add_lldb_test_dependency)
35
36function(add_lldb_library name)
37  include_directories(BEFORE
38    ${CMAKE_CURRENT_BINARY_DIR}
39)
40
41  # only supported parameters to this macro are the optional
42  # MODULE;SHARED;STATIC library type and source files
43  cmake_parse_arguments(PARAM
44    "MODULE;SHARED;STATIC;OBJECT;PLUGIN"
45    "INSTALL_PREFIX;ENTITLEMENTS"
46    "EXTRA_CXXFLAGS;DEPENDS;LINK_LIBS;LINK_COMPONENTS;CLANG_LIBS"
47    ${ARGN})
48  llvm_process_sources(srcs ${PARAM_UNPARSED_ARGUMENTS})
49  list(APPEND LLVM_LINK_COMPONENTS ${PARAM_LINK_COMPONENTS})
50
51  if(PARAM_PLUGIN)
52    set_property(GLOBAL APPEND PROPERTY LLDB_PLUGINS ${name})
53  endif()
54
55  if (MSVC_IDE OR XCODE)
56    string(REGEX MATCHALL "/[^/]+" split_path ${CMAKE_CURRENT_SOURCE_DIR})
57    list(GET split_path -1 dir)
58    file(GLOB_RECURSE headers
59      ../../include/lldb${dir}/*.h)
60    set(srcs ${srcs} ${headers})
61  endif()
62  if (PARAM_MODULE)
63    set(libkind MODULE)
64  elseif (PARAM_SHARED)
65    set(libkind SHARED)
66  elseif (PARAM_OBJECT)
67    set(libkind OBJECT)
68  else ()
69    # PARAM_STATIC or library type unspecified. BUILD_SHARED_LIBS
70    # does not control the kind of libraries created for LLDB,
71    # only whether or not they link to shared/static LLVM/Clang
72    # libraries.
73    set(libkind STATIC)
74  endif()
75
76  #PIC not needed on Win
77  # FIXME: Setting CMAKE_CXX_FLAGS here is a no-op, use target_compile_options
78  # or omit this logic instead.
79  if (NOT WIN32)
80    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC")
81  endif()
82
83  if (PARAM_OBJECT)
84    add_library(${name} ${libkind} ${srcs})
85  else()
86    if(PARAM_ENTITLEMENTS)
87      set(pass_ENTITLEMENTS ENTITLEMENTS ${PARAM_ENTITLEMENTS})
88    endif()
89
90    if(LLDB_NO_INSTALL_DEFAULT_RPATH)
91      set(pass_NO_INSTALL_RPATH NO_INSTALL_RPATH)
92    endif()
93
94    llvm_add_library(${name} ${libkind} ${srcs}
95      LINK_LIBS ${PARAM_LINK_LIBS}
96      DEPENDS ${PARAM_DEPENDS}
97      ${pass_ENTITLEMENTS}
98      ${pass_NO_INSTALL_RPATH}
99    )
100
101    if(CLANG_LINK_CLANG_DYLIB)
102      target_link_libraries(${name} PRIVATE clang-cpp)
103    else()
104      target_link_libraries(${name} PRIVATE ${PARAM_CLANG_LIBS})
105    endif()
106  endif()
107
108  if(PARAM_SHARED)
109    set(install_dest lib${LLVM_LIBDIR_SUFFIX})
110    if(PARAM_INSTALL_PREFIX)
111      set(install_dest ${PARAM_INSTALL_PREFIX})
112    endif()
113    # RUNTIME is relevant for DLL platforms, FRAMEWORK for macOS
114    install(TARGETS ${name} COMPONENT ${name}
115      RUNTIME DESTINATION bin
116      LIBRARY DESTINATION ${install_dest}
117      ARCHIVE DESTINATION ${install_dest}
118      FRAMEWORK DESTINATION ${install_dest})
119    if (NOT CMAKE_CONFIGURATION_TYPES)
120      add_llvm_install_targets(install-${name}
121                              DEPENDS ${name}
122                              COMPONENT ${name})
123    endif()
124  endif()
125
126  # Hack: only some LLDB libraries depend on the clang autogenerated headers,
127  # but it is simple enough to make all of LLDB depend on some of those
128  # headers without negatively impacting much of anything.
129  if(NOT LLDB_BUILT_STANDALONE)
130    add_dependencies(${name} clang-tablegen-targets)
131  endif()
132
133  # Add in any extra C++ compilation flags for this library.
134  target_compile_options(${name} PRIVATE ${PARAM_EXTRA_CXXFLAGS})
135
136  if(PARAM_PLUGIN)
137    get_property(parent_dir DIRECTORY PROPERTY PARENT_DIRECTORY)
138    if(EXISTS ${parent_dir})
139      get_filename_component(category ${parent_dir} NAME)
140      set_target_properties(${name} PROPERTIES FOLDER "lldb plugins/${category}")
141    endif()
142  else()
143    set_target_properties(${name} PROPERTIES FOLDER "lldb libraries")
144  endif()
145endfunction(add_lldb_library)
146
147function(add_lldb_executable name)
148  cmake_parse_arguments(ARG
149    "GENERATE_INSTALL"
150    "INSTALL_PREFIX;ENTITLEMENTS"
151    "LINK_LIBS;CLANG_LIBS;LINK_COMPONENTS"
152    ${ARGN}
153    )
154
155  if(ARG_ENTITLEMENTS)
156    set(pass_ENTITLEMENTS ENTITLEMENTS ${ARG_ENTITLEMENTS})
157  endif()
158
159  if(LLDB_NO_INSTALL_DEFAULT_RPATH)
160    set(pass_NO_INSTALL_RPATH NO_INSTALL_RPATH)
161  endif()
162
163  list(APPEND LLVM_LINK_COMPONENTS ${ARG_LINK_COMPONENTS})
164  add_llvm_executable(${name}
165    ${pass_ENTITLEMENTS}
166    ${pass_NO_INSTALL_RPATH}
167    ${ARG_UNPARSED_ARGUMENTS}
168  )
169
170  target_link_libraries(${name} PRIVATE ${ARG_LINK_LIBS})
171  if(CLANG_LINK_CLANG_DYLIB)
172    target_link_libraries(${name} PRIVATE clang-cpp)
173  else()
174    target_link_libraries(${name} PRIVATE ${ARG_CLANG_LIBS})
175  endif()
176  set_target_properties(${name} PROPERTIES FOLDER "lldb executables")
177
178  if(ARG_GENERATE_INSTALL)
179    set(install_dest bin)
180    if(ARG_INSTALL_PREFIX)
181      set(install_dest ${ARG_INSTALL_PREFIX})
182    endif()
183    install(TARGETS ${name} COMPONENT ${name}
184            RUNTIME DESTINATION ${install_dest})
185    if (NOT CMAKE_CONFIGURATION_TYPES)
186      add_llvm_install_targets(install-${name}
187                               DEPENDS ${name}
188                               COMPONENT ${name})
189    endif()
190    if(APPLE AND ARG_INSTALL_PREFIX)
191      lldb_add_post_install_steps_darwin(${name} ${ARG_INSTALL_PREFIX})
192    endif()
193  endif()
194endfunction()
195
196
197macro(add_lldb_tool_subdirectory name)
198  add_llvm_subdirectory(LLDB TOOL ${name})
199endmacro()
200
201function(add_lldb_tool name)
202  cmake_parse_arguments(ARG "ADD_TO_FRAMEWORK" "" "" ${ARGN})
203  if(LLDB_BUILD_FRAMEWORK AND ARG_ADD_TO_FRAMEWORK)
204    set(subdir LLDB.framework/Versions/${LLDB_FRAMEWORK_VERSION}/Resources)
205    add_lldb_executable(${name}
206      GENERATE_INSTALL
207      INSTALL_PREFIX ${LLDB_FRAMEWORK_INSTALL_DIR}/${subdir}
208      ${ARG_UNPARSED_ARGUMENTS}
209    )
210    lldb_add_to_buildtree_lldb_framework(${name} ${subdir})
211    return()
212  endif()
213
214  add_lldb_executable(${name} GENERATE_INSTALL ${ARG_UNPARSED_ARGUMENTS})
215endfunction()
216
217# The test suite relies on finding LLDB.framework binary resources in the
218# build-tree. Remove them before installing to avoid collisions with their
219# own install targets.
220function(lldb_add_to_buildtree_lldb_framework name subdir)
221  # Destination for the copy in the build-tree. While the framework target may
222  # not exist yet, it will exist when the generator expression gets expanded.
223  get_target_property(framework_build_dir liblldb LIBRARY_OUTPUT_DIRECTORY)
224  set(copy_dest "${framework_build_dir}/${subdir}/$<TARGET_FILE_NAME:${name}>")
225
226  # Copy into the given subdirectory for testing.
227  add_custom_command(TARGET ${name} POST_BUILD
228    COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${name}> ${copy_dest}
229    COMMENT "Copy ${name} to ${copy_dest}"
230  )
231endfunction()
232
233# Add extra install steps for dSYM creation and stripping for the given target.
234function(lldb_add_post_install_steps_darwin name install_prefix)
235  if(NOT APPLE)
236    message(WARNING "Darwin-specific functionality; not currently available on non-Apple platforms.")
237    return()
238  endif()
239
240  get_target_property(output_name ${name} OUTPUT_NAME)
241  if(NOT output_name)
242    set(output_name ${name})
243  endif()
244
245  get_target_property(is_framework ${name} FRAMEWORK)
246  if(is_framework)
247    get_target_property(buildtree_dir ${name} LIBRARY_OUTPUT_DIRECTORY)
248    if(buildtree_dir)
249      set(bundle_subdir ${output_name}.framework/Versions/${LLDB_FRAMEWORK_VERSION}/)
250    else()
251      message(SEND_ERROR "Framework target ${name} missing property for output directory. Cannot generate post-install steps.")
252      return()
253    endif()
254  else()
255    get_target_property(target_type ${name} TYPE)
256    if(target_type STREQUAL "EXECUTABLE")
257      set(buildtree_dir ${LLVM_RUNTIME_OUTPUT_INTDIR})
258    else()
259      # Only ever install shared libraries.
260      set(output_name "lib${output_name}.dylib")
261      set(buildtree_dir ${LLVM_LIBRARY_OUTPUT_INTDIR})
262    endif()
263  endif()
264
265  # Generate dSYM
266  set(dsym_name ${output_name}.dSYM)
267  if(is_framework)
268    set(dsym_name ${output_name}.framework.dSYM)
269  endif()
270  if(LLDB_DEBUGINFO_INSTALL_PREFIX)
271    # This makes the path absolute, so we must respect DESTDIR.
272    set(dsym_name "\$ENV\{DESTDIR\}${LLDB_DEBUGINFO_INSTALL_PREFIX}/${dsym_name}")
273  endif()
274
275  set(buildtree_name ${buildtree_dir}/${bundle_subdir}${output_name})
276  install(CODE "message(STATUS \"Externalize debuginfo: ${dsym_name}\")" COMPONENT ${name})
277  install(CODE "execute_process(COMMAND xcrun dsymutil -o=${dsym_name} ${buildtree_name})"
278          COMPONENT ${name})
279
280  # Strip distribution binary with -ST (removing debug symbol table entries and
281  # Swift symbols). Avoid CMAKE_INSTALL_DO_STRIP and llvm_externalize_debuginfo()
282  # as they can't be configured sufficiently.
283  set(installtree_name "\$ENV\{DESTDIR\}${install_prefix}/${bundle_subdir}${output_name}")
284  install(CODE "message(STATUS \"Stripping: ${installtree_name}\")" COMPONENT ${name})
285  install(CODE "execute_process(COMMAND xcrun strip -ST ${installtree_name})"
286          COMPONENT ${name})
287endfunction()
288
289# CMake's set_target_properties() doesn't allow to pass lists for RPATH
290# properties directly (error: "called with incorrect number of arguments").
291# Instead of defining two list variables each time, use this helper function.
292function(lldb_setup_rpaths name)
293  cmake_parse_arguments(LIST "" "" "BUILD_RPATH;INSTALL_RPATH" ${ARGN})
294  set_target_properties(${name} PROPERTIES
295    BUILD_WITH_INSTALL_RPATH OFF
296    BUILD_RPATH "${LIST_BUILD_RPATH}"
297    INSTALL_RPATH "${LIST_INSTALL_RPATH}"
298  )
299endfunction()
300
301function(lldb_find_system_debugserver path)
302  execute_process(COMMAND xcode-select -p
303                  RESULT_VARIABLE exit_code
304                  OUTPUT_VARIABLE xcode_dev_dir
305                  ERROR_VARIABLE error_msg
306                  OUTPUT_STRIP_TRAILING_WHITESPACE)
307  if(exit_code)
308    message(WARNING "`xcode-select -p` failed:\n${error_msg}")
309  else()
310    set(subpath "LLDB.framework/Resources/debugserver")
311    set(path_shared "${xcode_dev_dir}/../SharedFrameworks/${subpath}")
312    set(path_private "${xcode_dev_dir}/Library/PrivateFrameworks/${subpath}")
313
314    if(EXISTS ${path_shared})
315      set(${path} ${path_shared} PARENT_SCOPE)
316    elseif(EXISTS ${path_private})
317      set(${path} ${path_private} PARENT_SCOPE)
318    else()
319      message(WARNING "System debugserver requested, but not found. "
320                      "Candidates don't exist: ${path_shared}\n${path_private}")
321    endif()
322  endif()
323endfunction()
324