
The `ARCHIVE` artifact kind is not valid for `install(FILES ...)`. Additionally, install wasn't resolving the target's `TARGET_FILE` properly and was trying to find it in the top-level build directory, rather than in the libclc binary directory. This is because our `TARGET_FILE` properties were being set to relative paths. The cmake behaviour they are trying to mimic - `$<TARGET_FILE:$tgt>` - provides an absolute path. As such this patch updates instances where we set the `TARGET_FILE` property to return an absolute path.
181 lines
5.2 KiB
CMake
181 lines
5.2 KiB
CMake
# Compiles an OpenCL C - or assembles an LL file - to bytecode
|
|
#
|
|
# Arguments:
|
|
# * TRIPLE <string>
|
|
# Target triple for which to compile the bytecode file.
|
|
# * INPUT <string>
|
|
# File to compile/assemble to bytecode
|
|
# * OUTPUT <string>
|
|
# Bytecode file to generate
|
|
# * EXTRA_OPTS <string> ...
|
|
# List of compiler options to use. Note that some are added by default.
|
|
# * DEPENDENCIES <string> ...
|
|
# List of extra dependencies to inject
|
|
#
|
|
# Depends on the clang, llvm-as, and llvm-link targets for compiling,
|
|
# assembling, and linking, respectively.
|
|
function(compile_to_bc)
|
|
cmake_parse_arguments(ARG
|
|
""
|
|
"TRIPLE;INPUT;OUTPUT"
|
|
"EXTRA_OPTS;DEPENDENCIES"
|
|
${ARGN}
|
|
)
|
|
|
|
# If this is an LLVM IR file (identified soley by its file suffix),
|
|
# pre-process it with clang to a temp file, then assemble that to bytecode.
|
|
set( TMP_SUFFIX )
|
|
get_filename_component( FILE_EXT ${ARG_INPUT} EXT )
|
|
if( NOT ${FILE_EXT} STREQUAL ".ll" )
|
|
# Pass '-c' when not running the preprocessor
|
|
set( PP_OPTS -c )
|
|
else()
|
|
set( PP_OPTS -E;-P )
|
|
set( TMP_SUFFIX .tmp )
|
|
endif()
|
|
|
|
set( TARGET_ARG )
|
|
if( ARG_TRIPLE )
|
|
set( TARGET_ARG "-target" ${ARG_TRIPLE} )
|
|
endif()
|
|
|
|
# Ensure the directory we are told to output to exists
|
|
get_filename_component( ARG_OUTPUT_DIR ${ARG_OUTPUT} DIRECTORY )
|
|
file( MAKE_DIRECTORY ${ARG_OUTPUT_DIR} )
|
|
|
|
add_custom_command(
|
|
OUTPUT ${ARG_OUTPUT}${TMP_SUFFIX}
|
|
COMMAND ${clang_exe}
|
|
${TARGET_ARG}
|
|
${PP_OPTS}
|
|
${ARG_EXTRA_OPTS}
|
|
-MD -MF ${ARG_OUTPUT}.d -MT ${ARG_OUTPUT}${TMP_SUFFIX}
|
|
# LLVM 13 enables standard includes by default - we don't want
|
|
# those when pre-processing IR. We disable it unconditionally.
|
|
$<$<VERSION_GREATER_EQUAL:${LLVM_PACKAGE_VERSION},13.0.0>:-cl-no-stdinc>
|
|
-emit-llvm
|
|
-o ${ARG_OUTPUT}${TMP_SUFFIX}
|
|
-x cl
|
|
${ARG_INPUT}
|
|
DEPENDS
|
|
${clang_target}
|
|
${ARG_INPUT}
|
|
${ARG_DEPENDENCIES}
|
|
DEPFILE ${ARG_OUTPUT}.d
|
|
)
|
|
|
|
if( ${FILE_EXT} STREQUAL ".ll" )
|
|
add_custom_command(
|
|
OUTPUT ${ARG_OUTPUT}
|
|
COMMAND ${llvm-as_exe} -o ${ARG_OUTPUT} ${ARG_OUTPUT}${TMP_SUFFIX}
|
|
DEPENDS ${llvm-as_target} ${ARG_OUTPUT}${TMP_SUFFIX}
|
|
)
|
|
endif()
|
|
endfunction()
|
|
|
|
# Links together one or more bytecode files
|
|
#
|
|
# Arguments:
|
|
# * TARGET <string>
|
|
# Custom target to create
|
|
# * INPUT <string> ...
|
|
# List of bytecode files to link together
|
|
# * DEPENDENCIES <string> ...
|
|
# List of extra dependencies to inject
|
|
function(link_bc)
|
|
cmake_parse_arguments(ARG
|
|
""
|
|
"TARGET"
|
|
"INPUTS;DEPENDENCIES"
|
|
${ARGN}
|
|
)
|
|
|
|
set( LINK_INPUT_ARG ${ARG_INPUTS} )
|
|
if( WIN32 OR CYGWIN )
|
|
# Create a response file in case the number of inputs exceeds command-line
|
|
# character limits on certain platforms.
|
|
file( TO_CMAKE_PATH ${LIBCLC_ARCH_OBJFILE_DIR}/${ARG_TARGET}.rsp RSP_FILE )
|
|
# Turn it into a space-separate list of input files
|
|
list( JOIN ARG_INPUTS " " RSP_INPUT )
|
|
file( WRITE ${RSP_FILE} ${RSP_INPUT} )
|
|
# Ensure that if this file is removed, we re-run CMake
|
|
set_property( DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS
|
|
${RSP_FILE}
|
|
)
|
|
set( LINK_INPUT_ARG "@${RSP_FILE}" )
|
|
endif()
|
|
|
|
add_custom_command(
|
|
OUTPUT ${ARG_TARGET}.bc
|
|
COMMAND ${llvm-link_exe} -o ${ARG_TARGET}.bc ${LINK_INPUT_ARG}
|
|
DEPENDS ${llvm-link_target} ${ARG_DEPENDENCIES} ${ARG_INPUTS} ${RSP_FILE}
|
|
)
|
|
|
|
add_custom_target( ${ARG_TARGET} ALL DEPENDS ${ARG_TARGET}.bc )
|
|
set_target_properties( ${ARG_TARGET} PROPERTIES
|
|
TARGET_FILE ${CMAKE_CURRENT_BINARY_DIR}/${ARG_TARGET}.bc
|
|
FOLDER "libclc/Device IR/Linking"
|
|
)
|
|
endfunction()
|
|
|
|
# Decomposes and returns variables based on a libclc triple and architecture
|
|
# combination. Returns data via one or more optional output variables.
|
|
#
|
|
# Arguments:
|
|
# * TRIPLE <string>
|
|
# libclc target triple to query
|
|
# * DEVICE <string>
|
|
# libclc device to query
|
|
#
|
|
# Optional Arguments:
|
|
# * CPU <var>
|
|
# Variable name to be set to the target CPU
|
|
# * ARCH_SUFFIX <var>
|
|
# Variable name to be set to the triple/architecture suffix
|
|
# * CLANG_TRIPLE <var>
|
|
# Variable name to be set to the normalized clang triple
|
|
function(get_libclc_device_info)
|
|
cmake_parse_arguments(ARG
|
|
""
|
|
"TRIPLE;DEVICE;CPU;ARCH_SUFFIX;CLANG_TRIPLE"
|
|
""
|
|
${ARGN}
|
|
)
|
|
|
|
if( NOT ARG_TRIPLE OR NOT ARG_DEVICE )
|
|
message( FATAL_ERROR "Must provide both TRIPLE and DEVICE" )
|
|
endif()
|
|
|
|
string( REPLACE "-" ";" TRIPLE ${ARG_TRIPLE} )
|
|
list( GET TRIPLE 0 ARCH )
|
|
|
|
# Some targets don't have a specific device architecture to target
|
|
if( ARG_DEVICE STREQUAL none OR ARCH STREQUAL spirv OR ARCH STREQUAL spirv64 )
|
|
set( cpu )
|
|
set( arch_suffix "${ARG_TRIPLE}" )
|
|
else()
|
|
set( cpu "${ARG_DEVICE}" )
|
|
set( arch_suffix "${ARG_DEVICE}-${ARG_TRIPLE}" )
|
|
endif()
|
|
|
|
if( ARG_CPU )
|
|
set( ${ARG_CPU} ${cpu} PARENT_SCOPE )
|
|
endif()
|
|
|
|
if( ARG_ARCH_SUFFIX )
|
|
set( ${ARG_ARCH_SUFFIX} ${arch_suffix} PARENT_SCOPE )
|
|
endif()
|
|
|
|
# Some libclc targets are not real clang triples: return their canonical
|
|
# triples.
|
|
if( ARCH STREQUAL spirv OR ARCH STREQUAL clspv )
|
|
set( ARG_TRIPLE "spir--" )
|
|
elseif( ARCH STREQUAL spirv64 OR ARCH STREQUAL clspv64 )
|
|
set( ARG_TRIPLE "spir64--" )
|
|
endif()
|
|
|
|
if( ARG_CLANG_TRIPLE )
|
|
set( ${ARG_CLANG_TRIPLE} ${ARG_TRIPLE} PARENT_SCOPE )
|
|
endif()
|
|
endfunction()
|