Commit #87622 broke the build. Ninja was happy with creating the output directories as necessary, but Unix Makefiles isn't. Ensure they are always created. Fixes #88626.
161 lines
4.4 KiB
CMake
161 lines
4.4 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 libclc::clang and libclc::llvm-as targets for compiling and
|
|
# assembling, 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 libclc::clang
|
|
${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
|
|
libclc::clang
|
|
${ARG_INPUT}
|
|
${ARG_DEPENDENCIES}
|
|
DEPFILE ${ARG_OUTPUT}.d
|
|
)
|
|
|
|
if( ${FILE_EXT} STREQUAL ".ll" )
|
|
add_custom_command(
|
|
OUTPUT ${ARG_OUTPUT}
|
|
COMMAND libclc::llvm-as -o ${ARG_OUTPUT} ${ARG_OUTPUT}${TMP_SUFFIX}
|
|
DEPENDS libclc::llvm-as ${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
|
|
function(link_bc)
|
|
cmake_parse_arguments(ARG
|
|
""
|
|
"TARGET"
|
|
"INPUTS"
|
|
${ARGN}
|
|
)
|
|
|
|
add_custom_command(
|
|
OUTPUT ${ARG_TARGET}.bc
|
|
COMMAND libclc::llvm-link -o ${ARG_TARGET}.bc ${ARG_INPUTS}
|
|
DEPENDS libclc::llvm-link ${ARG_INPUTS}
|
|
)
|
|
|
|
add_custom_target( ${ARG_TARGET} ALL DEPENDS ${ARG_TARGET}.bc )
|
|
set_target_properties( ${ARG_TARGET} PROPERTIES TARGET_FILE ${ARG_TARGET}.bc )
|
|
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()
|