Skip to content

Commit

Permalink
Add helper for cross-compiling Halide generators.
Browse files Browse the repository at this point in the history
Created a new function, add_halide_generator, that helps users
write correct cross-compiling builds by establishing the following
convention for them:

1. Define Halide generators and libraries in the same project
2. Assume two builds: a host build and a cross build.
3. When creating a generator, check to see if we can load a pre-built
   version of the target.
4. If so, just use it, and add aliases to make sure all the names
   line up.
5. If not, make sure the full Halide package is loaded and create a
   target for the generator.
     a. If CMAKE_CROSSCOMPILING is set, then _warn_ the user (the
        variable is unreliable on macOS) that something seems fishy.
     b. Create export rules for the generator. It creates a package
        called PACKAGE_NAME and appends to its EXPORT_FILE.
     c. Create a custom target also named PACKAGE_NAME for building
        just the generators.
     d. Create an alias "${PACKAGE_NAMESPACE}${TARGET}".
6. Users are expected to use the alias in conjunction
   with add_halide_library. Users can test the existence of TARGET
   to determine whether a pre-built one was loaded (and set additional
   properties if not).
7. Setting ${PACKAGE_NAME}_ROOT is enough to load pre-built generators.

PACKAGE_NAME is ${PROJECT_NAME}-generators by default.
PACKAGE_NAMESPACE is "${PROJECT_NAME}::generators::" by default.
EXPORT_FILE is "${PROJECT_BINARY_DIR}/cmake/${PACKAGE_NAME}-config.cmake" by default.

Users are free to avoid the helper if it would not fit their workflow.
  • Loading branch information
alexreinking committed Oct 29, 2021
1 parent 541bc37 commit 58af0ac
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 43 deletions.
84 changes: 84 additions & 0 deletions cmake/HalideGeneratorHelpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,90 @@ define_property(TARGET PROPERTY Halide_GENERATOR_HAS_POST_BUILD
BRIEF_DOCS "On a Halide generator target, true if Halide.dll copy command has already been added."
FULL_DOCS "On a Halide generator target, true if Halide.dll copy command has already been added.")

##
# Function to simplify writing the CMake rules for creating a generator executable
# that follows our recommended cross-compiling workflow.
##

function(add_halide_generator TARGET)
set(options "")
set(oneValueArgs PACKAGE_NAME PACKAGE_NAMESPACE EXPORT_FILE)
set(multiValueArgs SOURCES LINK_LIBRARIES)
cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

if (NOT ARG_PACKAGE_NAME)
set(ARG_PACKAGE_NAME "${PROJECT_NAME}-generators")
endif ()

if (NOT ARG_PACKAGE_NAMESPACE)
set(ARG_PACKAGE_NAMESPACE "${PROJECT_NAME}::generators::")
endif ()

if (NOT ARG_EXPORT_FILE)
file(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/cmake")
set(ARG_EXPORT_FILE "${PROJECT_BINARY_DIR}/cmake/${ARG_PACKAGE_NAME}-config.cmake")
endif ()

if (NOT ARG_SOURCES)
set(ARG_SOURCES "${ARG_UNPARSED_ARGUMENTS}")
endif ()

_Halide_try_load_generators()

# Communicate found information to the caller
set(${ARG_PACKAGE_NAME}_FOUND "${${ARG_PACKAGE_NAME}_FOUND}" PARENT_SCOPE)

set(gen "${ARG_PACKAGE_NAMESPACE}${TARGET}")
if (NOT TARGET "${gen}")
if (NOT TARGET "${ARG_PACKAGE_NAME}")
add_custom_target("${ARG_PACKAGE_NAME}")
endif ()

if (NOT Halide_FOUND)
find_package(Halide REQUIRED)
endif ()

add_executable(${TARGET} ${ARG_SOURCES})
add_executable(${gen} ALIAS ${TARGET})
target_link_libraries(${TARGET} PRIVATE Halide::Generator ${ARG_LINK_LIBRARIES})

add_dependencies("${ARG_PACKAGE_NAME}" ${TARGET})
export(TARGETS ${TARGET}
NAMESPACE ${ARG_PACKAGE_NAMESPACE}
APPEND FILE "${ARG_EXPORT_FILE}")
endif ()
endfunction()

# NOTE: this function must only be called by add_halide_generator
# since it reads from its scope.
function(_Halide_try_load_generators)
# Don't repeatedly run the search for the tools package.
if (NOT DEFINED ${ARG_PACKAGE_NAME}_FOUND)
# Some toolchains, like Emscripten, try to disable finding packages
# outside their sysroots, but we always want to find the native
# generators. Setting CMAKE_FIND_ROOT_PATH_BOTH here overrides
# the toolchain search preference. This is okay since a user can
# always override this call by setting ${ARG_PACKAGE_NAME}_ROOT.
find_package(${ARG_PACKAGE_NAME} QUIET
CMAKE_FIND_ROOT_PATH_BOTH)

# Communicate found information to the caller
set(${ARG_PACKAGE_NAME}_FOUND "${${ARG_PACKAGE_NAME}_FOUND}" PARENT_SCOPE)

if (NOT ${ARG_PACKAGE_NAME}_FOUND AND CMAKE_CROSSCOMPILING)
message(WARNING
"${ARG_PACKAGE_NAME} were not found and it looks like you are cross-compiling. "
"This is likely to fail. Please set -D${ARG_PACKAGE_NAME}_ROOT=... at the CMake "
"command line to the build directory of a host-built ${PROJECT_NAME}.")
endif ()
endif ()
endfunction()

##
# Function to simplify writing the CMake rules for invoking a generator executable
# and getting a usable CMake library out of it.
##

function(add_halide_library TARGET)
##
# Set up argument parsing for extra outputs.
Expand Down
17 changes: 11 additions & 6 deletions test/integration/xc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ project(xc)

enable_testing()

if (CMAKE_CROSSCOMPILING)
find_package(xc-generators REQUIRED)
else ()
add_subdirectory(generators)
endif ()
# Only need the platform-independent / source-only helpers.
find_package(HalideHelpers REQUIRED)

add_subdirectory(add)
add_halide_generator(add_gen add.cpp)
add_halide_library(add FROM xc::generators::add_gen
REGISTRATION add_reg_cpp)

add_executable(run_add ${add_reg_cpp})
target_link_libraries(run_add PRIVATE add Halide::RunGenMain)

add_test(NAME run_add
COMMAND run_add --output_extents=[10,10] --benchmarks=all)
File renamed without changes.
13 changes: 0 additions & 13 deletions test/integration/xc/add/CMakeLists.txt

This file was deleted.

24 changes: 0 additions & 24 deletions test/integration/xc/generators/CMakeLists.txt

This file was deleted.

0 comments on commit 58af0ac

Please sign in to comment.