Created
August 24, 2017 11:10
-
-
Save mcourteaux/66ada94604d1122fb1c3b99f43dca380 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
include(CMakeParseArguments) | |
function(halide_use_image_io TARGET) | |
target_include_directories(${TARGET} PRIVATE "${HALIDE_ROOT_DIR}/tools") | |
foreach(PKG PNG JPEG) | |
# It's OK to call find_package() for the same package multiple times. | |
find_package(${PKG} QUIET) | |
if(${PKG}_FOUND) | |
target_compile_definitions(${TARGET} PRIVATE ${${PKG}_DEFINITIONS}) | |
target_include_directories(${TARGET} PRIVATE ${${PKG}_INCLUDE_DIRS}) | |
target_link_libraries(${TARGET} ${${PKG}_LIBRARIES}) | |
else() | |
message(STATUS "${PKG} not found for ${TARGET}; compiling with -DHALIDE_NO_${PKG}") | |
target_compile_definitions(${TARGET} PRIVATE -DHALIDE_NO_${PKG}) | |
endif() | |
endforeach() | |
endfunction() | |
function(halide_project name folder) | |
add_executable("${name}" ${ARGN}) | |
if (MSVC) | |
else() | |
target_compile_options("${name}" PUBLIC "-fno-rtti") | |
endif() | |
target_link_libraries("${name}" PUBLIC Halide ${CMAKE_DL_LIBS} ${CMAKE_THREAD_LIBS_INIT}) | |
#target_include_directories("${name}" PRIVATE "${HALIDE_ROOT_DIR}/tools") | |
set_target_properties("${name}" PROPERTIES FOLDER "${folder}") | |
if (MSVC) | |
# 4006: "already defined, second definition ignored" | |
# 4088: "/FORCE used, image may not work" | |
# (Note that MSVC apparently considers 4088 too important to allow us to ignore it; | |
# I'm nevertheless leaving this here to document that we don't care about it.) | |
set_target_properties(${name} PROPERTIES LINK_FLAGS "/ignore:4006 /ignore:4088") | |
target_compile_definitions("${name}" PRIVATE _CRT_SECURE_NO_WARNINGS) | |
target_link_libraries("${name}" PRIVATE Kernel32) | |
endif() | |
endfunction(halide_project) | |
function(halide_generator_genfiles_dir NAME OUTVAR) | |
set(GENFILES_DIR "${CMAKE_CURRENT_BINARY_DIR}/generator_genfiles/${NAME}") | |
file(MAKE_DIRECTORY "${GENFILES_DIR}") | |
set(${OUTVAR} "${GENFILES_DIR}" PARENT_SCOPE) | |
endfunction() | |
function(halide_generator_get_exec_path TARGET OUTVAR) | |
if(MSVC) | |
# In MSVC, the generator executable will be placed in a configuration specific | |
# directory specified by ${CMAKE_CFG_INTDIR}. | |
set(${OUTVAR} "${CMAKE_CURRENT_BINARY_DIR}/bin/${CMAKE_CFG_INTDIR}/${TARGET}${CMAKE_EXECUTABLE_SUFFIX}" PARENT_SCOPE) | |
elseif(XCODE) | |
# In Xcode, the generator executable will be placed in a configuration specific | |
# directory, so the Xcode variable $(CONFIGURATION) is passed in the custom build script. | |
set(${OUTVAR} "${CMAKE_CURRENT_BINARY_DIR}/bin/$(CONFIGURATION)/${TARGET}${CMAKE_EXECUTABLE_SUFFIX}" PARENT_SCOPE) | |
else() | |
set(${OUTVAR} "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}${CMAKE_EXECUTABLE_SUFFIX}" PARENT_SCOPE) | |
endif() | |
endfunction() | |
function(halide_generator_add_exec_generator_target) | |
set(options ) | |
set(oneValueArgs GENERATOR_TARGET GENFILES_DIR) | |
set(multiValueArgs OUTPUTS GENERATOR_ARGS) | |
cmake_parse_arguments(args "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) | |
message("Generator.exec target for '${args_GENERATOR_TARGET}'.") | |
halide_generator_get_exec_path(${args_GENERATOR_TARGET} EXEC_PATH) | |
list(GET args_OUTPUTS 0 CODE_FILE) | |
list(GET args_OUTPUTS 1 HDR_FILE) | |
message("${CODE_FILE}") | |
message("${HDR_FILE}") | |
message("Outputs: ${args_OUTPUTS}") | |
add_custom_command( | |
OUTPUT ${CODE_FILE} ${HDR_FILE} | |
DEPENDS "${args_GENERATOR_TARGET}" | |
COMMAND ${EXEC_PATH} ${args_GENERATOR_ARGS} | |
WORKING_DIRECTORY ${CMAKE_BINARY_DIR} | |
COMMENT "Executing Generator ${args_GENERATOR_TARGET} with args ${args_GENERATOR_ARGS}..." | |
) | |
endfunction() | |
# This function adds custom build steps to invoke a Halide generator executable | |
# and produce a static library containing the generated code. | |
# | |
# The generator executable must be produced separately, e.g. using a call to the | |
# function halide_add_generator() or halide_project(...) or add_executable(...) | |
# and passed to this function in the GENERATOR_TARGET parameter. | |
# | |
# Usage: | |
# halide_add_aot_library(<name> | |
# GENERATOR_TARGET <target> | |
# GENERATOR_NAME <string> | |
# GENERATED_FUNCTION <string> | |
# GENERATOR_OUTPUTS <arg> <arg> ... | |
# GENERATOR_ARGS <arg> <arg> ...) | |
# | |
# <name> is the name of the library being defined. | |
# GENERATOR_TARGET is the name of the generator executable target, which is assumed to be | |
# defined elsewhere. | |
# GENERATOR_TARGET is the name of the generator executable target, which is assumed to be | |
# defined elsewhere. | |
# GENERATOR_NAME is the registered name of the Halide::Generator derived object | |
# GENERATED_FUNCTION is the name of the C function to be generated by Halide, including C++ | |
# namespace (if any); if omitted, default to GENERATOR_NAME | |
# GENERATOR_OUTPUTS are the values to pass to -e; if omitted, defaults to "h static_library" | |
# GENERATOR_ARGS are optional extra arguments passed to the generator executable during | |
# build. | |
function(halide_add_aot_library AOT_LIBRARY_TARGET) | |
# Parse arguments | |
set(options ) | |
set(oneValueArgs GENERATOR_TARGET GENERATOR_NAME GENERATED_FUNCTION) | |
set(multiValueArgs GENERATOR_ARGS GENERATOR_OUTPUTS FILTER_DEPS) | |
cmake_parse_arguments(args "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) | |
if (args_GENERATED_FUNCTION STREQUAL "") | |
set(args_GENERATED_FUNCTION ${args_GENERATOR_NAME}) | |
endif() | |
# Create a directory to contain generator specific intermediate files | |
halide_generator_genfiles_dir(${AOT_LIBRARY_TARGET} GENFILES_DIR) | |
# Determine the name of the output files | |
set(FILTER_LIB "${AOT_LIBRARY_TARGET}${CMAKE_STATIC_LIBRARY_SUFFIX}") | |
set(FILTER_HDR "${AOT_LIBRARY_TARGET}.h") | |
set(FILTER_CPP "${AOT_LIBRARY_TARGET}.cpp") | |
set(GENERATOR_EXEC_ARGS "-o" "${GENFILES_DIR}") | |
if (NOT ${args_GENERATED_FUNCTION} STREQUAL "") | |
list(APPEND GENERATOR_EXEC_ARGS "-f" "${args_GENERATED_FUNCTION}" ) | |
endif() | |
if (NOT ${args_GENERATOR_NAME} STREQUAL "") | |
list(APPEND GENERATOR_EXEC_ARGS "-g" "${args_GENERATOR_NAME}") | |
endif() | |
if (NOT "${args_GENERATOR_OUTPUTS}" STREQUAL "") | |
string(REPLACE ";" "," _tmp "${args_GENERATOR_OUTPUTS}") | |
list(APPEND GENERATOR_EXEC_ARGS "-e" ${_tmp}) | |
endif() | |
# GENERATOR_ARGS always come last | |
list(APPEND GENERATOR_EXEC_ARGS ${args_GENERATOR_ARGS}) | |
if ("${args_GENERATOR_OUTPUTS}" STREQUAL "") | |
set(args_GENERATOR_OUTPUTS static_library h) | |
endif() | |
set(OUTPUTS ) | |
# This is the CMake idiom for "if foo in list" | |
list(FIND args_GENERATOR_OUTPUTS "static_library" _lib_index) | |
list(FIND args_GENERATOR_OUTPUTS "h" _h_index) | |
list(FIND args_GENERATOR_OUTPUTS "cpp" _cpp_index) | |
string(LENGTH "${CMAKE_BINARY_DIR}" BINARY_PATH_LENTH) | |
MATH(EXPR BINARY_PATH_LENTH "${BINARY_PATH_LENTH}+1") | |
string(SUBSTRING "${GENFILES_DIR}" ${BINARY_PATH_LENTH} -1 OUTPUT_DIR) | |
if (${_lib_index} GREATER -1) | |
list(APPEND OUTPUTS "${GENFILES_DIR}/${FILTER_LIB}") | |
endif() | |
if (${_h_index} GREATER -1) | |
list(APPEND OUTPUTS "${GENFILES_DIR}/${FILTER_HDR}") | |
set_source_files_properties("${GENFILES_DIR}/${FILTER_HDR}" PROPERTIES GENERATED TRUE) | |
endif() | |
if (${_cpp_index} GREATER -1) | |
list(APPEND OUTPUTS "${GENFILES_DIR}/${FILTER_CPP}") | |
set_source_files_properties("${GENFILES_DIR}/${FILTER_HDR}" PROPERTIES GENERATED TRUE) | |
endif() | |
halide_generator_add_exec_generator_target( | |
GENERATOR_TARGET ${args_GENERATOR_TARGET} | |
GENERATOR_ARGS "${GENERATOR_EXEC_ARGS}" | |
GENFILES_DIR ${GENFILES_DIR} | |
OUTPUTS "${OUTPUTS}" | |
) | |
add_library("${AOT_LIBRARY_TARGET}" INTERFACE) | |
target_link_libraries(${AOT_LIBRARY_TARGET} INTERFACE "${GENFILES_DIR}/${FILTER_LIB}") | |
endfunction(halide_add_aot_library) | |
# Usage: | |
# halide_add_aot_library_dependency(TARGET AOT_LIBRARY_TARGET) | |
function(halide_add_aot_library_dependency TARGET AOT_LIBRARY_TARGET) | |
halide_generator_genfiles_dir(${AOT_LIBRARY_TARGET} GENFILES_DIR) | |
set(FILTER_LIB "${AOT_LIBRARY_TARGET}${CMAKE_STATIC_LIBRARY_SUFFIX}") | |
set(FILTER_HDR "${AOT_LIBRARY_TARGET}.h") | |
target_link_libraries("${TARGET}" PUBLIC "${AOT_LIBRARY_TARGET}") | |
target_include_directories("${TARGET}" PUBLIC "${GENFILES_DIR}") | |
add_dependencies("${TARGET}" "${AOT_LIBRARY_TARGET}") | |
target_sources("${TARGET}" PRIVATE "${GENFILES_DIR}/${FILTER_HDR}") | |
if (WIN32) | |
if (MSVC) | |
# /FORCE:multiple allows clobbering the halide runtime symbols in the lib | |
# linker warnings disabled: | |
# 4006: "already defined, second definition ignored" | |
# 4088: "/FORCE used, image may not work" | |
# (Note that MSVC apparently considers 4088 too important to allow us to ignore it; | |
# I'm nevertheless leaving this here to document that we don't care about it.) | |
set_target_properties("${TARGET}" PROPERTIES LINK_FLAGS "/STACK:8388608,1048576 /FORCE:multiple /ignore:4006 /ignore:4088") | |
else() | |
set_target_properties("${TARGET}" PROPERTIES LINK_FLAGS "-Wl,--allow-multiple-definition") | |
endif() | |
else() | |
target_link_libraries("${TARGET}" PRIVATE dl pthread z) | |
endif() | |
endfunction(halide_add_aot_library_dependency) | |
function(halide_add_generator NAME) | |
set(options WITH_STUB) | |
set(oneValueArgs STUB_GENERATOR_NAME) | |
set(multiValueArgs SRCS STUB_DEPS) | |
cmake_parse_arguments(args "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) | |
halide_project("${NAME}" | |
"generator" | |
"${HALIDE_ROOT_DIR}/tools/GenGen.cpp" | |
"${args_SRCS}") | |
set_target_properties(${NAME} PROPERTIES FOLDER "generator") | |
endfunction(halide_add_generator) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment