Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMake clean-up #5967

Merged
merged 2 commits into from
May 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions README_cmake.md
Original file line number Diff line number Diff line change
Expand Up @@ -805,6 +805,7 @@ add_halide_library(<target> FROM <generator-target>
[GRADIENT_DESCENT]
[C_BACKEND]
[REGISTRATION OUTVAR]
[HEADER OUTVAR]
[<extra-output> OUTVAR])

extra-output = ASSEMBLY | BITCODE | COMPILER_LOG | CPP_STUB
Expand Down Expand Up @@ -869,10 +870,16 @@ compiler on a generated source. Note that a `<target>.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
Expand Down
101 changes: 55 additions & 46 deletions cmake/HalideGeneratorHelpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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})

Expand All @@ -69,7 +69,7 @@ function(add_halide_library TARGET)
endif ()
endif ()

set(GRADIENT_DESCENT "$<BOOL:${ARG_GRADIENT_DESCENT}>")
set(gradient_descent "$<BOOL:${ARG_GRADIENT_DESCENT}>")

if (NOT ARG_GENERATOR)
set(ARG_GENERATOR "${TARGET}")
Expand Down Expand Up @@ -116,72 +116,74 @@ 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 ()

##
# Determine which outputs the generator call will emit.
##

_Halide_get_platform_details(
${ARG_FROM}
generator_cmd
crosscompiling
object_suffix
static_library_suffix
${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 ()

##
# 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}")
Expand All @@ -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 ()

Expand All @@ -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 "$<TARGET_FILE:${p}>")
list(APPEND generator_plugins "$<TARGET_FILE:${p}>")
endforeach ()
set(GEN_PLUGINS -p "$<JOIN:${GEN_PLUGINS},$<COMMA>>")
set(generator_plugins -p "$<JOIN:${generator_plugins},$<COMMA>>")
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 "$<JOIN:${GENERATOR_OUTPUTS},$<COMMA>>"
${GEN_PLUGINS}
${GEN_AUTOSCHEDULER}
-e "$<JOIN:${generator_outputs},$<COMMA>>"
${generator_plugins}
${autoscheduler}
-o .
"target=$<JOIN:${ARG_TARGETS},$<COMMA>>"
${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 "$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>")
target_link_libraries("${TARGET}" INTERFACE "${ARG_USE_RUNTIME}")
endfunction()

Expand All @@ -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
Expand Down Expand Up @@ -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 ()
Expand All @@ -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 ()
Expand Down
52 changes: 28 additions & 24 deletions cmake/HalideTargetHelpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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 ()
4 changes: 3 additions & 1 deletion dependencies/llvm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down Expand Up @@ -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.
Expand Down
7 changes: 4 additions & 3 deletions dependencies/wasm/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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 $<BUILD_INTERFACE:$<TARGET_OBJECTS:wabt>>)
target_include_directories(wabt-obj
add_library(Halide_wabt INTERFACE)
target_sources(Halide_wabt INTERFACE $<BUILD_INTERFACE:$<TARGET_OBJECTS:wabt>>)
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
$<BUILD_INTERFACE:${wabt_SOURCE_DIR}>
$<BUILD_INTERFACE:${wabt_BINARY_DIR}>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/_deps>)
set_target_properties(Halide_wabt PROPERTIES EXPORT_NAME wabt)
endif ()

if (WITH_WASM_SHELL)
Expand Down
Loading