[llvm-shlib] Fix the version naming style of libLLVM for Windows (#85710)
[llvm-project.git] / libclc / CMakeLists.txt
blobfa1d8e4adbcc4fb380d7cf3c60e4726c0755b8f7
1 cmake_minimum_required(VERSION 3.20.0)
3 project( libclc VERSION 0.2.0 LANGUAGES CXX C)
5 set(CMAKE_CXX_STANDARD 17)
7 include( GNUInstallDirs )
8 set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
9   amdgcn-amdhsa/lib/SOURCES;
10   amdgcn/lib/SOURCES;
11   amdgcn-mesa3d/lib/SOURCES;
12   amdgpu/lib/SOURCES;
13   clspv/lib/SOURCES;
14   clspv64/lib/SOURCES;
15   generic/lib/SOURCES;
16   ptx/lib/SOURCES;
17   ptx-nvidiacl/lib/SOURCES;
18   r600/lib/SOURCES;
19   spirv/lib/SOURCES;
20   spirv64/lib/SOURCES
23 # List of all targets
24 set( LIBCLC_TARGETS_ALL
25   amdgcn--
26   amdgcn--amdhsa
27   clspv--
28   clspv64--
29   r600--
30   nvptx--
31   nvptx64--
32   nvptx--nvidiacl
33   nvptx64--nvidiacl
34   spirv-mesa3d-
35   spirv64-mesa3d-
38 set( LIBCLC_MIN_LLVM "3.9.0" )
40 set( LIBCLC_TARGETS_TO_BUILD "all"
41     CACHE STRING "Semicolon-separated list of targets to build, or 'all'." )
43 option( ENABLE_RUNTIME_SUBNORMAL "Enable runtime linking of subnormal support."
44 OFF )
46 find_package(LLVM REQUIRED HINTS "${LLVM_CMAKE_DIR}")
47 include(AddLLVM)
49 message( "LLVM version: ${LLVM_PACKAGE_VERSION}" )
51 if( ${LLVM_PACKAGE_VERSION} VERSION_LESS ${LIBCLC_MIN_LLVM} )
52         message( FATAL_ERROR "libclc needs at least LLVM ${LIBCLC_MIN_LLVM}" )
53 endif()
55 # mesa3d environment is only available since LLVM 4.0
56 if( ${LLVM_PACKAGE_VERSION} VERSION_GREATER "3.9.0" )
57         set( LIBCLC_TARGETS_ALL ${LIBCLC_TARGETS_ALL} amdgcn-mesa-mesa3d )
58 endif()
60 if( LIBCLC_TARGETS_TO_BUILD STREQUAL "all" )
61         set( LIBCLC_TARGETS_TO_BUILD ${LIBCLC_TARGETS_ALL} )
62 endif()
64 find_program( LLVM_CLANG clang PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
65 find_program( LLVM_AS llvm-as PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
66 find_program( LLVM_LINK llvm-link PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
67 find_program( LLVM_OPT opt PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
68 find_program( LLVM_SPIRV llvm-spirv PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH )
70 # Print toolchain
71 message( "clang: ${LLVM_CLANG}" )
72 message( "llvm-as: ${LLVM_AS}" )
73 message( "llvm-link: ${LLVM_LINK}" )
74 message( "opt: ${LLVM_OPT}" )
75 message( "llvm-spirv: ${LLVM_SPIRV}" )
76 message( "" )
77 if( NOT LLVM_CLANG OR NOT LLVM_OPT OR NOT LLVM_AS OR NOT LLVM_LINK )
78         message( FATAL_ERROR "toolchain incomplete!" )
79 endif()
81 list( SORT LIBCLC_TARGETS_TO_BUILD )
83 if( "spirv-mesa3d-" IN_LIST LIBCLC_TARGETS_TO_BUILD OR "spirv64-mesa3d-" IN_LIST LIBCLC_TARGETS_TO_BUILD )
84         if( NOT LLVM_SPIRV )
85                 message( FATAL_ERROR "SPIR-V targets requested, but spirv-tools is not installed" )
86         endif()
87 endif()
89 set( CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake )
90 set( CMAKE_CLC_COMPILER ${LLVM_CLANG} )
91 set( CMAKE_CLC_ARCHIVE ${LLVM_LINK} )
92 set( CMAKE_LLAsm_PREPROCESSOR ${LLVM_CLANG} )
93 set( CMAKE_LLAsm_COMPILER ${LLVM_AS} )
94 set( CMAKE_LLAsm_ARCHIVE ${LLVM_LINK} )
96 # Construct LLVM version define
97 set( LLVM_VERSION_DEFINE "-DHAVE_LLVM=0x${LLVM_VERSION_MAJOR}0${LLVM_VERSION_MINOR}" )
100 # LLVM 13 enables standard includes by default
101 if( ${LLVM_PACKAGE_VERSION} VERSION_GREATER "12.99.99" )
102                                 set( CMAKE_LLAsm_FLAGS "${CMAKE_LLAsm_FLAGS} -cl-no-stdinc")
103                                 set( CMAKE_CLC_FLAGS "${CMAKE_CLC_FLAGS} -cl-no-stdinc")
104 endif()
106 enable_language( CLC LLAsm )
107 # This needs to be set before any target that needs it
108 # We need to use LLVM_INCLUDE_DIRS here, because if we are linking to an
109 # llvm build directory, this includes $src/llvm/include which is where all the
110 # headers are not $build/include/ which is what LLVM_INCLUDE_DIR is set to.
111 include_directories( ${LLVM_INCLUDE_DIRS} )
113 # Setup prepare_builtins tools
114 set(LLVM_LINK_COMPONENTS
115   BitReader
116   BitWriter
117   Core
118   Support
120 add_llvm_executable( prepare_builtins utils/prepare-builtins.cpp )
121 target_compile_definitions( prepare_builtins PRIVATE ${LLVM_VERSION_DEFINE} )
122 # These were not properly reported in early LLVM and we don't need them
123 target_compile_options( prepare_builtins PRIVATE -fno-rtti -fno-exceptions )
125 # Setup arch devices
126 set( r600--_devices cedar cypress barts cayman )
127 set( amdgcn--_devices tahiti )
128 set( amdgcn-mesa-mesa3d_devices ${amdgcn--_devices} )
129 set( amdgcn--amdhsa_devices none )
130 set( clspv--_devices none )
131 set( clspv64--_devices none )
132 set( nvptx--_devices none )
133 set( nvptx64--_devices none )
134 set( nvptx--nvidiacl_devices none )
135 set( nvptx64--nvidiacl_devices none )
136 set( spirv-mesa3d-_devices none )
137 set( spirv64-mesa3d-_devices none )
139 # Setup aliases
140 set( cedar_aliases palm sumo sumo2 redwood juniper )
141 set( cypress_aliases hemlock )
142 set( barts_aliases turks caicos )
143 set( cayman_aliases aruba )
144 set( tahiti_aliases pitcairn verde oland hainan bonaire kabini kaveri hawaii
145         mullins tonga tongapro iceland carrizo fiji stoney polaris10 polaris11
146         gfx602 gfx705 gfx805
147         gfx900 gfx902 gfx904 gfx906 gfx908 gfx909 gfx90a gfx90c gfx940 gfx941 gfx942
148         gfx1010 gfx1011 gfx1012 gfx1013
149         gfx1030 gfx1031 gfx1032 gfx1033 gfx1034 gfx1035 gfx1036
150         gfx1100 gfx1101 gfx1102 gfx1103
151         gfx1150 gfx1151
152         gfx1200 gfx1201
155 # pkg-config file
156 configure_file( libclc.pc.in libclc.pc @ONLY )
157 install( FILES ${CMAKE_CURRENT_BINARY_DIR}/libclc.pc DESTINATION "${CMAKE_INSTALL_DATADIR}/pkgconfig" )
158 install( DIRECTORY generic/include/clc DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}" )
160 if( ENABLE_RUNTIME_SUBNORMAL )
161         add_library( subnormal_use_default STATIC
162                 generic/lib/subnormal_use_default.ll )
163         add_library( subnormal_disable STATIC
164                 generic/lib/subnormal_disable.ll )
165         install( TARGETS subnormal_use_default subnormal_disable ARCHIVE
166                 DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" )
167 endif()
169 find_package( Python3 REQUIRED COMPONENTS Interpreter )
170 file( TO_CMAKE_PATH ${CMAKE_SOURCE_DIR}/generic/lib/gen_convert.py script_loc )
171 add_custom_command(
172         OUTPUT convert.cl
173         COMMAND ${Python3_EXECUTABLE} ${script_loc} > convert.cl
174         DEPENDS ${script_loc} )
175 add_custom_target( "generate_convert.cl" DEPENDS convert.cl )
177 enable_testing()
179 foreach( t ${LIBCLC_TARGETS_TO_BUILD} )
180         message( "BUILDING ${t}" )
181         string( REPLACE "-" ";" TRIPLE  ${t} )
182         list( GET TRIPLE 0 ARCH )
183         list( GET TRIPLE 1 VENDOR )
184         list( GET TRIPLE 2 OS )
186         set( dirs )
188         if ( NOT ${ARCH} STREQUAL spirv AND NOT ${ARCH} STREQUAL spirv64 AND
189                          NOT ${ARCH} STREQUAL clspv AND NOT ${ARCH} STREQUAL clspv64)
190                 LIST( APPEND dirs generic )
191         endif()
193         if( ${ARCH} STREQUAL r600 OR ${ARCH} STREQUAL amdgcn )
194                 list( APPEND dirs amdgpu )
195         endif()
197         #nvptx is special
198         if( ${ARCH} STREQUAL nvptx OR ${ARCH} STREQUAL nvptx64 )
199                 set( DARCH ptx )
200         else()
201                 set( DARCH ${ARCH} )
202         endif()
204         # Enumerate SOURCES* files
205         set( source_list )
206         foreach( l ${dirs} ${DARCH} ${DARCH}-${OS} ${DARCH}-${VENDOR}-${OS} )
207                 foreach( s "SOURCES" "SOURCES_${LLVM_MAJOR}.${LLVM_MINOR}" )
208                         file( TO_CMAKE_PATH ${l}/lib/${s} file_loc )
209                         file( TO_CMAKE_PATH ${CMAKE_SOURCE_DIR}/${file_loc} loc )
210                         # Prepend the location to give higher priority to
211                         # specialized implementation
212                         if( EXISTS ${loc} )
213                                 set( source_list ${file_loc} ${source_list} )
214                         endif()
215                 endforeach()
216         endforeach()
218         # Add the generated convert.cl here to prevent adding
219         # the one listed in SOURCES
220         if( NOT ${ARCH} STREQUAL "spirv" AND NOT ${ARCH} STREQUAL "spirv64" )
221                 set( rel_files convert.cl )
222                 set( objects convert.cl )
223                 if( NOT ENABLE_RUNTIME_SUBNORMAL AND NOT ${ARCH} STREQUAL "clspv" AND
224                     NOT ${ARCH} STREQUAL "clspv64" )
225                         list( APPEND rel_files generic/lib/subnormal_use_default.ll )
226                 endif()
227         else()
228                 set( rel_files )
229                 set( objects )
230         endif()
232         foreach( l ${source_list} )
233                 file( READ ${l} file_list )
234                 string( REPLACE "\n" ";" file_list ${file_list} )
235                 get_filename_component( dir ${l} DIRECTORY )
236                 foreach( f ${file_list} )
237                         list( FIND objects ${f} found )
238                         if( found EQUAL  -1 )
239                                 list( APPEND objects ${f} )
240                                 list( APPEND rel_files ${dir}/${f} )
241                                 # FIXME: This should really go away
242                                 file( TO_CMAKE_PATH ${CMAKE_SOURCE_DIR}/${dir}/${f} src_loc )
243                                 get_filename_component( fdir ${src_loc} DIRECTORY )
245                                 set_source_files_properties( ${dir}/${f}
246                                         PROPERTIES COMPILE_FLAGS "-I ${fdir}" )
247                         endif()
248                 endforeach()
249         endforeach()
251         foreach( d ${${t}_devices} )
252                 # Some targets don't have a specific GPU to target
253                 if( ${d} STREQUAL "none" OR ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" )
254                         set( mcpu )
255                         set( arch_suffix "${t}" )
256                 else()
257                         set( mcpu "-mcpu=${d}" )
258                         set( arch_suffix "${d}-${t}" )
259                 endif()
260                 message( "      DEVICE: ${d} ( ${${d}_aliases} )" )
262                 if ( ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" )
263                         if( ${ARCH} STREQUAL "spirv" )
264                                 set( t "spir--" )
265                         else()
266                                 set( t "spir64--" )
267                         endif()
268                         set( build_flags -O0 -finline-hint-functions )
269                         set( opt_flags )
270                         set( spvflags --spirv-max-version=1.1 )
271                 elseif( ${ARCH} STREQUAL "clspv" )
272                         set( t "spir--" )
273                         set( build_flags "-Wno-unknown-assumption")
274                         set( opt_flags -O3 )
275                 elseif( ${ARCH} STREQUAL "clspv64" )
276                         set( t "spir64--" )
277                         set( build_flags "-Wno-unknown-assumption")
278                         set( opt_flags -O3 )
279                 else()
280                         set( build_flags )
281                         set( opt_flags -O3 )
282                 endif()
284                 add_library( builtins.link.${arch_suffix} STATIC ${rel_files} )
285                 # Make sure we depend on the pseudo target to prevent
286                 # multiple invocations
287                 add_dependencies( builtins.link.${arch_suffix}
288                         generate_convert.cl )
289                 # CMake will turn this include into absolute path
290                 target_include_directories( builtins.link.${arch_suffix} PRIVATE
291                         "generic/include" )
292                 target_compile_definitions( builtins.link.${arch_suffix} PRIVATE
293                         "__CLC_INTERNAL" )
294                 string( TOUPPER "-DCLC_${ARCH}" CLC_TARGET_DEFINE )
295                 target_compile_definitions( builtins.link.${arch_suffix} PRIVATE
296                         ${CLC_TARGET_DEFINE} )
297                 target_compile_options( builtins.link.${arch_suffix} PRIVATE  -target
298                         ${t} ${mcpu} -fno-builtin -nostdlib ${build_flags} )
299                 set_target_properties( builtins.link.${arch_suffix} PROPERTIES
300                         LINKER_LANGUAGE CLC )
302                 set( obj_suffix ${arch_suffix}.bc )
304                 # Add opt target
305                 add_custom_command( OUTPUT "builtins.opt.${obj_suffix}"
306                                     COMMAND ${LLVM_OPT} ${opt_flags} -o
307                                     "builtins.opt.${obj_suffix}"
308                                     "builtins.link.${obj_suffix}"
309                                     DEPENDS "builtins.link.${arch_suffix}" )
310                 add_custom_target( "opt.${obj_suffix}" ALL
311                                    DEPENDS "builtins.opt.${obj_suffix}" )
313                 if( ${ARCH} STREQUAL "spirv" OR ${ARCH} STREQUAL "spirv64" )
314                         set( spv_suffix ${arch_suffix}.spv )
315                         add_custom_command( OUTPUT "${spv_suffix}"
316                                             COMMAND ${LLVM_SPIRV} ${spvflags}
317                                             -o "${spv_suffix}"
318                                             "builtins.link.${obj_suffix}"
319                                             DEPENDS "builtins.link.${arch_suffix}" )
320                         add_custom_target( "prepare-${spv_suffix}" ALL
321                                            DEPENDS "${spv_suffix}" )
322                         install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${spv_suffix}
323                                  DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" )
324                 else()
326                         # Add prepare target
327                         add_custom_command( OUTPUT "${obj_suffix}"
328                                             COMMAND prepare_builtins -o
329                                             "${obj_suffix}"
330                                             "builtins.opt.${obj_suffix}"
331                                             DEPENDS "opt.${obj_suffix}"
332                                                     "builtins.opt.${obj_suffix}"
333                                                     prepare_builtins )
334                         add_custom_target( "prepare-${obj_suffix}" ALL
335                                            DEPENDS "${obj_suffix}" )
337                         # nvptx-- targets don't include workitem builtins
338                         if( NOT ${t} MATCHES ".*ptx.*--$" )
339                                 add_test( NAME external-calls-${obj_suffix}
340                                           COMMAND ./check_external_calls.sh ${CMAKE_CURRENT_BINARY_DIR}/${obj_suffix} ${LLVM_TOOLS_BINARY_DIR}
341                                           WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} )
342                         endif()
344                         install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${obj_suffix} DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" )
345                         foreach( a ${${d}_aliases} )
346                                 set( alias_suffix "${a}-${t}.bc" )
347                                 add_custom_target( ${alias_suffix} ALL
348                                                    COMMAND ${CMAKE_COMMAND} -E
349                                                    create_symlink ${obj_suffix}
350                                                    ${alias_suffix}
351                                                    DEPENDS "prepare-${obj_suffix}" )
352                                 install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${alias_suffix} DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" )
353                         endforeach( a )
354                 endif()
355         endforeach( d )
356 endforeach( t )