diff --git a/README_cmake.md b/README_cmake.md index a59ab16f68b5..b15989d4baeb 100644 --- a/README_cmake.md +++ b/README_cmake.md @@ -805,6 +805,7 @@ add_halide_library( FROM [GRADIENT_DESCENT] [C_BACKEND] [REGISTRATION OUTVAR] + [HEADER OUTVAR] [ OUTVAR]) extra-output = ASSEMBLY | BITCODE | COMPILER_LOG | CPP_STUB @@ -869,10 +870,16 @@ compiler on a generated source. Note that a `.runtime` target is _not_ created in this case, and the `USE_RUNTIME` option is ignored. Other options work as expected. -If `REGISTRATION` is set, the path to the generated `.registration.cpp` file -will be set in `OUTVAR`. This can be used to generate a runner for a Halide -library that is useful for benchmarking and testing, as documented above. This -is equivalent to setting `-e registration` at the generator command line. +If `REGISTRATION` is set, the path (relative to `CMAKE_CURRENT_BINARY_DIR`) +to the generated `.registration.cpp` file will be set in `OUTVAR`. This can be +used to generate a runner for a Halide library that is useful for benchmarking +and testing, as documented above. This is equivalent to setting +`-e registration` at the generator command line. + +If `HEADER` is set, the path (relative to `CMAKE_CURRENT_BINARY_DIR`) to the +generated `.h` header file will be set in `OUTVAR`. This can be used with +`install(FILES)` to conveniently deploy the generated header along with your +library. Lastly, each of the `extra-output` arguments directly correspond to an extra output (via `-e`) from the generator. The value `OUTVAR` names a variable into diff --git a/cmake/HalideGeneratorHelpers.cmake b/cmake/HalideGeneratorHelpers.cmake index d48e02778970..6a65a14912e6 100644 --- a/cmake/HalideGeneratorHelpers.cmake +++ b/cmake/HalideGeneratorHelpers.cmake @@ -17,7 +17,7 @@ function(add_halide_library TARGET) # - `object` is selected for CMake-target-compile # - `static_library` is selected for cross-compile # - `cpp_stub` is not available - set(EXTRA_OUTPUT_NAMES + set(extra_output_names ASSEMBLY BITCODE COMPILER_LOG @@ -48,7 +48,7 @@ function(add_halide_library TARGET) ## set(options C_BACKEND GRADIENT_DESCENT) - set(oneValueArgs FROM GENERATOR FUNCTION_NAME NAMESPACE USE_RUNTIME AUTOSCHEDULER ${EXTRA_OUTPUT_NAMES}) + set(oneValueArgs FROM GENERATOR FUNCTION_NAME NAMESPACE USE_RUNTIME AUTOSCHEDULER HEADER ${extra_output_names}) set(multiValueArgs TARGETS FEATURES PARAMS PLUGINS) cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) @@ -69,7 +69,7 @@ function(add_halide_library TARGET) endif () endif () - set(GRADIENT_DESCENT "$") + set(gradient_descent "$") if (NOT ARG_GENERATOR) set(ARG_GENERATOR "${TARGET}") @@ -116,17 +116,15 @@ function(add_halide_library TARGET) if (ARG_C_BACKEND) # The C backend does not provide a runtime, so just supply headers. set(ARG_USE_RUNTIME Halide::Runtime) - else () + elseif (NOT ARG_USE_RUNTIME) # If we're not using an existing runtime, create one. - if (NOT ARG_USE_RUNTIME) - _Halide_add_halide_runtime("${TARGET}.runtime" FROM ${ARG_FROM} - TARGETS ${ARG_TARGETS}) - set(ARG_USE_RUNTIME "${TARGET}.runtime") - elseif (NOT TARGET ${ARG_USE_RUNTIME}) - message(FATAL_ERROR "Invalid runtime target ${ARG_USE_RUNTIME}") - else () - _Halide_add_targets_to_runtime(${ARG_USE_RUNTIME} TARGETS ${ARG_TARGETS}) - endif () + _Halide_add_halide_runtime("${TARGET}.runtime" FROM ${ARG_FROM} + TARGETS ${ARG_TARGETS}) + set(ARG_USE_RUNTIME "${TARGET}.runtime") + elseif (NOT TARGET ${ARG_USE_RUNTIME}) + message(FATAL_ERROR "Invalid runtime target ${ARG_USE_RUNTIME}") + else () + _Halide_add_targets_to_runtime(${ARG_USE_RUNTIME} TARGETS ${ARG_TARGETS}) endif () ## @@ -134,6 +132,7 @@ function(add_halide_library TARGET) ## _Halide_get_platform_details( + ${ARG_FROM} generator_cmd crosscompiling object_suffix @@ -141,39 +140,42 @@ function(add_halide_library TARGET) ${ARG_TARGETS}) # Always emit a C header - set(GENERATOR_OUTPUTS c_header) - set(GENERATOR_OUTPUT_FILES "${TARGET}.h") + set(generator_outputs c_header) + set(generator_output_files "${TARGET}.h") + if (ARG_HEADER) + set(${ARG_HEADER} "${TARGET}.h" PARENT_SCOPE) + endif () # Then either a C source, a set of object files, or a cross-compiled static library. if (ARG_C_BACKEND) - list(APPEND GENERATOR_OUTPUTS c_source) - set(GENERATOR_SOURCES "${TARGET}.halide_generated.cpp") + list(APPEND generator_outputs c_source) + set(generator_sources "${TARGET}.halide_generated.cpp") elseif (crosscompiling) # When cross-compiling, we need to use a static, imported library - list(APPEND GENERATOR_OUTPUTS static_library) - set(GENERATOR_SOURCES "${TARGET}${static_library_suffix}") + list(APPEND generator_outputs static_library) + set(generator_sources "${TARGET}${static_library_suffix}") else () # When compiling for the current CMake toolchain, create a native - list(APPEND GENERATOR_OUTPUTS object) + list(APPEND generator_outputs object) list(LENGTH ARG_TARGETS len) if (len EQUAL 1) - set(GENERATOR_SOURCES "${TARGET}${object_suffix}") + set(generator_sources "${TARGET}${object_suffix}") else () - set(GENERATOR_SOURCES ${ARG_TARGETS}) - list(TRANSFORM GENERATOR_SOURCES PREPEND "${TARGET}-") - list(TRANSFORM GENERATOR_SOURCES APPEND "${object_suffix}") - list(APPEND GENERATOR_SOURCES "${TARGET}_wrapper${object_suffix}") + set(generator_sources ${ARG_TARGETS}) + list(TRANSFORM generator_sources PREPEND "${TARGET}-") + list(TRANSFORM generator_sources APPEND "${object_suffix}") + list(APPEND generator_sources "${TARGET}_wrapper${object_suffix}") endif () endif () - list(APPEND GENERATOR_OUTPUT_FILES ${GENERATOR_SOURCES}) + list(APPEND generator_output_files ${generator_sources}) # Add in extra outputs using the table defined at the start of this function - foreach (out IN LISTS EXTRA_OUTPUT_NAMES) + foreach (out IN LISTS extra_output_names) if (ARG_${out}) set(${ARG_${out}} "${TARGET}${${out}_extension}" PARENT_SCOPE) - list(APPEND GENERATOR_OUTPUT_FILES "${TARGET}${${out}_extension}") + list(APPEND generator_output_files "${TARGET}${${out}_extension}") string(TOLOWER "${out}" out) - list(APPEND GENERATOR_OUTPUTS ${out}) + list(APPEND generator_outputs ${out}) endif () endforeach () @@ -181,7 +183,7 @@ function(add_halide_library TARGET) # Attach an autoscheduler if the user requested it ## - set(GEN_AUTOSCHEDULER "") + set(autoscheduler "") if (ARG_AUTOSCHEDULER) if ("${ARG_AUTOSCHEDULER}" MATCHES "::") if (NOT TARGET "${ARG_AUTOSCHEDULER}") @@ -195,7 +197,7 @@ function(add_halide_library TARGET) elseif (NOT ARG_PLUGINS) message(AUTHOR_WARNING "AUTOSCHEDULER set to a scheduler name but no plugins were loaded") endif () - set(GEN_AUTOSCHEDULER -s "${ARG_AUTOSCHEDULER}") + set(autoscheduler -s "${ARG_AUTOSCHEDULER}") list(PREPEND ARG_PARAMS auto_schedule=true) endif () @@ -206,44 +208,44 @@ function(add_halide_library TARGET) if (crosscompiling) add_library("${TARGET}" STATIC IMPORTED GLOBAL) set_target_properties("${TARGET}" PROPERTIES - IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/${GENERATOR_SOURCES}") + IMPORTED_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/${generator_sources}") else () - add_library("${TARGET}" STATIC ${GENERATOR_SOURCES}) + add_library("${TARGET}" STATIC ${generator_sources}) set_target_properties("${TARGET}" PROPERTIES POSITION_INDEPENDENT_CODE ON LINKER_LANGUAGE CXX) endif () # Load the plugins and setup dependencies - set(GEN_PLUGINS "") + set(generator_plugins "") if (ARG_PLUGINS) foreach (p IN LISTS ARG_PLUGINS) - list(APPEND GEN_PLUGINS "$") + list(APPEND generator_plugins "$") endforeach () - set(GEN_PLUGINS -p "$>") + set(generator_plugins -p "$>") endif () - add_custom_command(OUTPUT ${GENERATOR_OUTPUT_FILES} + add_custom_command(OUTPUT ${generator_output_files} COMMAND ${generator_cmd} -n "${TARGET}" - -d "${GRADIENT_DESCENT}" + -d "${gradient_descent}" -g "${ARG_GENERATOR}" -f "${ARG_FUNCTION_NAME}" - -e "$>" - ${GEN_PLUGINS} - ${GEN_AUTOSCHEDULER} + -e "$>" + ${generator_plugins} + ${autoscheduler} -o . "target=$>" ${ARG_PARAMS} DEPENDS "${ARG_FROM}" ${ARG_PLUGINS} VERBATIM) - list(TRANSFORM GENERATOR_OUTPUT_FILES PREPEND "${CMAKE_CURRENT_BINARY_DIR}/") - add_custom_target("${TARGET}.update" ALL DEPENDS ${GENERATOR_OUTPUT_FILES}) + list(TRANSFORM generator_output_files PREPEND "${CMAKE_CURRENT_BINARY_DIR}/") + add_custom_target("${TARGET}.update" ALL DEPENDS ${generator_output_files}) add_dependencies("${TARGET}" "${TARGET}.update") - target_include_directories("${TARGET}" INTERFACE "${CMAKE_CURRENT_BINARY_DIR}") + target_include_directories("${TARGET}" INTERFACE "$") target_link_libraries("${TARGET}" INTERFACE "${ARG_USE_RUNTIME}") endfunction() @@ -254,6 +256,7 @@ endfunction() function(_Halide_add_halide_runtime RT) cmake_parse_arguments(ARG "" "FROM" "TARGETS" ${ARGN}) _Halide_get_platform_details( + ${ARG_FROM} generator_cmd crosscompiling object_suffix @@ -293,7 +296,7 @@ function(_Halide_add_halide_runtime RT) _Halide_add_targets_to_runtime("${RT}" TARGETS ${ARG_TARGETS}) endfunction() -function(_Halide_get_platform_details OUT_GEN OUT_XC OUT_OBJ OUT_STATIC) +function(_Halide_get_platform_details ARG_FROM OUT_GEN OUT_XC OUT_OBJ OUT_STATIC) if ("${ARGN}" MATCHES "host") set(ARGN "${Halide_HOST_TARGET}") endif () @@ -317,7 +320,13 @@ function(_Halide_get_platform_details OUT_GEN OUT_XC OUT_OBJ OUT_STATIC) set(${OUT_GEN} ${ARG_FROM} PARENT_SCOPE) endif () - _Halide_get_triple(halide_triple "${ARGN}") + # Well-formed targets must either start with "host" or a target triple. + if ("${ARGN}" MATCHES "host") + set(halide_triple ${Halide_HOST_TARGET}) + else () + string(REGEX REPLACE "^([^-]+-[^-]+-[^-]+).*$" "\\1" halide_triple "${ARGN}") + endif () + if (NOT Halide_CMAKE_TARGET STREQUAL halide_triple) set("${OUT_XC}" 1 PARENT_SCOPE) else () diff --git a/cmake/HalideTargetHelpers.cmake b/cmake/HalideTargetHelpers.cmake index 830c93ec73cb..7725042738c7 100644 --- a/cmake/HalideTargetHelpers.cmake +++ b/cmake/HalideTargetHelpers.cmake @@ -2,16 +2,6 @@ # Utilities for manipulating Halide target triples ## -function(_Halide_get_triple OUTVAR) - # Well-formed targets must either start with "host" or a target triple. - if (ARGN MATCHES "host") - set(${OUTVAR} ${Halide_HOST_TARGET}) - else () - string(REGEX REPLACE "^([^-]+-[^-]+-[^-]+).*$" "\\1" ${OUTVAR} "${ARGN}") - endif () - set(${OUTVAR} "${${OUTVAR}}" PARENT_SCOPE) -endfunction() - function(_Halide_cmake_target OUTVAR) # Get arch from CMake string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" arch) @@ -31,33 +21,47 @@ function(_Halide_cmake_target OUTVAR) set(${OUTVAR} "${arch}-${bits}-${os}" PARENT_SCOPE) endfunction() +function(_Halide_cache var val doc) + if (DEFINED ${var}) + set(${var} "${${var}}" CACHE STRING "${doc}") + else () + set(${var} "${val}" CACHE STRING "${doc}") + endif () +endfunction() + ## # Set Halide `host` and `cmake` meta-target values ## -# This variable is set by package scripts and might differ from Halide_CMAKE_TARGET below. -if (NOT Halide_HOST_TARGET) - _Halide_cmake_target(Halide_HOST_TARGET) -endif () +_Halide_cmake_target(_active_triple) -if (NOT Halide_CMAKE_TARGET) - _Halide_cmake_target(Halide_CMAKE_TARGET) -endif () +_Halide_cache(Halide_HOST_TARGET "${_active_triple}" "Halide target triple matching the Halide library") +_Halide_cache(Halide_CMAKE_TARGET "${_active_triple}" "Halide target triple matching the CMake target") + +unset(_active_triple) ## # Cache variable to control the global target for add_halide_library. ## if (NOT "$ENV{HL_TARGET}" STREQUAL "") - set(Halide_TARGET "$ENV{HL_TARGET}" CACHE STRING "The target to use when compiling AOT tests") + set(_default_target "$ENV{HL_TARGET}") elseif (Halide_HOST_TARGET STREQUAL Halide_CMAKE_TARGET) - set(Halide_TARGET "host" CACHE STRING "The target to use when compiling AOT tests") + set(_default_target "host") else () - set(Halide_TARGET "${Halide_CMAKE_TARGET}" CACHE STRING "The target to use when compiling AOT tests") + set(_default_target "${Halide_CMAKE_TARGET}") endif () -if (NOT Halide_TARGET_MESSAGE_PRINTED AND NOT Halide_FIND_QUIETLY) - message(STATUS "Halide detected current CMake target: ${Halide_CMAKE_TARGET}") - message(STATUS "Halide using default generator target: ${Halide_TARGET}") - set(Halide_TARGET_MESSAGE_PRINTED TRUE CACHE INTERNAL "Limit printing the detected targets multiple times") +_Halide_cache(Halide_TARGET "${_default_target}" "The default target to use when AOT compiling") + +unset(_default_target) + +## +# Print the active values of all special target triples. +## + +if (NOT ${CMAKE_FIND_PACKAGE_NAME}_FIND_QUIETLY) + message(STATUS "Halide 'host' platform triple: ${Halide_HOST_TARGET}") + message(STATUS "Halide 'cmake' platform triple: ${Halide_CMAKE_TARGET}") + message(STATUS "Halide default AOT target: ${Halide_TARGET}") endif () diff --git a/dependencies/llvm/CMakeLists.txt b/dependencies/llvm/CMakeLists.txt index eb0b1653f50a..5c8142d1ba1f 100644 --- a/dependencies/llvm/CMakeLists.txt +++ b/dependencies/llvm/CMakeLists.txt @@ -15,6 +15,7 @@ find_package(Clang REQUIRED CONFIG HINTS "${LLVM_DIR}/../clang") message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}") +message(STATUS "Using ClangConfig.cmake in: ${Clang_DIR}") if (LLVM_PACKAGE_VERSION VERSION_LESS 11.0) message(FATAL_ERROR "LLVM version must be 11.0 or newer") @@ -76,7 +77,8 @@ endforeach () set(wasm_libs "") if (TARGET_WEBASSEMBLY) - find_package(LLD CONFIG REQUIRED HINTS "${LLVM_DIR}/../lld") + find_package(LLD CONFIG REQUIRED HINTS "${LLVM_DIR}/../lld" "${LLVM_DIR}/../lib/cmake/lld") + message(STATUS "Using LLDConfig.cmake in: ${LLD_DIR}") # LLVM has a mis-feature that allows it to build and export both static and shared libraries at the same # time, while inconsistently linking its own static libraries (for lldWasm and others) to the shared library. diff --git a/dependencies/wasm/CMakeLists.txt b/dependencies/wasm/CMakeLists.txt index 8ea75b0534df..7d9cfeb48071 100644 --- a/dependencies/wasm/CMakeLists.txt +++ b/dependencies/wasm/CMakeLists.txt @@ -43,14 +43,15 @@ if (WITH_WABT) # TODO: we want to require unique prefixes to include these files, to avoid ambiguity; # this means we have to prefix with "wabt-src/...", which is less bad than other alternatives, # but perhaps we could do better (esp. if wabt was smarter about what it exposed?) - add_library(wabt-obj INTERFACE) - target_sources(wabt-obj INTERFACE $>) - target_include_directories(wabt-obj + add_library(Halide_wabt INTERFACE) + target_sources(Halide_wabt INTERFACE $>) + target_include_directories(Halide_wabt SYSTEM # Use -isystem instead of -I; this is a trick so that clang-tidy won't analyze these includes INTERFACE $ $ $) + set_target_properties(Halide_wabt PROPERTIES EXPORT_NAME wabt) endif () if (WITH_WASM_SHELL) diff --git a/packaging/CMakeLists.txt b/packaging/CMakeLists.txt index 7a12a9463828..6cf4304c57f7 100644 --- a/packaging/CMakeLists.txt +++ b/packaging/CMakeLists.txt @@ -5,8 +5,7 @@ include(CMakePackageConfigHelpers) # Custom locations ## -set(HALIDE_INSTALL_CMAKEDIR - "${CMAKE_INSTALL_LIBDIR}/cmake/Halide" +set(Halide_INSTALL_CMAKEDIR "${CMAKE_INSTALL_LIBDIR}/cmake/Halide" CACHE STRING "Path to Halide cmake files") ## @@ -14,7 +13,7 @@ set(HALIDE_INSTALL_CMAKEDIR ## set(optional_dependencies "") -foreach (target IN ITEMS wabt-obj) +foreach (target IN ITEMS Halide_wabt) if (TARGET ${target}) list(APPEND optional_dependencies ${target}) endif () @@ -158,24 +157,24 @@ if (Halide_SHARED_LLVM OR (NOT BUILD_SHARED_LIBS AND NOT Halide_BUNDLE_LLVM)) endif () install(FILES "${depFile}" - DESTINATION ${HALIDE_INSTALL_CMAKEDIR} + DESTINATION ${Halide_INSTALL_CMAKEDIR} COMPONENT Halide_Development) endif () install(EXPORT Halide_Targets - DESTINATION ${HALIDE_INSTALL_CMAKEDIR} + DESTINATION ${Halide_INSTALL_CMAKEDIR} NAMESPACE Halide::${LIB_TYPE}:: FILE Halide-Targets-ns-${LIB_TYPE}.cmake COMPONENT Halide_Development) install(EXPORT Halide_Targets - DESTINATION ${HALIDE_INSTALL_CMAKEDIR} + DESTINATION ${Halide_INSTALL_CMAKEDIR} NAMESPACE Halide:: FILE Halide-Targets-${LIB_TYPE}.cmake COMPONENT Halide_Development) install(EXPORT Halide_Interfaces - DESTINATION ${HALIDE_INSTALL_CMAKEDIR} + DESTINATION ${Halide_INSTALL_CMAKEDIR} NAMESPACE Halide:: FILE Halide-Interfaces.cmake COMPONENT Halide_Development) @@ -191,7 +190,7 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/HalideConfigVersion.cmake ${Halide_SOURCE_DIR}/cmake/HalideGeneratorHelpers.cmake ${Halide_SOURCE_DIR}/cmake/HalideTargetHelpers.cmake - DESTINATION ${HALIDE_INSTALL_CMAKEDIR} + DESTINATION ${Halide_INSTALL_CMAKEDIR} COMPONENT Halide_Development) ## diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 0a334334d82a..27d2f84191f1 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -391,8 +391,8 @@ if (Halide_WITH_INTROSPECTION) target_compile_definitions(Halide PRIVATE WITH_INTROSPECTION) endif () -if (TARGET wabt-obj) - target_link_libraries(Halide PRIVATE wabt-obj) +if (TARGET Halide_wabt) + target_link_libraries(Halide PRIVATE Halide_wabt) target_compile_definitions(Halide PRIVATE WITH_WABT) endif ()