1# This tool creates a shared library from the LLVM libraries. Generating this 2# library is enabled by setting LLVM_BUILD_LLVM_DYLIB=yes on the CMake 3# commandline. By default the shared library only exports the LLVM C API. 4 5set(SOURCES 6 libllvm.cpp 7 ) 8 9if(LLVM_LINK_LLVM_DYLIB AND LLVM_DYLIB_EXPORTED_SYMBOL_FILE) 10 message(WARNING "Using LLVM_LINK_LLVM_DYLIB with LLVM_DYLIB_EXPORTED_SYMBOL_FILE may not work. Use at your own risk.") 11endif() 12 13if(LLVM_BUILD_LLVM_DYLIB) 14 if(MSVC AND NOT LLVM_BUILD_LLVM_DYLIB_VIS) 15 message(FATAL_ERROR "Generating libLLVM is not supported on MSVC") 16 endif() 17 if(ZOS) 18 message(FATAL_ERROR "Generating libLLVM is not supported on z/OS") 19 endif() 20 21 llvm_map_components_to_libnames(LIB_NAMES ${LLVM_DYLIB_COMPONENTS}) 22 23 # Exclude libLLVMTableGen for the following reasons: 24 # - it is only used by internal *-tblgen utilities; 25 # - it pollutes the global options space. 26 list(REMOVE_ITEM LIB_NAMES "LLVMTableGen") 27 28 if(LLVM_DYLIB_EXPORTED_SYMBOL_FILE) 29 set(LLVM_EXPORTED_SYMBOL_FILE ${LLVM_DYLIB_EXPORTED_SYMBOL_FILE}) 30 add_custom_target(libLLVMExports DEPENDS ${LLVM_EXPORTED_SYMBOL_FILE}) 31 endif() 32 33 if (LLVM_LINK_LLVM_DYLIB) 34 set(INSTALL_WITH_TOOLCHAIN INSTALL_WITH_TOOLCHAIN) 35 endif() 36 if (WIN32) 37 add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB SONAME ${INSTALL_WITH_TOOLCHAIN} ${SOURCES}) 38 else() 39 add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB OUTPUT_NAME LLVM ${INSTALL_WITH_TOOLCHAIN} ${SOURCES}) 40 # Add symlink for backwards compatibility with old library name 41 llvm_install_library_symlink(LLVM-${LLVM_VERSION_MAJOR}${LLVM_VERSION_SUFFIX} $<TARGET_FILE_NAME:LLVM> SHARED FULL_DEST COMPONENT LLVM) 42 endif() 43 44 list(REMOVE_DUPLICATES LIB_NAMES) 45 if("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin") 46 set(LIB_NAMES -Wl,-all_load ${LIB_NAMES}) 47 else() 48 configure_file( 49 ${CMAKE_CURRENT_SOURCE_DIR}/simple_version_script.map.in 50 ${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map) 51 52 if(MSVC) 53 target_link_directories(LLVM PRIVATE ${LLVM_LIBRARY_DIR}) 54 foreach(library ${LIB_NAMES}) 55 target_link_options(LLVM PRIVATE /WHOLEARCHIVE:${library}.lib) 56 endforeach() 57 else() 58 # GNU ld doesn't resolve symbols in the version script. 59 set(LIB_NAMES -Wl,--whole-archive ${LIB_NAMES} -Wl,--no-whole-archive) 60 if (NOT LLVM_LINKER_IS_SOLARISLD AND NOT MINGW) 61 # Solaris ld does not accept global: *; so there is no way to version *all* global symbols 62 set(LIB_NAMES -Wl,--version-script,${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map ${LIB_NAMES}) 63 endif() 64 if (NOT MINGW AND NOT LLVM_LINKER_IS_SOLARISLD_ILLUMOS) 65 # Optimize function calls for default visibility definitions to avoid PLT and 66 # reduce dynamic relocations. 67 # Note: for -fno-pic default, the address of a function may be different from 68 # inside and outside libLLVM.so. 69 target_link_options(LLVM PRIVATE LINKER:-Bsymbolic-functions) 70 endif() 71 endif() 72 endif() 73 74 target_link_libraries(LLVM PRIVATE ${LIB_NAMES}) 75 76 if(LLVM_ENABLE_THREADS AND NOT HAVE_CXX_ATOMICS64_WITHOUT_LIB) 77 target_link_libraries(LLVM PUBLIC atomic) 78 endif() 79 80 if (APPLE) 81 set_property(TARGET LLVM APPEND_STRING PROPERTY 82 LINK_FLAGS 83 " -compatibility_version 1 -current_version ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}") 84 endif() 85 86 if(TARGET libLLVMExports) 87 add_dependencies(LLVM libLLVMExports) 88 endif() 89endif() 90 91if(LLVM_BUILD_LLVM_C_DYLIB AND NOT MSVC) 92 if(NOT APPLE) 93 message(FATAL_ERROR "Generating libLLVM-c is only supported on Darwin") 94 endif() 95 96 if(NOT LLVM_BUILD_LLVM_DYLIB) 97 message(FATAL_ERROR "Generating libLLVM-c requires LLVM_BUILD_LLVM_C_DYLIB on Darwin") 98 endif() 99 100 # To get the export list for a single llvm library: 101 # nm ${LIB_PATH} | awk "/T _LLVM/ { print $3 }" | sort -u | sed -e "s/^_//g" > ${LIB_PATH}.exports 102 103 set(LLVM_EXPORTED_SYMBOL_FILE ${LLVM_BINARY_DIR}/libllvm-c.exports) 104 105 set(LIB_DIR ${LLVM_LIBRARY_DIR}) 106 set(LIB_NAME ${LIB_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}LLVM) 107 set(LIB_PATH ${LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX}) 108 set(LIB_EXPORTS_PATH ${LIB_NAME}.exports) 109 list(APPEND LLVM_DYLIB_REQUIRED_EXPORTS ${LIB_EXPORTS_PATH}) 110 111 add_custom_command(OUTPUT ${LLVM_EXPORTED_SYMBOL_FILE} 112 COMMAND nm ${LIB_PATH} | awk "/T _LLVM/ || /T LLVM/ { print $3 }" | sort -u | sed -e "s/^_//g" > ${LLVM_EXPORTED_SYMBOL_FILE} 113 WORKING_DIRECTORY ${LIB_DIR} 114 DEPENDS LLVM 115 COMMENT "Generating Export list for LLVM..." 116 VERBATIM ) 117 118 add_custom_target(libLLVMCExports DEPENDS ${LLVM_EXPORTED_SYMBOL_FILE}) 119 120 add_llvm_library(LLVM-C SHARED ${SOURCES} INSTALL_WITH_TOOLCHAIN) 121 122 target_link_libraries(LLVM-C PUBLIC LLVM) 123 add_dependencies(LLVM-C libLLVMCExports) 124 125 set_property(TARGET LLVM-C APPEND_STRING PROPERTY 126 LINK_FLAGS 127 " -compatibility_version 1 -current_version ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH} -Wl,-reexport_library ${LIB_PATH}") 128endif() 129 130if(LLVM_BUILD_LLVM_C_DYLIB AND MSVC) 131 # Build the LLVM-C.dll library that exports the C API. 132 133 set(LLVM_LINK_COMPONENTS 134 ${LLVM_DYLIB_COMPONENTS} 135 ) 136 137 llvm_map_components_to_libnames(LIB_NAMES ${LLVM_DYLIB_COMPONENTS}) 138 list(REMOVE_DUPLICATES LIB_NAMES) 139 140 # The python script needs to know whether symbols are prefixed with underscores or not. 141 if(LLVM_HOST_TRIPLE MATCHES "i?86-.*win.*") 142 set(GEN_UNDERSCORE "--underscore") 143 else() 144 set(GEN_UNDERSCORE "") 145 endif() 146 147 # Set this name here, not used in multi conf loop, 148 # but add script will pick the right one. 149 set(LIBSFILE ${LLVM_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libllvm-c.args) 150 151 # Get the full name to the libs so the python script understands them. 152 foreach(lib ${LIB_NAMES}) 153 list(APPEND FULL_LIB_NAMES ${LLVM_LIBRARY_DIR}/${lib}.lib) 154 endforeach() 155 156 # Need to separate lib names with newlines. 157 string(REPLACE ";" "\n" FILE_CONTENT "${FULL_LIB_NAMES}") 158 159 if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".") 160 foreach(BUILD_MODE ${CMAKE_CONFIGURATION_TYPES}) 161 # Replace the special string with a per config directory. 162 string(REPLACE ${CMAKE_CFG_INTDIR} ${BUILD_MODE} PER_CONF_CONTENT "${FILE_CONTENT}") 163 164 # Write out the full lib names into file to be read by the python script. 165 # One libsfile per build, the add_custom_command should expand 166 # ${CMAKE_CFG_INTDIR} correctly and select the right one. 167 file(WRITE ${LLVM_BINARY_DIR}/${BUILD_MODE}/libllvm-c.args "${PER_CONF_CONTENT}") 168 endforeach() 169 else() 170 # Write out the full lib names into file to be read by the python script. 171 file(WRITE ${LIBSFILE} "${FILE_CONTENT}") 172 endif() 173 174 # Generate the exports file dynamically. 175 set(GEN_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/gen-msvc-exports.py) 176 177 set(LLVM_EXPORTED_SYMBOL_FILE ${LLVM_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libllvm-c.exports) 178 get_host_tool_path(llvm-nm LLVM_NM llvm_nm_exe llvm_nm_target) 179 180 add_custom_command(OUTPUT ${LLVM_EXPORTED_SYMBOL_FILE} 181 COMMAND "${Python3_EXECUTABLE}" ${GEN_SCRIPT} --libsfile ${LIBSFILE} ${GEN_UNDERSCORE} --nm "${llvm_nm_exe}" -o ${LLVM_EXPORTED_SYMBOL_FILE} 182 DEPENDS ${LIB_NAMES} ${llvm_nm_target} 183 COMMENT "Generating export list for LLVM-C" 184 VERBATIM ) 185 186 # Finally link the target. 187 add_llvm_library(LLVM-C SHARED INSTALL_WITH_TOOLCHAIN ${SOURCES} DEPENDS intrinsics_gen) 188 189 if (LLVM_INTEGRATED_CRT_ALLOC AND MSVC) 190 # Make sure we search LLVMSupport first, before the CRT libs 191 set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${CMAKE_CXX_LINKER_WRAPPER_FLAG}-INCLUDE:malloc") 192 endif() 193 194endif() 195