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