xref: /llvm-project/clang/cmake/modules/AddClang.cmake (revision 1842a3d833d934793012c717e98b10d51193fd0d)
1include(GNUInstallDirs)
2include(LLVMDistributionSupport)
3
4function(clang_tablegen)
5  # Syntax:
6  # clang_tablegen output-file [tablegen-arg ...] SOURCE source-file
7  # [[TARGET cmake-target-name] [DEPENDS extra-dependency ...]]
8  #
9  # Generates a custom command for invoking tblgen as
10  #
11  # tblgen source-file -o=output-file tablegen-arg ...
12  #
13  # and, if cmake-target-name is provided, creates a custom target for
14  # executing the custom command depending on output-file. It is
15  # possible to list more files to depend after DEPENDS.
16
17  cmake_parse_arguments(CTG "" "SOURCE;TARGET" "" ${ARGN})
18
19  if( NOT CTG_SOURCE )
20    message(FATAL_ERROR "SOURCE source-file required by clang_tablegen")
21  endif()
22
23  set( CLANG_TABLEGEN_ARGUMENTS "" )
24  set( LLVM_TARGET_DEFINITIONS ${CTG_SOURCE} )
25  tablegen(CLANG ${CTG_UNPARSED_ARGUMENTS} ${CLANG_TABLEGEN_ARGUMENTS})
26
27  if(CTG_TARGET)
28    add_public_tablegen_target(${CTG_TARGET})
29    set_property(GLOBAL APPEND PROPERTY CLANG_TABLEGEN_TARGETS ${CTG_TARGET})
30  endif()
31endfunction(clang_tablegen)
32
33macro(set_clang_windows_version_resource_properties name)
34  if(DEFINED windows_resource_file)
35    set_windows_version_resource_properties(${name} ${windows_resource_file}
36      VERSION_MAJOR ${CLANG_VERSION_MAJOR}
37      VERSION_MINOR ${CLANG_VERSION_MINOR}
38      VERSION_PATCHLEVEL ${CLANG_VERSION_PATCHLEVEL}
39      VERSION_STRING "${CLANG_VERSION}"
40      PRODUCT_NAME "clang")
41  endif()
42endmacro()
43
44macro(add_clang_subdirectory name)
45  add_llvm_subdirectory(CLANG TOOL ${name})
46endmacro()
47
48macro(add_clang_library name)
49  cmake_parse_arguments(ARG
50    "SHARED;STATIC;INSTALL_WITH_TOOLCHAIN"
51    ""
52    "ADDITIONAL_HEADERS"
53    ${ARGN})
54  set(srcs)
55  if(MSVC_IDE OR XCODE)
56    # Add public headers
57    file(RELATIVE_PATH lib_path
58      ${CLANG_SOURCE_DIR}/lib/
59      ${CMAKE_CURRENT_SOURCE_DIR}
60    )
61    if(NOT lib_path MATCHES "^[.][.]")
62      file( GLOB_RECURSE headers
63        ${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.h
64        ${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.def
65      )
66      set_source_files_properties(${headers} PROPERTIES HEADER_FILE_ONLY ON)
67
68      file( GLOB_RECURSE tds
69        ${CLANG_SOURCE_DIR}/include/clang/${lib_path}/*.td
70      )
71      source_group("TableGen descriptions" FILES ${tds})
72      set_source_files_properties(${tds} PROPERTIES HEADER_FILE_ONLY ON)
73
74      if(headers OR tds)
75        set(srcs ${headers} ${tds})
76      endif()
77    endif()
78  endif(MSVC_IDE OR XCODE)
79  if(srcs OR ARG_ADDITIONAL_HEADERS)
80    set(srcs
81      ADDITIONAL_HEADERS
82      ${srcs}
83      ${ARG_ADDITIONAL_HEADERS} # It may contain unparsed unknown args.
84      )
85  endif()
86
87  if(ARG_SHARED AND ARG_STATIC)
88    set(LIBTYPE SHARED STATIC)
89  elseif(ARG_SHARED)
90    set(LIBTYPE SHARED)
91  else()
92    # llvm_add_library ignores BUILD_SHARED_LIBS if STATIC is explicitly set,
93    # so we need to handle it here.
94    if(BUILD_SHARED_LIBS)
95      set(LIBTYPE SHARED)
96    else()
97      set(LIBTYPE STATIC)
98    endif()
99    if(NOT XCODE AND NOT MSVC_IDE)
100      # The Xcode generator doesn't handle object libraries correctly.
101      # The Visual Studio CMake generator does handle object libraries
102      # correctly, but it is preferable to list the libraries with their
103      # source files (instead of the object files and the source files in
104      # a separate target in the "Object Libraries" folder)
105      list(APPEND LIBTYPE OBJECT)
106    endif()
107    set_property(GLOBAL APPEND PROPERTY CLANG_STATIC_LIBS ${name})
108  endif()
109  llvm_add_library(${name} ${LIBTYPE} ${ARG_UNPARSED_ARGUMENTS} ${srcs})
110
111  if(MSVC AND NOT CLANG_LINK_CLANG_DYLIB)
112    # Make sure all consumers also turn off visibility macros so they're not
113    # trying to dllimport symbols.
114    target_compile_definitions(${name} PUBLIC CLANG_BUILD_STATIC)
115    if(TARGET "obj.${name}")
116      target_compile_definitions("obj.${name}" PUBLIC CLANG_BUILD_STATIC)
117    endif()
118  elseif(TARGET "obj.${name}" AND NOT ARG_SHARED AND NOT ARG_STATIC)
119    # Clang component libraries linked to clang-cpp are declared without SHARED or STATIC
120    target_compile_definitions("obj.${name}" PUBLIC CLANG_EXPORTS)
121  endif()
122
123  set(libs ${name})
124  if(ARG_SHARED AND ARG_STATIC)
125    list(APPEND libs ${name}_static)
126  endif()
127
128  foreach(lib ${libs})
129    if(TARGET ${lib})
130      target_link_libraries(${lib} INTERFACE ${LLVM_COMMON_LIBS})
131
132      if (NOT LLVM_INSTALL_TOOLCHAIN_ONLY OR ARG_INSTALL_WITH_TOOLCHAIN)
133        get_target_export_arg(${name} Clang export_to_clangtargets UMBRELLA clang-libraries)
134        install(TARGETS ${lib}
135          COMPONENT ${lib}
136          ${export_to_clangtargets}
137          LIBRARY DESTINATION lib${LLVM_LIBDIR_SUFFIX}
138          ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX}
139          RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
140
141        if (NOT LLVM_ENABLE_IDE)
142          add_llvm_install_targets(install-${lib}
143                                   DEPENDS ${lib}
144                                   COMPONENT ${lib})
145        endif()
146
147        set_property(GLOBAL APPEND PROPERTY CLANG_LIBS ${lib})
148      endif()
149      set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${lib})
150    else()
151      # Add empty "phony" target
152      add_custom_target(${lib})
153    endif()
154  endforeach()
155
156  set_clang_windows_version_resource_properties(${name})
157endmacro(add_clang_library)
158
159macro(add_clang_executable name)
160  add_llvm_executable( ${name} ${ARGN} )
161  set_clang_windows_version_resource_properties(${name})
162  set_target_properties(${name} PROPERTIES XCODE_GENERATE_SCHEME ON)
163endmacro(add_clang_executable)
164
165macro(add_clang_tool name)
166  cmake_parse_arguments(ARG "DEPENDS;GENERATE_DRIVER" "" "" ${ARGN})
167  if (NOT CLANG_BUILD_TOOLS)
168    set(EXCLUDE_FROM_ALL ON)
169  endif()
170  if(ARG_GENERATE_DRIVER
171     AND LLVM_TOOL_LLVM_DRIVER_BUILD
172     AND (NOT LLVM_DISTRIBUTION_COMPONENTS OR ${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS)
173    )
174    set(get_obj_args ${ARGN})
175    list(FILTER get_obj_args EXCLUDE REGEX "^SUPPORT_PLUGINS$")
176    generate_llvm_objects(${name} ${get_obj_args})
177    add_custom_target(${name} DEPENDS llvm-driver clang-resource-headers)
178  else()
179    add_clang_executable(${name} ${ARGN})
180    add_dependencies(${name} clang-resource-headers)
181
182    if (CLANG_BUILD_TOOLS)
183      get_target_export_arg(${name} Clang export_to_clangtargets)
184      install(TARGETS ${name}
185        ${export_to_clangtargets}
186        RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
187        COMPONENT ${name})
188
189      if(NOT LLVM_ENABLE_IDE)
190        add_llvm_install_targets(install-${name}
191                                 DEPENDS ${name}
192                                 COMPONENT ${name})
193      endif()
194      set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${name})
195    endif()
196  endif()
197  set_target_properties(${name} PROPERTIES XCODE_GENERATE_SCHEME ON)
198endmacro()
199
200macro(add_clang_symlink name dest)
201  get_property(LLVM_DRIVER_TOOLS GLOBAL PROPERTY LLVM_DRIVER_TOOLS)
202  if(LLVM_TOOL_LLVM_DRIVER_BUILD
203     AND ${dest} IN_LIST LLVM_DRIVER_TOOLS
204     AND (NOT LLVM_DISTRIBUTION_COMPONENTS OR ${dest} IN_LIST LLVM_DISTRIBUTION_COMPONENTS)
205    )
206    set_property(GLOBAL APPEND PROPERTY LLVM_DRIVER_TOOL_ALIASES_${dest} ${name})
207  else()
208    llvm_add_tool_symlink(CLANG ${name} ${dest} ALWAYS_GENERATE)
209    # Always generate install targets
210    llvm_install_symlink(CLANG ${name} ${dest} ALWAYS_GENERATE)
211  endif()
212endmacro()
213
214function(clang_target_link_libraries target type)
215  if (TARGET obj.${target})
216    target_link_libraries(obj.${target} ${ARGN})
217  endif()
218
219  get_property(LLVM_DRIVER_TOOLS GLOBAL PROPERTY LLVM_DRIVER_TOOLS)
220  if(LLVM_TOOL_LLVM_DRIVER_BUILD AND ${target} IN_LIST LLVM_DRIVER_TOOLS)
221    set(target llvm-driver)
222  endif()
223
224  if (CLANG_LINK_CLANG_DYLIB)
225    target_link_libraries(${target} ${type} clang-cpp)
226  else()
227    target_link_libraries(${target} ${type} ${ARGN})
228  endif()
229endfunction()
230