1

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?

Jiang
  • 149
  • 6
  • Note that the Halide CMake rules will be changing substantially with the next release. Among other things, this problem will be fixed. – Alex Reinking Mar 12 '20 at 21:58
  • Since Halide 10, the function `add_halide_library` should be used instead and `halide_library` has been removed. – Alex Reinking Aug 05 '21 at 17:18

1 Answers1

3

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.

Tsyvarev
  • 60,011
  • 17
  • 110
  • 153
  • I tried the method. `add_library(a_filter_global INTERFACE GLOBAL)` shows an error saying `add_library GLOBAL option may only be used with IMPORTED libraries`. Once I deleted the GLOBAL keyword as to `add_library(a_filter_global INTERFACE)`, it works with no problem. Thanks! – Jiang Mar 12 '20 at 20:28
  • 1
    You can also set the target property IMPORTED_GLOBAL to TRUE – Alex Reinking Mar 12 '20 at 20:31
  • @Jiang: Thanks for checking, I have fixed the answer. – Tsyvarev Mar 12 '20 at 20:42
  • @AlexReinking: Thanks for info, I did't know about that property. I have added this way to the answer. – Tsyvarev Mar 12 '20 at 20:43