cmakehalide

The visibility of halide_library in subdirectory using CMake building system


It seems that the Halide library created using:

halide_library(xxx SRCS xxx_generator.cpp)

in CMakeLists.txt in a subdirectory is invisible to its parent or parallel-directories.

For example, I have a Halide project using CMake like this:

├── A
│   ├── a_generator.cpp
│   ├── a_run_generator.cpp
│   └── CMakeLists.txt
├── B
│   ├── b_run_generator.cpp
│   └── CMakeLists.txt
└── CMakeLists.txt

And in CMakeLists.txt in subfolder A, I have

halide_library(a_filter SRCS a_generator.cpp)

And I want to link the "a_filter" library to "b_run_generator.cpp" in subfolder B like this:

add_executable(b_run_generator b_run_generator.cpp)
target_link_library(b_run_generator PRIVATE a_filter)

the CMake complains that it couldn't find "a_filter".

And if I link to the explicit path of "a_filter", a lot of error shows up like this:

/usr/bin/ld: ../genfiles/a/a.a(a.a.o): in function `a':
halide_buffer_t.cpp:(.text.a+0x82f): undefined reference to `halide_error_buffer_argument_is_null'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0x8a3): undefined reference to `halide_error_buffer_allocation_too_large'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0x8be): undefined reference to `halide_error_buffer_allocation_too_large'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0x8d6): undefined reference to `halide_error_buffer_extents_too_large'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0x8f1): undefined reference to `halide_error_buffer_allocation_too_large'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0x90c): undefined reference to `halide_error_buffer_allocation_too_large'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0x927): undefined reference to `halide_error_buffer_extents_too_large'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0x943): undefined reference to `halide_error_device_dirty_with_no_device_support'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0x95f): undefined reference to `halide_error_host_is_null'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0x986): undefined reference to `halide_error_bad_type'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0x9a2): undefined reference to `halide_error_bad_dimensions'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0x9cc): undefined reference to `halide_error_access_out_of_bounds'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0x9e4): undefined reference to `halide_error_buffer_extents_negative'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0xa0e): undefined reference to `halide_error_access_out_of_bounds'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0xa2b): undefined reference to `halide_error_buffer_extents_negative'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0xa45): undefined reference to `halide_error_buffer_extents_negative'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0xa5f): undefined reference to `halide_error_buffer_extents_negative'
/usr/bin/ld: halide_buffer_t.cpp:(.text.a+0xa99): undefined reference to `halide_error_constraint_violated'
clang-9: error: linker command failed with exit code 1 (use -v to see invocation)

So my question is, how do I make the halide library created in a subdirectory visible to its parent or parallel-directories?


Solution

  • Function halide_library actually creates an IMPORTED library, which by default is visible only in the current scope or below:

    # Inside 'halide_library_from_generator' function which is called from 'halide_library'
    # ...
    add_library("${BASENAME}" STATIC IMPORTED)
    

    While normal add_library(IMPORTED) accepts GLOBAL keyword for make it globally visible, halide_library doesn't accept this keyword.

    You may "wrap" the target, created with halide_library, so resulted target will be globally visible:

    halide_library(a_filter SRCS a_generator.cpp)
    # Create globally visible wrapper target 'a_filter_global'.
    add_library(a_filter_global INTERFACE)
    target_link_libraries(a_filter_global INTERFACE a_filter)
    

    Then use the wrapper target:

    add_executable(b_run_generator b_run_generator.cpp)
    target_link_library(b_run_generator PRIVATE a_filter_global)
    

    Since version 3.11 CMake allows to set IMPORTED_GLOBAL property for the IMPORTED target for make it globally visible:

    halide_library(a_filter SRCS a_generator.cpp)
    # Make the target globally visible.
    set_target_properties(a_filter PROPERTIES IMPORTED_GLOBAL TRUE)
    

    Note, that setting the property should be performed from the same directory where the target is created with halide_library.