aboutsummaryrefslogtreecommitdiff
path: root/llvm-libgcc/CMakeLists.txt
blob: 013c9ca2e330766acf33a09a624ee4f0bc80f08d (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
#===============================================================================
# Setup Project
#===============================================================================

cmake_minimum_required(VERSION 3.20.0)

set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")

# Check if llvm-libgcc is built as a standalone project
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LLVM_LIBGCC_STANDALONE_BUILD)
  project(llvm-libgcc LANGUAGES C CXX ASM)
  set(COMPILER_RT_STANDALONE_BUILD ON)
  set_property(GLOBAL PROPERTY USE_FOLDERS ON)
  set(LLVM_LIBGCC_COMPILER_RT_BINARY_DIR "compiler-rt")
  set(LLVM_LIBGCC_LIBUNWIND_BINARY_DIR "libunwind")
else()
  set(LLVM_LIBGCC_COMPILER_RT_BINARY_DIR "../compiler-rt")
  set(LLVM_LIBGCC_LIBUNWIND_BINARY_DIR "../libunwind")
endif()

# Add path for custom modules
list(INSERT CMAKE_MODULE_PATH 0
  "${CMAKE_CURRENT_SOURCE_DIR}/cmake"
  "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
  "${CMAKE_CURRENT_SOURCE_DIR}/../runtimes/cmake/Modules"
  "${LLVM_COMMON_CMAKE_UTILS}"
  "${LLVM_COMMON_CMAKE_UTILS}/Modules"
)

set(LLVM_LIBGCC_LIBUNWIND_PATH "${CMAKE_CURRENT_LIST_DIR}/../libunwind"
  CACHE PATH "Specify path to libunwind source.")
set(LLVM_LIBGCC_COMPILER_RT_PATH "${CMAKE_CURRENT_LIST_DIR}/../compiler-rt"
  CACHE PATH "Specify path to compiler-rt source.")

include(GNUInstallDirs)

if(NOT LLVM_LIBGCC_EXPLICIT_OPT_IN)
  message(FATAL_ERROR
    "llvm-libgcc is not for the casual LLVM user. It is intended to be used by distro "
    "managers who want to replace libgcc with compiler-rt and libunwind, but cannot "
    "fully abandon the libgcc family (e.g. because they are dependent on glibc). Such "
    "managers must have worked out their compatibility requirements ahead of using "
    "llvm-libgcc. If you want to build llvm-libgcc, please add -DLLVM_LIBGCC_EXPLICIT_OPT_IN=Yes "
    "to your CMake invocation and try again.")
endif()

if(HAVE_COMPILER_RT)
  message(FATAL_ERROR
    "Attempting to build both compiler-rt and llvm-libgcc will cause irreconcilable "
    "target clashes. Please choose one or the other, but not both.")
endif()

if(HAVE_LIBUNWIND)
  message(FATAL_ERROR
    "Attempting to build both libunwind and llvm-libgcc will cause irreconcilable "
    "target clashes. Please choose one or the other, but not both.")
endif()

#===============================================================================
# Configure System
#===============================================================================

if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE)
  set(LLVM_LIBGCC_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE})
  set(LLVM_LIBGCC_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH
      "Path where built llvm-libgcc libraries should be installed.")
  if(LIBCXX_LIBDIR_SUBDIR)
    string(APPEND LLVM_LIBGCC_LIBRARY_DIR /${LLVM_LIBGCC_LIBDIR_SUBDIR})
    string(APPEND LLVM_LIBGCC_INSTALL_LIBRARY_DIR /${LLVM_LIBGCC_LIBDIR_SUBDIR})
  endif()
else()
  if(LLVM_LIBRARY_OUTPUT_INTDIR)
    set(LLVM_LIBGCC_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR})
  else()
    set(LLVM_LIBGCC_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LLVM_LIBGCC_LIBDIR_SUFFIX})
  endif()
  set(LLVM_LIBGCC_INSTALL_LIBRARY_DIR lib${LLVM_LIBGCC_LIBDIR_SUFFIX} CACHE PATH
      "Path where built llvm-libgcc libraries should be installed.")
endif()

set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LLVM_LIBGCC_LIBRARY_DIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LLVM_LIBGCC_LIBRARY_DIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_LIBGCC_LIBRARY_DIR})

#===============================================================================
# Build libraries
#===============================================================================

set(COMPILER_RT_BUILD_BUILTINS ON)
set(COMPILER_RT_BUILTINS_HIDE_SYMBOLS OFF)
add_subdirectory(${LLVM_LIBGCC_COMPILER_RT_PATH} ${LLVM_LIBGCC_COMPILER_RT_BINARY_DIR})

set(LIBUNWIND_ENABLE_STATIC ON)
set(LIBUNWIND_ENABLE_SHARED ON)
set(LIBUNWIND_USE_COMPILER_RT OFF)
set(LIBUNWIND_HAS_GCC_LIB OFF)
set(LIBUNWIND_HAS_GCC_S_LIB OFF)
add_subdirectory(${LLVM_LIBGCC_LIBUNWIND_PATH} ${LLVM_LIBGCC_LIBUNWIND_BINARY_DIR})

add_custom_target(gcc_s.ver
  SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/gcc_s.ver.in
  COMMAND ${CMAKE_C_COMPILER} -E
    -xc ${CMAKE_CURRENT_SOURCE_DIR}/gcc_s.ver.in
    -o ${CMAKE_CURRENT_BINARY_DIR}/gcc_s.ver
)

add_dependencies(unwind_shared gcc_s.ver)

construct_compiler_rt_default_triple()

target_link_options(unwind_shared PUBLIC
  -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/gcc_s.ver
)

target_link_libraries(unwind_shared PUBLIC
  $<TARGET_OBJECTS:clang_rt.builtins-${COMPILER_RT_DEFAULT_TARGET_ARCH}>
  m
)

#===============================================================================
# Install Symlinks
#===============================================================================

get_compiler_rt_install_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} install_dir_builtins)
string(REGEX REPLACE "^lib/" "" install_dir_builtins "${install_dir_builtins}")
string(FIND "${install_dir_builtins}" "clang" install_path_contains_triple)
if(install_path_contains_triple EQUAL -1)
  set(builtins_suffix "-${COMPILER_RT_DEFAULT_TARGET_ARCH}")
else()
  string(PREPEND install_dir_builtins "../")
endif()
set(LLVM_LIBGCC_COMPILER_RT ${install_dir_builtins}/libclang_rt.builtins${builtins_suffix}.a)

add_custom_target(llvm-libgcc ALL
  DEPENDS unwind_shared unwind_static clang_rt.builtins-${COMPILER_RT_DEFAULT_TARGET_ARCH}
  COMMAND ${CMAKE_COMMAND} -E create_symlink ${LLVM_LIBGCC_COMPILER_RT} libgcc.a
  COMMAND ${CMAKE_COMMAND} -E create_symlink libunwind.a libgcc_eh.a
  COMMAND ${CMAKE_COMMAND} -E create_symlink libunwind.so libgcc_s.so.1.0
  COMMAND ${CMAKE_COMMAND} -E create_symlink libgcc_s.so.1.0 libgcc_s.so.1
  COMMAND ${CMAKE_COMMAND} -E create_symlink libgcc_s.so.1 libgcc_s.so
)

install(TARGETS unwind_shared unwind_static
  LIBRARY DESTINATION ${LLVM_LIBGCC_INSTALL_LIBRARY_DIR} COMPONENT llvm-libgcc
  ARCHIVE DESTINATION ${LLVM_LIBGCC_INSTALL_LIBRARY_DIR} COMPONENT llvm-libgcc
  RUNTIME DESTINATION ${LLVM_LIBGCC_INSTALL_RUNTIME_DIR} COMPONENT llvm-libgcc)

install(TARGETS clang_rt.builtins-${COMPILER_RT_DEFAULT_TARGET_ARCH}
  LIBRARY DESTINATION ${LLVM_LIBGCC_INSTALL_LIBRARY_DIR}/${install_dir_builtins} COMPONENT llvm-libgcc
  ARCHIVE DESTINATION ${LLVM_LIBGCC_INSTALL_LIBRARY_DIR}/${install_dir_builtins} COMPONENT llvm-libgcc
  RUNTIME DESTINATION ${LLVM_LIBGCC_INSTALL_RUNTIME_DIR}/${install_dir_builtins} COMPONENT llvm-libgcc)

foreach(VAR libgcc.a libgcc_eh.a libgcc_s.so.1.0 libgcc_s.so.1 libgcc_s.so)
  install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${VAR}
    DESTINATION ${LLVM_LIBGCC_INSTALL_LIBRARY_DIR}
    COMPONENT llvm-libgcc)
endforeach()