diff --git a/HalideGenerator.cmake b/HalideGenerator.cmake index 5769fe2dd34e..1efa319203f9 100644 --- a/HalideGenerator.cmake +++ b/HalideGenerator.cmake @@ -70,7 +70,7 @@ 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) + set(multiValueArgs GENERATOR_ARGS GENERATOR_OUTPUTS FILTER_DEPS) cmake_parse_arguments(args "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) if (args_GENERATED_FUNCTION STREQUAL "") @@ -134,9 +134,10 @@ function(halide_add_aot_library AOT_LIBRARY_TARGET) set(RUNGEN "${AOT_LIBRARY_TARGET}.rungen") add_executable("${RUNGEN}" "${CMAKE_SOURCE_DIR}/tools/RunGenStubs.cpp") - target_compile_definitions("${RUNGEN}" PRIVATE "-DHL_RUNGEN_FILTER=${AOT_LIBRARY_TARGET}") + target_compile_definitions("${RUNGEN}" PRIVATE "-DHL_RUNGEN_FILTER_HEADER=\"${AOT_LIBRARY_TARGET}.h\"") target_link_libraries("${RUNGEN}" PRIVATE HalideToolsRunGen) halide_add_aot_library_dependency("${RUNGEN}" "${AOT_LIBRARY_TARGET}") + target_link_libraries("${RUNGEN}" PRIVATE ${args_FILTER_DEPS}) # Not all Generators will build properly with RunGen (e.g., missing # external dependencies), so exclude them from the "ALL" targets diff --git a/Makefile b/Makefile index d4c9f2d64702..922ed8a773b1 100644 --- a/Makefile +++ b/Makefile @@ -865,7 +865,6 @@ test_aotcpp_generators: $(GENERATOR_AOTCPP_TESTS) # not all will work directly (e.g. due to missing define_externs at link time), so we blacklist # those known to be broken for plausible reasons. GENERATOR_BUILD_RUNGEN_TESTS = $(GENERATOR_EXTERNAL_TEST_GENERATORS:$(ROOT_DIR)/test/generator/%_generator.cpp=$(FILTERS_DIR)/%.rungen) -GENERATOR_BUILD_RUNGEN_TESTS := $(filter-out $(FILTERS_DIR)/cxx_mangling.rungen,$(GENERATOR_BUILD_RUNGEN_TESTS)) GENERATOR_BUILD_RUNGEN_TESTS := $(filter-out $(FILTERS_DIR)/cxx_mangling_define_extern.rungen,$(GENERATOR_BUILD_RUNGEN_TESTS)) GENERATOR_BUILD_RUNGEN_TESTS := $(filter-out $(FILTERS_DIR)/define_extern_opencl.rungen,$(GENERATOR_BUILD_RUNGEN_TESTS)) GENERATOR_BUILD_RUNGEN_TESTS := $(filter-out $(FILTERS_DIR)/matlab.rungen,$(GENERATOR_BUILD_RUNGEN_TESTS)) @@ -1248,8 +1247,8 @@ $(BUILD_DIR)/RunGen.o: $(ROOT_DIR)/tools/RunGen.cpp $(RUNTIME_EXPORTED_INCLUDES) @mkdir -p $(BUILD_DIR) $(CXX) -c $< $(TEST_CXX_FLAGS) $(IMAGE_IO_CXX_FLAGS) -I$(INCLUDE_DIR) -I $(SRC_DIR)/runtime -I$(ROOT_DIR)/tools -o $@ -$(FILTERS_DIR)/%.rungen: $(BUILD_DIR)/RunGen.o $(BIN_DIR)/$(TARGET)/runtime.a $(ROOT_DIR)/tools/RunGenStubs.cpp $(FILTERS_DIR)/%.a - $(CXX) -DHL_RUNGEN_FILTER=$* $^ $(TEST_LD_FLAGS) $(IMAGE_IO_LIBS) -o $@ +$(FILTERS_DIR)/%.rungen: $(BUILD_DIR)/RunGen.o $(BIN_DIR)/$(TARGET)/runtime.a $(ROOT_DIR)/tools/RunGenStubs.cpp $(FILTERS_DIR)/%.a + $(CXX) -std=c++11 -DHL_RUNGEN_FILTER_HEADER=\"$*.h\" -I$(FILTERS_DIR) $^ $(TEST_LD_FLAGS) $(IMAGE_IO_LIBS) -o $@ RUNARGS ?= diff --git a/src/CodeGen_C.cpp b/src/CodeGen_C.cpp index e3c7c84dcd34..fac3dd40ca60 100644 --- a/src/CodeGen_C.cpp +++ b/src/CodeGen_C.cpp @@ -1583,6 +1583,30 @@ void CodeGen_C::compile(const LoweredFunc &f) { } stream << "\n"; } + + if (is_header() && f.linkage == LoweredFunc::ExternalPlusMetadata) { + // C syntax for function-that-returns-function-pointer is fun. + const string getter = R"INLINE_CODE( + +// This allows the includer of this file to get the argv/metadata entry points +// for this file without needing to know the specific function names; +// if HALIDE_GET_STANDARD_ARGV_FUNCTION is defined before this file is +// included, an inline function with that name is provided that return +// a function pointer to the _argv() entry point (similarly, +// HALIDE_GET_STANDARD_METADATA_FUNCTION -> _metadata() entry point). +#ifdef HALIDE_GET_STANDARD_ARGV_FUNCTION +inline int (*HALIDE_GET_STANDARD_ARGV_FUNCTION())(void**) { + return $NAME$_argv; +} +#endif +#ifdef HALIDE_GET_STANDARD_METADATA_FUNCTION +inline const struct halide_filter_metadata_t* (*HALIDE_GET_STANDARD_METADATA_FUNCTION())() { + return $NAME$_metadata; +} +#endif +)INLINE_CODE"; + stream << replace_all(getter, "$NAME$", f.name) << "\n\n"; + } } void CodeGen_C::compile(const Buffer<> &buffer) { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 45b35d4c4f31..dfa22679cc18 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -150,13 +150,12 @@ function(halide_define_aot_test NAME) GENERATOR_TARGET "${NAME}.generator" GENERATOR_NAME "${args_GENERATOR_NAME}" GENERATED_FUNCTION "${args_GENERATED_FUNCTION}" - GENERATOR_ARGS "target=${args_GENERATOR_HALIDE_TARGET}" "${args_GENERATOR_ARGS}") + GENERATOR_ARGS "target=${args_GENERATOR_HALIDE_TARGET}" "${args_GENERATOR_ARGS}" + FILTER_DEPS "${args_FILTER_DEPS}") halide_add_aot_library_dependency("${TARGET}" "${AOT_LIBRARY_TARGET}") endif() - foreach(F ${args_FILTER_DEPS}) - target_link_libraries("${TARGET}" PRIVATE ${F}) - endforeach() + target_link_libraries("${TARGET}" PRIVATE ${args_FILTER_DEPS}) endfunction(halide_define_aot_test) diff --git a/tools/RunGenStubs.cpp b/tools/RunGenStubs.cpp index 6e7838a81aae..1d687a2ca940 100644 --- a/tools/RunGenStubs.cpp +++ b/tools/RunGenStubs.cpp @@ -1,20 +1,13 @@ -#ifndef HL_RUNGEN_FILTER - #error "You must define HL_RUNGEN_FILTER" -#endif +#define HALIDE_GET_STANDARD_ARGV_FUNCTION halide_rungen_redirect_argv_getter +#define HALIDE_GET_STANDARD_METADATA_FUNCTION halide_rungen_redirect_metadata_getter -#define HL_RUNGEN_NAME__(prefix, suffix) prefix##suffix -#define HL_RUNGEN_NAME_(prefix, suffix) HL_RUNGEN_NAME__(prefix, suffix) -#define HL_RUNGEN_NAME(suffix) HL_RUNGEN_NAME_(HL_RUNGEN_FILTER, suffix) - -struct halide_filter_metadata_t; - -extern "C" int HL_RUNGEN_NAME(_argv)(void **args); -extern "C" const struct halide_filter_metadata_t *HL_RUNGEN_NAME(_metadata)(); +// This is legal C, as long as the macro expands to a single quoted (or <>-enclosed) string literal +#include HL_RUNGEN_FILTER_HEADER extern "C" int halide_rungen_redirect_argv(void **args) { - return HL_RUNGEN_NAME(_argv)(args); + return halide_rungen_redirect_argv_getter()(args); } extern "C" const struct halide_filter_metadata_t *halide_rungen_redirect_metadata() { - return HL_RUNGEN_NAME(_metadata)(); + return halide_rungen_redirect_metadata_getter()(); }