From 1da4cd1755ae6066a9ba23e15678b3cc4b340b27 Mon Sep 17 00:00:00 2001 From: Harald van Dijk Date: Tue, 2 Jul 2024 16:26:58 +0100 Subject: [PATCH] [libclc] Fix cross in-tree builds (#97392) When performing cross in-tree builds, we need native versions of various tools, we cannot assume the cross builds that are part of the current build are executable. LLVM provides the setup_host_tool function to handle this, either picking up versions of tools from LLVM_NATIVE_TOOL_DIR, or implicitly building native versions as needed. Use it for libclc too. LLVM's setup_host_tool function assumes the project is LLVM, so this also needs libclc's project() to be conditional on it being built standalone. Luckily, the only change this needs is using CMAKE_CURRENT_SOURCE_DIR instead of PROJECT_SOURCE_DIR. --- libclc/CMakeLists.txt | 55 +++++++++++++++------------- libclc/cmake/modules/AddLibclc.cmake | 16 ++++---- 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/libclc/CMakeLists.txt b/libclc/CMakeLists.txt index ef8d21b167623a..4f5625ff949168 100644 --- a/libclc/CMakeLists.txt +++ b/libclc/CMakeLists.txt @@ -1,11 +1,13 @@ cmake_minimum_required(VERSION 3.20.0) -project( libclc VERSION 0.2.0 LANGUAGES CXX C) +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + project(libclc VERSION 0.2.0 LANGUAGES CXX C) +endif() set(CMAKE_CXX_STANDARD 17) # Add path for custom modules -list( INSERT CMAKE_MODULE_PATH 0 "${PROJECT_SOURCE_DIR}/cmake/modules" ) +list( INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" ) set( LIBCLC_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} ) set( LIBCLC_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} ) @@ -49,12 +51,12 @@ if( LIBCLC_STANDALONE_BUILD OR CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DI message( FATAL_ERROR "libclc needs at least LLVM ${LIBCLC_MIN_LLVM}" ) endif() - # Import required tools as targets + # Import required tools if( NOT EXISTS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} ) foreach( tool IN ITEMS clang llvm-as llvm-link opt ) find_program( LLVM_TOOL_${tool} ${tool} PATHS ${LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH ) - add_executable( libclc::${tool} IMPORTED GLOBAL ) - set_target_properties( libclc::${tool} PROPERTIES IMPORTED_LOCATION ${LLVM_TOOL_${tool}} ) + set( ${tool}_exe ${LLVM_TOOL_${tool}} ) + set( ${tool}_target ) endforeach() endif() else() @@ -71,9 +73,10 @@ else() endif() if( NOT EXISTS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} ) - foreach( tool IN ITEMS clang llvm-as llvm-link opt ) - add_executable(libclc::${tool} ALIAS ${tool}) - endforeach() + setup_host_tool( clang CLANG clang_exe clang_target ) + setup_host_tool( llvm-as LLVM_AS llvm-as_exe llvm-as_target ) + setup_host_tool( llvm-link LLVM_LINK llvm-link_exe llvm-link_target ) + setup_host_tool( opt OPT opt_exe opt_target ) endif() endif() @@ -88,14 +91,13 @@ if( EXISTS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} ) foreach( tool IN ITEMS clang llvm-as llvm-link opt ) find_program( LLVM_CUSTOM_TOOL_${tool} ${tool} PATHS ${LIBCLC_CUSTOM_LLVM_TOOLS_BINARY_DIR} NO_DEFAULT_PATH ) - add_executable( libclc::${tool} IMPORTED GLOBAL ) - set_target_properties( libclc::${tool} PROPERTIES - IMPORTED_LOCATION ${LLVM_CUSTOM_TOOL_${tool}} ) + set( ${tool}_exe ${LLVM_CUSTOM_TOOL_${tool}} ) + set( ${tool}_target ) endforeach() endif() foreach( tool IN ITEMS clang opt llvm-as llvm-link ) - if( NOT TARGET libclc::${tool} ) + if( NOT EXISTS "${${tool}_exe}" AND NOT TARGET "${${tool}_target}" ) message( FATAL_ERROR "libclc toolchain incomplete - missing tool ${tool}!" ) endif() endforeach() @@ -165,8 +167,11 @@ set(LLVM_LINK_COMPONENTS ) if( LIBCLC_STANDALONE_BUILD ) add_llvm_executable( prepare_builtins utils/prepare-builtins.cpp ) + set( prepare_builtins_exe prepare_builtins ) + set( prepare_builtins_target prepare_builtins ) else() add_llvm_utility( prepare_builtins utils/prepare-builtins.cpp ) + setup_host_tool( prepare_builtins PREPARE_BUILTINS prepare_builtins_exe prepare_builtins_target ) endif() target_compile_definitions( prepare_builtins PRIVATE ${LLVM_VERSION_DEFINE} ) # These were not properly reported in early LLVM and we don't need them @@ -211,7 +216,7 @@ if( ENABLE_RUNTIME_SUBNORMAL ) foreach( file IN ITEMS subnormal_use_default subnormal_disable ) link_bc( TARGET ${file} - INPUTS ${PROJECT_SOURCE_DIR}/generic/lib/${file}.ll + INPUTS ${CMAKE_CURRENT_SOURCE_DIR}/generic/lib/${file}.ll ) install( FILES $ ARCHIVE DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" ) @@ -219,7 +224,7 @@ if( ENABLE_RUNTIME_SUBNORMAL ) endif() find_package( Python3 REQUIRED COMPONENTS Interpreter ) -file( TO_CMAKE_PATH ${PROJECT_SOURCE_DIR}/generic/lib/gen_convert.py script_loc ) +file( TO_CMAKE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/generic/lib/gen_convert.py script_loc ) add_custom_command( OUTPUT convert.cl COMMAND ${Python3_EXECUTABLE} ${script_loc} > convert.cl @@ -264,7 +269,7 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) foreach( l ${dirs} ${DARCH} ${DARCH}-${OS} ${DARCH}-${VENDOR}-${OS} ) foreach( s "SOURCES" "SOURCES_${LLVM_MAJOR}.${LLVM_MINOR}" ) file( TO_CMAKE_PATH ${l}/lib/${s} file_loc ) - file( TO_CMAKE_PATH ${PROJECT_SOURCE_DIR}/${file_loc} loc ) + file( TO_CMAKE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${file_loc} loc ) # Prepend the location to give higher priority to # specialized implementation if( EXISTS ${loc} ) @@ -339,7 +344,7 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) list( APPEND build_flags -D__CLC_INTERNAL -D${CLC_TARGET_DEFINE} - -I${PROJECT_SOURCE_DIR}/generic/include + -I${CMAKE_CURRENT_SOURCE_DIR}/generic/include # FIXME: Fix libclc to not require disabling this noisy warning -Wno-bitwise-conditional-parentheses ) @@ -360,9 +365,9 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) # the path (e.g., ironing out any ".."), then make it relative to the # root directory again, and use that relative path component for the # binary path. - get_filename_component( abs_path ${file} ABSOLUTE BASE_DIR ${PROJECT_SOURCE_DIR} ) - file( RELATIVE_PATH root_rel_path ${PROJECT_SOURCE_DIR} ${abs_path} ) - set( input_file ${PROJECT_SOURCE_DIR}/${file} ) + get_filename_component( abs_path ${file} ABSOLUTE BASE_DIR ${CMAKE_CURRENT_SOURCE_DIR} ) + file( RELATIVE_PATH root_rel_path ${CMAKE_CURRENT_SOURCE_DIR} ${abs_path} ) + set( input_file ${CMAKE_CURRENT_SOURCE_DIR}/${file} ) set( output_file "${LIBCLC_ARCH_OBJFILE_DIR}/${root_rel_path}.bc" ) endif() @@ -373,7 +378,7 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) INPUT ${input_file} OUTPUT ${output_file} EXTRA_OPTS "${mcpu}" -fno-builtin -nostdlib - "${build_flags}" -I${PROJECT_SOURCE_DIR}/${file_dir} + "${build_flags}" -I${CMAKE_CURRENT_SOURCE_DIR}/${file_dir} DEPENDENCIES generate_convert.cl clspv-generate_convert.cl ) list( APPEND bytecode_files ${output_file} ) @@ -407,9 +412,9 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) # Add opt target add_custom_command( OUTPUT ${builtins_opt_lib_tgt}.bc - COMMAND libclc::opt ${opt_flags} -o ${builtins_opt_lib_tgt}.bc + COMMAND ${opt_exe} ${opt_flags} -o ${builtins_opt_lib_tgt}.bc ${builtins_link_lib} - DEPENDS libclc::opt ${builtins_link_lib} ${builtins_link_lib_tgt} + DEPENDS ${opt_target} ${builtins_link_lib} ${builtins_link_lib_tgt} ) add_custom_target( ${builtins_opt_lib_tgt} ALL DEPENDS ${builtins_opt_lib_tgt}.bc @@ -423,15 +428,15 @@ foreach( t ${LIBCLC_TARGETS_TO_BUILD} ) # Add prepare target set( obj_suffix ${arch_suffix}.bc ) add_custom_command( OUTPUT ${obj_suffix} - COMMAND prepare_builtins -o ${obj_suffix} ${builtins_opt_lib} - DEPENDS ${builtins_opt_lib} ${builtins_opt_lib_tgt} prepare_builtins ) + COMMAND ${prepare_builtins_exe} -o ${obj_suffix} ${builtins_opt_lib} + DEPENDS ${builtins_opt_lib} ${builtins_opt_lib_tgt} ${prepare_builtins_target} ) add_custom_target( prepare-${obj_suffix} ALL DEPENDS ${obj_suffix} ) # nvptx-- targets don't include workitem builtins if( NOT clang_triple MATCHES ".*ptx.*--$" ) add_test( NAME external-calls-${obj_suffix} COMMAND ./check_external_calls.sh ${CMAKE_CURRENT_BINARY_DIR}/${obj_suffix} ${LLVM_TOOLS_BINARY_DIR} - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} ) + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} ) endif() install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${obj_suffix} DESTINATION "${CMAKE_INSTALL_DATADIR}/clc" ) diff --git a/libclc/cmake/modules/AddLibclc.cmake b/libclc/cmake/modules/AddLibclc.cmake index ea97e504364ba5..68b33ede6c3697 100644 --- a/libclc/cmake/modules/AddLibclc.cmake +++ b/libclc/cmake/modules/AddLibclc.cmake @@ -12,8 +12,8 @@ # * DEPENDENCIES ... # List of extra dependencies to inject # -# Depends on the libclc::clang and libclc::llvm-as targets for compiling and -# assembling, respectively. +# Depends on the clang, llvm-as, and llvm-link targets for compiling, +# assembling, and linking, respectively. function(compile_to_bc) cmake_parse_arguments(ARG "" @@ -45,7 +45,7 @@ function(compile_to_bc) add_custom_command( OUTPUT ${ARG_OUTPUT}${TMP_SUFFIX} - COMMAND libclc::clang + COMMAND ${clang_exe} ${TARGET_ARG} ${PP_OPTS} ${ARG_EXTRA_OPTS} @@ -58,7 +58,7 @@ function(compile_to_bc) -x cl ${ARG_INPUT} DEPENDS - libclc::clang + ${clang_target} ${ARG_INPUT} ${ARG_DEPENDENCIES} DEPFILE ${ARG_OUTPUT}.d @@ -67,8 +67,8 @@ function(compile_to_bc) 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} + COMMAND ${llvm-as_exe} -o ${ARG_OUTPUT} ${ARG_OUTPUT}${TMP_SUFFIX} + DEPENDS ${llvm-as_target} ${ARG_OUTPUT}${TMP_SUFFIX} ) endif() endfunction() @@ -107,8 +107,8 @@ function(link_bc) add_custom_command( OUTPUT ${ARG_TARGET}.bc - COMMAND libclc::llvm-link -o ${ARG_TARGET}.bc ${LINK_INPUT_ARG} - DEPENDS libclc::llvm-link ${ARG_DEPENDENCIES} ${ARG_INPUTS} ${RSP_FILE} + 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 )