aboutsummaryrefslogtreecommitdiff
path: root/libcxx/src/CMakeLists.txt
blob: 1110a79ddcacd511e32a7fd6913f195561a9d3a7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
set(LIBCXX_LIB_CMAKEFILES_DIR "${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}"  PARENT_SCOPE)

# Get sources
set(LIBCXX_SOURCES
  algorithm.cpp
  any.cpp
  bind.cpp
  call_once.cpp
  charconv.cpp
  chrono.cpp
  error_category.cpp
  exception.cpp
  filesystem/filesystem_clock.cpp
  filesystem/filesystem_error.cpp
  filesystem/path_parser.h
  filesystem/path.cpp
  functional.cpp
  hash.cpp
  include/apple_availability.h
  include/atomic_support.h
  include/config_elast.h
  include/refstring.h
  include/ryu/common.h
  include/ryu/d2fixed.h
  include/ryu/d2fixed_full_table.h
  include/ryu/d2s.h
  include/ryu/d2s_full_table.h
  include/ryu/d2s_intrinsics.h
  include/ryu/digit_table.h
  include/ryu/f2s.h
  include/ryu/ryu.h
  include/to_chars_floating_point.h
  legacy_pointer_safety.cpp
  memory.cpp
  memory_resource.cpp
  new_handler.cpp
  new_helpers.cpp
  optional.cpp
  print.cpp
  random_shuffle.cpp
  ryu/d2fixed.cpp
  ryu/d2s.cpp
  ryu/f2s.cpp
  stdexcept.cpp
  string.cpp
  support/runtime/exception_fallback.ipp
  support/runtime/exception_glibcxx.ipp
  support/runtime/exception_libcxxabi.ipp
  support/runtime/exception_libcxxrt.ipp
  support/runtime/exception_msvc.ipp
  support/runtime/exception_pointer_cxxabi.ipp
  support/runtime/exception_pointer_glibcxx.ipp
  support/runtime/exception_pointer_msvc.ipp
  support/runtime/exception_pointer_unimplemented.ipp
  support/runtime/stdexcept_default.ipp
  support/runtime/stdexcept_vcruntime.ipp
  system_error.cpp
  typeinfo.cpp
  valarray.cpp
  variant.cpp
  vector.cpp
  verbose_abort.cpp
  )

if (LIBCXX_ENABLE_THREADS)
  list(APPEND LIBCXX_SOURCES
    atomic.cpp
    barrier.cpp
    condition_variable_destructor.cpp
    condition_variable.cpp
    future.cpp
    mutex_destructor.cpp
    mutex.cpp
    shared_mutex.cpp
    thread.cpp
    )
endif()

if (LIBCXX_ENABLE_RANDOM_DEVICE)
  list(APPEND LIBCXX_SOURCES
    random.cpp
    )
endif()

if (LIBCXX_ENABLE_LOCALIZATION)
  list(APPEND LIBCXX_SOURCES
    fstream.cpp
    include/sso_allocator.h
    ios.cpp
    ios.instantiations.cpp
    iostream.cpp
    locale.cpp
    ostream.cpp
    regex.cpp
    strstream.cpp
    )
endif()

if(WIN32)
  list(APPEND LIBCXX_SOURCES
    support/win32/locale_win32.cpp
    support/win32/support.cpp
    )

  if (NOT LIBCXX_HAS_PTHREAD_API)
    list(APPEND LIBCXX_SOURCES
      support/win32/thread_win32.cpp
      )
  endif()
elseif(ZOS)
  list(APPEND LIBCXX_SOURCES
    support/ibm/mbsnrtowcs.cpp
    support/ibm/wcsnrtombs.cpp
    support/ibm/xlocale_zos.cpp
    )
endif()

if (LIBCXX_ENABLE_FILESYSTEM)
  list(APPEND LIBCXX_SOURCES
    filesystem/directory_entry.cpp
    filesystem/directory_iterator.cpp
    filesystem/file_descriptor.h
    filesystem/operations.cpp
    filesystem/posix_compat.h
    filesystem/time_utils.h
    )
  # Filesystem uses __int128_t, which requires a definition of __muloi4 when
  # compiled with UBSAN. This definition is not provided by libgcc_s, but is
  # provided by compiler-rt. So we need to disable it to avoid having multiple
  # definitions. See filesystem/int128_builtins.cpp.
  if (NOT LIBCXX_USE_COMPILER_RT)
    list(APPEND LIBCXX_SOURCES
      filesystem/int128_builtins.cpp
      )
  endif()
endif()

if (LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS)
  list(APPEND LIBCXX_SOURCES
    new.cpp
    )
endif()

# Add all the headers to the project for IDEs.
if (LIBCXX_CONFIGURE_IDE)
  file(GLOB_RECURSE LIBCXX_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/*)
  if(WIN32)
    file( GLOB LIBCXX_WIN32_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../include/__support/win32/*.h)
    list(APPEND LIBCXX_HEADERS ${LIBCXX_WIN32_HEADERS})
  endif()
  # Force them all into the headers dir on MSVC, otherwise they end up at
  # project scope because they don't have extensions.
  if (MSVC_IDE)
    source_group("Header Files" FILES ${LIBCXX_HEADERS})
  endif()
endif()

if(NOT LIBCXX_INSTALL_LIBRARY)
  set(exclude_from_all EXCLUDE_FROM_ALL)
endif()

if (LIBCXX_GENERATE_COVERAGE AND NOT LIBCXX_COVERAGE_LIBRARY)
  find_compiler_rt_library(profile LIBCXX_COVERAGE_LIBRARY)
endif()
add_library_flags_if(LIBCXX_COVERAGE_LIBRARY "${LIBCXX_COVERAGE_LIBRARY}")

if (APPLE AND LLVM_USE_SANITIZER)
  if (("${LLVM_USE_SANITIZER}" STREQUAL "Address") OR
      ("${LLVM_USE_SANITIZER}" STREQUAL "Address;Undefined") OR
      ("${LLVM_USE_SANITIZER}" STREQUAL "Undefined;Address"))
    set(LIBFILE "libclang_rt.asan_osx_dynamic.dylib")
  elseif("${LLVM_USE_SANITIZER}" STREQUAL "Undefined")
    set(LIBFILE "libclang_rt.ubsan_osx_dynamic.dylib")
  elseif("${LLVM_USE_SANITIZER}" STREQUAL "Thread")
    set(LIBFILE "libclang_rt.tsan_osx_dynamic.dylib")
  else()
    message(WARNING "LLVM_USE_SANITIZER=${LLVM_USE_SANITIZER} is not supported on OS X")
  endif()
  if (LIBFILE)
    find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY)
    get_filename_component(LIBDIR "${LIBCXX_BUILTINS_LIBRARY}" DIRECTORY)
    if (NOT IS_DIRECTORY "${LIBDIR}")
      message(FATAL_ERROR "Cannot find compiler-rt directory on OS X required for LLVM_USE_SANITIZER")
    endif()
    set(LIBCXX_SANITIZER_LIBRARY "${LIBDIR}/${LIBFILE}")
    set(LIBCXX_SANITIZER_LIBRARY "${LIBCXX_SANITIZER_LIBRARY}" PARENT_SCOPE)
    message(STATUS "Manually linking compiler-rt library: ${LIBCXX_SANITIZER_LIBRARY}")
    add_library_flags("${LIBCXX_SANITIZER_LIBRARY}")
    add_link_flags("-Wl,-rpath,${LIBDIR}")
  endif()
endif()

split_list(LIBCXX_COMPILE_FLAGS)
split_list(LIBCXX_LINK_FLAGS)

# Build the shared library.
if (LIBCXX_ENABLE_SHARED)
  add_library(cxx_shared SHARED ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
  target_include_directories(cxx_shared PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
  target_link_libraries(cxx_shared PUBLIC cxx-headers
                                   PRIVATE ${LIBCXX_LIBRARIES})
  set_target_properties(cxx_shared
    PROPERTIES
      COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
      LINK_FLAGS    "${LIBCXX_LINK_FLAGS}"
      OUTPUT_NAME   "${LIBCXX_SHARED_OUTPUT_NAME}"
      VERSION       "${LIBCXX_LIBRARY_VERSION}"
      SOVERSION     "${LIBCXX_ABI_VERSION}"
      DEFINE_SYMBOL ""
  )
  cxx_add_common_build_flags(cxx_shared)

  if(ZOS)
    add_custom_command(TARGET cxx_shared POST_BUILD
      COMMAND
        ${LIBCXX_SOURCE_DIR}/utils/zos_rename_dll_side_deck.sh
        $<TARGET_LINKER_FILE_NAME:cxx_shared> $<TARGET_FILE_NAME:cxx_shared> "${LIBCXX_DLL_NAME}"
      COMMENT "Rename dll name inside the side deck file"
      WORKING_DIRECTORY $<TARGET_FILE_DIR:cxx_shared>
    )
  endif()

  # Link against libc++abi
  if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
    target_link_libraries(cxx_shared PRIVATE libcxx-abi-shared-objects)
  else()
    target_link_libraries(cxx_shared PUBLIC libcxx-abi-shared)
  endif()

  # Maybe re-export symbols from libc++abi
  # In particular, we don't re-export the symbols if libc++abi is merged statically
  # into libc++ because in that case there's no dylib to re-export from.
  if (APPLE AND LIBCXX_CXX_ABI MATCHES "libcxxabi$"
            AND NOT LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
    target_link_libraries(cxx_shared PRIVATE cxxabi-reexports)

    # TODO: These exports controls should not be tied to whether we re-export libc++abi symbols
    target_link_libraries(cxx_shared PRIVATE
      "-Wl,-unexported_symbols_list,${CMAKE_CURRENT_SOURCE_DIR}/../lib/libc++unexp.exp"
      "-Wl,-force_symbols_not_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/../lib/notweak.exp"
      "-Wl,-force_symbols_weak_list,${CMAKE_CURRENT_SOURCE_DIR}/../lib/weak.exp")
  endif()

  # Generate a linker script in place of a libc++.so symlink.
  if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
    set(link_libraries)

    set(imported_libname "$<TARGET_PROPERTY:libcxx-abi-shared,IMPORTED_LIBNAME>")
    set(output_name "$<TARGET_PROPERTY:libcxx-abi-shared,OUTPUT_NAME>")
    string(APPEND link_libraries "${CMAKE_LINK_LIBRARY_FLAG}$<IF:$<BOOL:${imported_libname}>,${imported_libname},${output_name}>")

    # TODO: Move to the same approach as above for the unwind library
    if (LIBCXXABI_USE_LLVM_UNWINDER)
      if (LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY)
        # libunwind is already included in libc++abi
      elseif (TARGET unwind_shared OR HAVE_LIBUNWIND)
        string(APPEND link_libraries " ${CMAKE_LINK_LIBRARY_FLAG}$<TARGET_PROPERTY:unwind_shared,OUTPUT_NAME>")
      else()
        string(APPEND link_libraries " ${CMAKE_LINK_LIBRARY_FLAG}unwind")
      endif()
    endif()

    set(linker_script "INPUT($<TARGET_SONAME_FILE_NAME:cxx_shared> ${link_libraries})")
    add_custom_command(TARGET cxx_shared POST_BUILD
      COMMAND "${CMAKE_COMMAND}" -E remove "$<TARGET_LINKER_FILE:cxx_shared>"
      COMMAND "${CMAKE_COMMAND}" -E echo "${linker_script}" > "$<TARGET_LINKER_FILE:cxx_shared>"
      COMMENT "Generating linker script: '${linker_script}' as file $<TARGET_LINKER_FILE:cxx_shared>"
      VERBATIM
    )
  endif()

  list(APPEND LIBCXX_BUILD_TARGETS "cxx_shared")
  if(WIN32 AND NOT MINGW AND NOT "${CMAKE_HOST_SYSTEM_NAME}" STREQUAL "Windows")
    # Since we most likely do not have a mt.exe replacement, disable the
    # manifest bundling.  This allows a normal cmake invocation to pass which
    # will attempt to use the manifest tool to generate the bundled manifest
    set_target_properties(cxx_shared PROPERTIES
                          APPEND_STRING PROPERTY LINK_FLAGS " /MANIFEST:NO")
  endif()
endif()

set(CMAKE_STATIC_LIBRARY_PREFIX "lib")

# Build the static library.
if (LIBCXX_ENABLE_STATIC)
  add_library(cxx_static STATIC ${exclude_from_all} ${LIBCXX_SOURCES} ${LIBCXX_HEADERS})
  target_include_directories(cxx_static PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
  target_link_libraries(cxx_static PUBLIC cxx-headers
                                   PRIVATE ${LIBCXX_LIBRARIES}
                                   PRIVATE libcxx-abi-static)
  set_target_properties(cxx_static
    PROPERTIES
      COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
      LINK_FLAGS    "${LIBCXX_LINK_FLAGS}"
      OUTPUT_NAME   "${LIBCXX_STATIC_OUTPUT_NAME}"
  )
  cxx_add_common_build_flags(cxx_static)

  if (LIBCXX_HERMETIC_STATIC_LIBRARY)
    # If the hermetic library doesn't define the operator new/delete functions
    # then its code shouldn't declare them with hidden visibility.  They might
    # actually be provided by a shared library at link time.
    if (LIBCXX_ENABLE_NEW_DELETE_DEFINITIONS)
      append_flags_if_supported(CXX_STATIC_LIBRARY_FLAGS -fvisibility-global-new-delete=force-hidden)
      if (NOT CXX_SUPPORTS_FVISIBILITY_GLOBAL_NEW_DELETE_EQ_FORCE_HIDDEN_FLAG)
        append_flags_if_supported(CXX_STATIC_LIBRARY_FLAGS -fvisibility-global-new-delete-hidden)
      endif()
    endif()
    target_compile_options(cxx_static PRIVATE ${CXX_STATIC_LIBRARY_FLAGS})
    # _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS can be defined in __config_site
    # too. Define it in the same way here, to avoid redefinition conflicts.
    target_compile_definitions(cxx_static PRIVATE _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=)
  endif()

  list(APPEND LIBCXX_BUILD_TARGETS "cxx_static")
  # Attempt to merge the libc++.a archive and the ABI library archive into one.
  if (LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY)
    target_link_libraries(cxx_static PRIVATE libcxx-abi-static-objects)
  endif()
endif()

# Add a meta-target for both libraries.
add_custom_target(cxx DEPENDS ${LIBCXX_BUILD_TARGETS})

set(LIBCXX_EXPERIMENTAL_SOURCES
  experimental/keep.cpp
  )

if (LIBCXX_PSTL_CPU_BACKEND STREQUAL "libdispatch")
  list(APPEND LIBCXX_EXPERIMENTAL_SOURCES
    pstl/libdispatch.cpp
    )
endif()

if (LIBCXX_ENABLE_LOCALIZATION AND LIBCXX_ENABLE_FILESYSTEM AND LIBCXX_ENABLE_TIME_ZONE_DATABASE)
  list(APPEND LIBCXX_EXPERIMENTAL_SOURCES
    include/tzdb/time_zone_link_private.h
    include/tzdb/time_zone_private.h
    include/tzdb/types_private.h
    include/tzdb/tzdb_list_private.h
    include/tzdb/tzdb_private.h
    time_zone.cpp
    tzdb.cpp
    tzdb_list.cpp
    )
endif()

add_library(cxx_experimental STATIC ${LIBCXX_EXPERIMENTAL_SOURCES})
target_link_libraries(cxx_experimental PUBLIC cxx-headers)
if (LIBCXX_ENABLE_SHARED)
  target_link_libraries(cxx_experimental PRIVATE cxx_shared)
else()
  target_link_libraries(cxx_experimental PRIVATE cxx_static)
endif()

if (LIBCXX_HERMETIC_STATIC_LIBRARY)
  # _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS can be defined in __config_site
  # too. Define it in the same way here, to avoid redefinition conflicts.
  target_compile_definitions(cxx_experimental PRIVATE _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=)
endif()

set_target_properties(cxx_experimental
  PROPERTIES
    COMPILE_FLAGS "${LIBCXX_COMPILE_FLAGS}"
    OUTPUT_NAME   "c++experimental"
)
cxx_add_common_build_flags(cxx_experimental)
target_compile_options(cxx_experimental PUBLIC -D_LIBCPP_ENABLE_EXPERIMENTAL)

if (LIBCXX_INSTALL_SHARED_LIBRARY)
  install(TARGETS cxx_shared
    ARCHIVE DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
    LIBRARY DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
    RUNTIME DESTINATION ${LIBCXX_INSTALL_RUNTIME_DIR} COMPONENT cxx)
endif()

if (LIBCXX_INSTALL_STATIC_LIBRARY)
  install(TARGETS cxx_static
    ARCHIVE DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
    LIBRARY DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
    RUNTIME DESTINATION ${LIBCXX_INSTALL_RUNTIME_DIR} COMPONENT cxx)
endif()

if (LIBCXX_INSTALL_LIBRARY)
  install(TARGETS cxx_experimental
    LIBRARY DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
    ARCHIVE DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR} COMPONENT cxx
    RUNTIME DESTINATION ${LIBCXX_INSTALL_RUNTIME_DIR} COMPONENT cxx)
endif()

# NOTE: This install command must go after the cxx install command otherwise
# it will not be executed after the library symlinks are installed.
if (LIBCXX_ENABLE_SHARED AND LIBCXX_ENABLE_ABI_LINKER_SCRIPT)
  install(FILES "$<TARGET_LINKER_FILE:cxx_shared>"
    DESTINATION ${LIBCXX_INSTALL_LIBRARY_DIR}
    COMPONENT libcxx)
endif()

if (NOT CMAKE_CONFIGURATION_TYPES)
    if(LIBCXX_INSTALL_LIBRARY)
      set(lib_install_target "cxx;cxx_experimental")
    endif()
    if(LIBCXX_INSTALL_HEADERS)
      set(header_install_target install-cxx-headers)
    endif()
    if(LIBCXX_INSTALL_MODULES)
      set(module_install_target install-cxx-modules)
    endif()
    add_custom_target(install-cxx
                      DEPENDS ${lib_install_target}
                              cxx_experimental
                              ${header_install_target}
                              ${module_install_target}
                      COMMAND "${CMAKE_COMMAND}"
                      -DCMAKE_INSTALL_COMPONENT=cxx
                      -P "${LIBCXX_BINARY_DIR}/cmake_install.cmake")
    add_custom_target(install-cxx-stripped
                      DEPENDS ${lib_install_target}
                              cxx_experimental
                              ${header_install_target}
                              ${module_install_target}
                      COMMAND "${CMAKE_COMMAND}"
                      -DCMAKE_INSTALL_COMPONENT=cxx
                      -DCMAKE_INSTALL_DO_STRIP=1
                      -P "${LIBCXX_BINARY_DIR}/cmake_install.cmake")
endif()