reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    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
# This tool creates a shared library from the LLVM libraries. Generating this
# library is enabled by setting LLVM_BUILD_LLVM_DYLIB=yes on the CMake
# commandline. By default the shared library only exports the LLVM C API.

set(SOURCES
  libllvm.cpp
  )

if(LLVM_LINK_LLVM_DYLIB AND LLVM_DYLIB_EXPORTED_SYMBOL_FILE)
  message(WARNING "Using LLVM_LINK_LLVM_DYLIB with LLVM_DYLIB_EXPORTED_SYMBOL_FILE may not work. Use at your own risk.")
endif()

if(LLVM_BUILD_LLVM_DYLIB)
  if(MSVC)
    message(FATAL_ERROR "Generating libLLVM is not supported on MSVC")
  endif()

  llvm_map_components_to_libnames(LIB_NAMES ${LLVM_DYLIB_COMPONENTS})

  # libLLVM.so should not have any dependencies on any other LLVM
  # shared libraries. When using the "all" pseudo-component,
  # LLVM_AVAILABLE_LIBS is added to the dependencies, which may
  # contain shared libraries (e.g. libLTO).
  #
  # Also exclude libLLVMTableGen for the following reasons:
  #  - it is only used by internal *-tblgen utilities;
  #  - it pollutes the global options space.
  foreach(lib ${LIB_NAMES})
    get_target_property(t ${lib} TYPE)
    if("${lib}" STREQUAL "LLVMTableGen")
    elseif("x${t}" STREQUAL "xSTATIC_LIBRARY")
      list(APPEND FILTERED_LIB_NAMES ${lib})
    endif()
  endforeach()
  set(LIB_NAMES ${FILTERED_LIB_NAMES})

  if(LLVM_DYLIB_EXPORTED_SYMBOL_FILE)
    set(LLVM_EXPORTED_SYMBOL_FILE ${LLVM_DYLIB_EXPORTED_SYMBOL_FILE})
    add_custom_target(libLLVMExports DEPENDS ${LLVM_EXPORTED_SYMBOL_FILE})
  endif()

  if (LLVM_LINK_LLVM_DYLIB)
    set(INSTALL_WITH_TOOLCHAIN INSTALL_WITH_TOOLCHAIN)
  endif()
  add_llvm_library(LLVM SHARED DISABLE_LLVM_LINK_LLVM_DYLIB SONAME ${INSTALL_WITH_TOOLCHAIN} ${SOURCES})

  list(REMOVE_DUPLICATES LIB_NAMES)
  if(("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux") OR (MINGW) OR (HAIKU)
     OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "FreeBSD")
     OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "GNU")
     OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "OpenBSD")
     OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia")
     OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "DragonFly")
     OR ("${CMAKE_SYSTEM_NAME}" STREQUAL "SunOS")) # FIXME: It should be "GNU ld for elf"
    configure_file(
    ${CMAKE_CURRENT_SOURCE_DIR}/simple_version_script.map.in
    ${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map)

    # GNU ld doesn't resolve symbols in the version script.
    set(LIB_NAMES -Wl,--whole-archive ${LIB_NAMES} -Wl,--no-whole-archive)
    if (NOT LLVM_LINKER_IS_SOLARISLD AND NOT MINGW)
      # Solaris ld does not accept global: *; so there is no way to version *all* global symbols
      set(LIB_NAMES -Wl,--version-script,${LLVM_LIBRARY_DIR}/tools/llvm-shlib/simple_version_script.map ${LIB_NAMES})
    endif()
  elseif("${CMAKE_SYSTEM_NAME}" STREQUAL "Darwin")
    set(LIB_NAMES -Wl,-all_load ${LIB_NAMES})
  endif()

  target_link_libraries(LLVM PRIVATE ${LIB_NAMES})

  if (APPLE)
    set_property(TARGET LLVM APPEND_STRING PROPERTY
                LINK_FLAGS
                " -compatibility_version 1 -current_version ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}")
  endif()

  if(TARGET libLLVMExports)
    add_dependencies(LLVM libLLVMExports)
  endif()
endif()

if(LLVM_BUILD_LLVM_C_DYLIB AND NOT MSVC)
  if(NOT APPLE)
    message(FATAL_ERROR "Generating libLLVM-c is only supported on Darwin")
  endif()

  if(NOT LLVM_BUILD_LLVM_DYLIB)
    message(FATAL_ERROR "Generating libLLVM-c requires LLVM_BUILD_LLVM_C_DYLIB on Darwin")
  endif()

  # To get the export list for a single llvm library:
  # nm ${LIB_PATH} | awk "/T _LLVM/ { print $3 }" | sort -u | sed -e "s/^_//g" > ${LIB_PATH}.exports

  set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_BINARY_DIR}/libllvm-c.exports)

  set(LIB_DIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX})
  set(LIB_NAME ${LIB_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}LLVM)
  set(LIB_PATH ${LIB_NAME}${CMAKE_SHARED_LIBRARY_SUFFIX})
  set(LIB_EXPORTS_PATH ${LIB_NAME}.exports)
  list(APPEND LLVM_DYLIB_REQUIRED_EXPORTS ${LIB_EXPORTS_PATH})

  add_custom_command(OUTPUT ${LLVM_EXPORTED_SYMBOL_FILE}
    COMMAND nm ${LIB_PATH} | awk "/T _LLVM/ || /T LLVM/ { print $3 }" | sort -u | sed -e "s/^_//g" > ${LLVM_EXPORTED_SYMBOL_FILE}
    WORKING_DIRECTORY ${LIB_DIR}
    DEPENDS LLVM
    COMMENT "Generating Export list for LLVM..."
    VERBATIM )

  add_custom_target(libLLVMCExports DEPENDS ${LLVM_EXPORTED_SYMBOL_FILE})

  add_llvm_library(LLVM-C SHARED ${SOURCES} INSTALL_WITH_TOOLCHAIN)
  
  target_link_libraries(LLVM-C PUBLIC LLVM)
  add_dependencies(LLVM-C libLLVMCExports)
  
  set_property(TARGET LLVM-C APPEND_STRING PROPERTY
              LINK_FLAGS
              " -compatibility_version 1 -current_version ${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH} -Wl,-reexport_library ${LIB_PATH}")
endif()

if(MSVC)
  # Build the LLVM-C.dll library that exports the C API.

  set(LLVM_LINK_COMPONENTS
    ${LLVM_DYLIB_COMPONENTS}
    )

  llvm_map_components_to_libnames(LIB_NAMES ${LLVM_DYLIB_COMPONENTS})
  list(REMOVE_DUPLICATES LIB_NAMES)

  # The python script needs to know whether symbols are prefixed with underscores or not.
  if(LLVM_HOST_TRIPLE STREQUAL "i686-pc-win32")
    set(GEN_UNDERSCORE "--underscore")
  else()
    set(GEN_UNDERSCORE "")
  endif()

  # Set this name here, not used in multi conf loop,
  # but add script will pick the right one.
  set(LIBSFILE ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libllvm-c.args)

  # Get the full name to the libs so the python script understands them.
  foreach(lib ${LIB_NAMES})
    list(APPEND FULL_LIB_NAMES ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib/${lib}.lib)
  endforeach()

  # Need to seperate lib names with newlines.
  string(REPLACE ";" "\n" FILE_CONTENT "${FULL_LIB_NAMES}")

  if(NOT "${CMAKE_CFG_INTDIR}" STREQUAL ".")
    foreach(BUILD_MODE ${CMAKE_CONFIGURATION_TYPES})
      # Replace the special string with a per config directory.
      string(REPLACE ${CMAKE_CFG_INTDIR} ${BUILD_MODE} PER_CONF_CONTENT "${FILE_CONTENT}")

      # Write out the full lib names into file to be read by the python script.
      # One libsfile per build, the add_custom_command should expand
      # ${CMAKE_CFG_INTDIR} correctly and select the right one.
      file(WRITE ${CMAKE_BINARY_DIR}/${BUILD_MODE}/libllvm-c.args "${PER_CONF_CONTENT}")
    endforeach()
  else()
    # Write out the full lib names into file to be read by the python script.
    file(WRITE ${LIBSFILE} "${FILE_CONTENT}")
  endif()

  # Generate the exports file dynamically.
  set(GEN_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/gen-msvc-exports.py)

  set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/libllvm-c.exports)

  if(CMAKE_CROSSCOMPILING)
    build_native_tool(llvm-nm llvm_nm)
    set(llvm_nm_target "${llvm_nm}")
  else()
    set(llvm_nm $<TARGET_FILE:llvm-nm>)
    set(llvm_nm_target llvm-nm)
  endif()

  add_custom_command(OUTPUT ${LLVM_EXPORTED_SYMBOL_FILE}
    COMMAND ${PYTHON_EXECUTABLE} ${GEN_SCRIPT} --libsfile ${LIBSFILE} ${GEN_UNDERSCORE} --nm "${llvm_nm}" -o ${LLVM_EXPORTED_SYMBOL_FILE}
    DEPENDS ${LIB_NAMES} ${llvm_nm_target}
    COMMENT "Generating export list for LLVM-C"
    VERBATIM )

  # Finally link the target.
  add_llvm_library(LLVM-C SHARED INSTALL_WITH_TOOLCHAIN ${SOURCES} DEPENDS intrinsics_gen)

endif()