summaryrefslogtreecommitdiffstats
path: root/cmake/LLVM.cmake
blob: d707d36058135e9bcd31f7df4ed743ed46046fa3 (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
# A convenience on top of the llvm package's cmake files, this creates a target
# to pass to target_link_libraries which correctly pulls in the llvm include
# dir and other compile dependencies
function(llvm_target_from_components target_name)
    set(components ${ARGN})
    llvm_map_components_to_libnames(llvm_libs
        ${components}
    )
    add_library(${target_name} INTERFACE)
    target_link_libraries(${target_name} INTERFACE ${llvm_libs})
    target_include_directories(
        ${target_name}
        SYSTEM
        INTERFACE ${LLVM_INCLUDE_DIRS}
    )
    target_compile_definitions(${target_name} INTERFACE ${LLVM_DEFINITIONS})
    if(NOT LLVM_ENABLE_RTTI)
        # Make sure that we don't disable rtti if this library wasn't compiled with
        # support
        add_supported_cxx_flags(${target_name} INTERFACE -fno-rtti /GR-)
    endif()
endfunction()

# The same for clang
function(clang_target_from_libs target_name)
    set(clang_libs ${ARGN})
    add_library(${target_name} INTERFACE)
    target_link_libraries(${target_name} INTERFACE ${clang_libs})
    target_include_directories(
        ${target_name}
        SYSTEM
        INTERFACE ${CLANG_INCLUDE_DIRS}
    )
    target_compile_definitions(${target_name} INTERFACE ${CLANG_DEFINITIONS})
    if(NOT LLVM_ENABLE_RTTI)
        # Make sure that we don't disable rtti if this library wasn't compiled with
        # support
        add_supported_cxx_flags(${target_name} INTERFACE -fno-rtti /GR-)
    endif()
endfunction()

function(fetch_or_build_slang_llvm)
    if(SLANG_SLANG_LLVM_FLAVOR STREQUAL "FETCH_BINARY")
        install_fetched_shared_library(
            "slang-llvm"
            "${SLANG_SLANG_LLVM_BINARY_URL}"
        )
    elseif(SLANG_SLANG_LLVM_FLAVOR STREQUAL "FETCH_BINARY_IF_POSSIBLE")
        if(SLANG_SLANG_LLVM_BINARY_URL)
            install_fetched_shared_library(
                "slang-llvm"
                "${SLANG_SLANG_LLVM_BINARY_URL}"
                IGNORE_FAILURE
            )
            if(NOT TARGET slang-llvm)
                message(
                    WARNING
                    "Unable to fetch slang-llvm prebuilt binary, configuring without LLVM support"
                )
            endif()
        endif()
    elseif(SLANG_SLANG_LLVM_FLAVOR STREQUAL "USE_SYSTEM_LLVM")
        find_package(LLVM 13.0 REQUIRED CONFIG)
        find_package(Clang REQUIRED CONFIG)

        llvm_target_from_components(llvm-dep filecheck native orcjit)
        clang_target_from_libs(
            clang-dep
            clangBasic
            clangCodeGen
            clangDriver
            clangLex
            clangFrontend
            clangFrontendTool
        )
        slang_add_target(
            source/slang-llvm
            MODULE
            LINK_WITH_PRIVATE core compiler-core llvm-dep clang-dep
            # We include slang.h, but don't need to link with it
            INCLUDE_FROM_PRIVATE slang
            # We include tools/slang-test/filecheck.h, but don't need to link
            # with it and it might not be a target if SLANG_ENABLE_TESTS is
            # false, so just include the directory manually here
            INCLUDE_DIRECTORIES_PRIVATE ${slang_SOURCE_DIR}/tools
            # This uses the SLANG_DLL_EXPORT macro from slang.h, so make sure to set
            # SLANG_DYNAMIC and SLANG_DYNAMIC_EXPORT
            EXPORT_MACRO_PREFIX SLANG
            INSTALL
            INSTALL_COMPONENT slang-llvm
            EXPORT_SET_NAME SlangTargets
        )
        # If we don't include this, then the symbols in the LLVM linked here may
        # conflict with those of other LLVMs linked at runtime, for instance in mesa.
        add_supported_cxx_linker_flags(
            slang-llvm
            PRIVATE
            "-Wl,--exclude-libs,ALL"
        )

        # The LLVM headers need a warning disabling, which somehow slips through \external
        if(MSVC)
            target_compile_options(slang-llvm PRIVATE -wd4244)
        endif()

        # TODO: Put a check here that libslang-llvm.so doesn't have a 'NEEDED'
        # directive for libLLVM-13.so, it's almost certainly going to break at
        # runtime in surprising ways when linked alongside Mesa (or anything else
        # pulling in libLLVM.so)
    endif()

    if(SLANG_ENABLE_PREBUILT_BINARIES)
        if(CMAKE_SYSTEM_NAME MATCHES "Windows")
            file(
                GLOB prebuilt_binaries
                "${slang_SOURCE_DIR}/external/slang-binaries/bin/windows-x64/*"
            )
            list(REMOVE_ITEM prebuilt_binaries ${prebuilt_d3d12_binaries})
            add_custom_target(
                copy-prebuilt-binaries
                ALL
                COMMAND
                    ${CMAKE_COMMAND} -E make_directory
                    ${CMAKE_BINARY_DIR}/$<CONFIG>/${runtime_subdir}
                COMMAND
                    ${CMAKE_COMMAND} -E copy_if_different ${prebuilt_binaries}
                    ${CMAKE_BINARY_DIR}/$<CONFIG>/${runtime_subdir}
                VERBATIM
            )
            set_target_properties(
                copy-prebuilt-binaries
                PROPERTIES FOLDER external
            )
        endif()
    endif()
endfunction()