halide / Halide

a language for fast, portable data-parallel computation
https://halide-lang.org
Other
5.89k stars 1.07k forks source link

encounter undefined reference when link halide generated static lib to a test executable #7622

Open ygsaber opened 1 year ago

ygsaber commented 1 year ago

I was using add_halide_generator and add_halide_library in cmakelists to generate a simple box filter halide static lib, which is called libhalide_box_filter.a, then link it to my test executable. The problem is it is good to compile the executable with the halide static lib together using cmakelists. But if I separate the process using two cmakelists, the first one contains the add_halide_generator and add_halide_library, and the second one links the generated static lib to the test executable, the linking step will show undefined reference error, as follow:

-- The C compiler identification is GNU 9.4.0 -- The CXX compiler identification is GNU 9.4.0 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done -- Halide 'host' platform triple: x86-64-linux -- Halide 'cmake' platform triple: x86-64-linux -- Halide default AOT target: host -- Found ZLIB: /usr/lib/x86_64-linux-gnu/libz.so (found version "1.2.11")
-- Found PNG: /usr/lib/x86_64-linux-gnu/libpng.so (found version "1.6.37") -- Found JPEG: /usr/lib/x86_64-linux-gnu/libjpeg.so (found version "90") /usr/local/lib/cmake/Halide

-- Configuring done (0.6s) -- Generating done (0.0s) -- Build files have been written to: /media/user/Backup/Documents/projects/Halide/test/test/test_x86/target [ 50%] Building CXX object CMakeFiles/box_filter_test.dir/box_filter_test.cpp.o [100%] Linking CXX executable box_filter_test /usr/bin/ld: /media/user/Backup/Documents/projects/Halide/test/test/test_x86/libhalide_box_filter.a(halide_box_filter.o): in function halide_box_filter_par_for_output_s0_v1_v1_v1': halide_buffer_t.cpp:(.text.halide_box_filter_par_for_output_s0_v1_v1_v1+0x1a3): undefined reference tohalide_malloc' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter_par_for_output_s0_v1_v1_v1+0x10c6): undefined reference to halide_malloc' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter_par_for_output_s0_v1_v1_v1+0x1173): undefined reference tohalide_free' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter_par_for_output_s0_v1_v1_v1+0x1345): undefined reference to halide_free' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter_par_for_output_s0_v1_v1_v1+0x137d): undefined reference tohalide_error_buffer_allocation_too_large' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter_par_for_output_s0_v1_v1_v1+0x1398): undefined reference to halide_error_out_of_memory' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter_par_for_output_s0_v1_v1_v1+0x13ae): undefined reference tohalide_error_buffer_allocation_too_large' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter_par_for_output_s0_v1_v1_v1+0x13ba): undefined reference to halide_error_out_of_memory' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter_par_for_output_s0_v1_v1_v1+0x13cd): undefined reference tohalide_free' /usr/bin/ld: /media/user/Backup/Documents/projects/Halide/test/test/test_x86/libhalide_box_filter.a(halide_box_filter.o): in function halide_box_filter': halide_buffer_t.cpp:(.text.halide_box_filter+0xb54): undefined reference tohalide_do_par_for' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter+0xb8e): undefined reference to halide_error_buffer_argument_is_null' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter+0xcd4): undefined reference tohalide_error_buffer_allocation_too_large' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter+0xcfb): undefined reference to halide_error_buffer_extents_too_large' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter+0xd23): undefined reference tohalide_error_device_dirty_with_no_device_support' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter+0xd4b): undefined reference to halide_error_host_is_null' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter+0xd85): undefined reference tohalide_error_bad_type' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter+0xdad): undefined reference to halide_error_bad_dimensions' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter+0xddb): undefined reference tohalide_error_access_out_of_bounds' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter+0xe23): undefined reference to halide_error_access_out_of_bounds' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter+0xe69): undefined reference tohalide_error_access_out_of_bounds' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter+0xeb2): undefined reference to halide_error_access_out_of_bounds' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter+0xeea): undefined reference tohalide_error_access_out_of_bounds' /usr/bin/ld: /media/user/Backup/Documents/projects/Halide/test/test/test_x86/libhalide_box_filter.a(halide_box_filter.o):halide_buffer_t.cpp:(.text.halide_box_filter+0xf16): more undefined references to halide_error_access_out_of_bounds' follow /usr/bin/ld: /media/user/Backup/Documents/projects/Halide/test/test/test_x86/libhalide_box_filter.a(halide_box_filter.o): in functionhalide_box_filter': halide_buffer_t.cpp:(.text.halide_box_filter+0xf44): undefined reference to halide_error_buffer_extents_negative' /usr/bin/ld: halide_buffer_t.cpp:(.text.halide_box_filter+0xf90): undefined reference tohalide_error_constraint_violated' collect2: error: ld returned 1 exit status make[2]: [CMakeFiles/box_filter_test.dir/build.make:101: box_filter_test] Error 1 make[1]: [CMakeFiles/Makefile2:83: CMakeFiles/box_filter_test.dir/all] Error 2 make: *** [Makefile:91: all] Error 2

the cmakelists.txt part 1 is as follow:

cmake_minimum_required(VERSION 3.22) project(box_filter_test) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED YES) set(CMAKE_CXX_EXTENSIONS NO) find_package(Halide REQUIRED) add_halide_generator(halide_box_filter.generator SOURCES box_filter.cpp) add_halide_library(halide_box_filter FROM halide_box_filter.generator REGISTRATION halide_reg_cpp TARGETS x86-64-linux SCHEDULE halide_box_filter AUTOSCHEDULER Halide::Adams2019 )

the cmakelists.txt part 2 is as follow:

cmake_minimum_required(VERSION 3.22) project(box_filter_test) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED YES) set(CMAKE_CXX_EXTENSIONS NO) find_package(Halide REQUIRED) add_executable(box_filter_test box_filter_test.cpp) target_link_libraries(box_filter_test PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/libhalide_box_filter.a Halide::Tools Halide::ImageIO )

The above two steps process will cause the above errors. While I use a single cmakelists as follow, it works fine:

cmake_minimum_required(VERSION 3.22) project(box_filter_test) set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED YES) set(CMAKE_CXX_EXTENSIONS NO) find_package(Halide REQUIRED) add_halide_generator(halide_box_filter.generator SOURCES box_filter.cpp) add_halide_library(halide_box_filter FROM halide_box_filter.generator REGISTRATION halide_reg_cpp TARGETS x86-64-linux SCHEDULE halide_box_filter AUTOSCHEDULER Halide::Adams2019 ) add_executable(box_filter_test box_filter_test.cpp) target_link_libraries(box_filter_test PRIVATE halide_box_filter Halide::Tools Halide::ImageIO )

My box_filter_test.cpp is as follow:

include "halide_benchmark.h"

include "halide_image_io.h"

include "HalideBuffer.h"

include

include "halide_box_filter.h"

int main(int argc, char **argv) { Halide::Runtime::Buffer<uint8_t, 3> input = Halide::Tools::load_image("images/input/155.png"); Halide::Runtime::Buffer<uint8_t, 3> output(input.width(), input.height(), input.channels()); double t = Halide::Tools::benchmark(10, 1, [&]() { halide_box_filter(input, output); }); Halide::Tools::save_image(output, "images/output/output.png"); }

I also tried to add include_directories() in the above part 2 cmakelists, and it didn't work. So anyone can help me with this issure? Any suggestion will be greatly appreciated!

ygsaber commented 1 year ago

linking the libhalide_box_filter.runtime.a lib in the part 2 cmakelist can solve the undefined reference when compile on x86-64-linux and for x86-64-linux, but when do cross compilation for arm-64-linux, there is no runtime.a lib generated, so the problem is still unsolved for cross compilation. It is weird that the source code of add_halide_library is supposed to generate runtime.a when cross compiling but not. Is it a bug or there is other things I have missed?

Also, I have tried to use g++ to generate the static lib instead of the part 1 cmakelist, and link the lib in part 2 cmakelist, the command is like following:

g++ ../../halide_generator/box_filter/box_filter.cpp ../../halide/x86-64-linux/share/Halide/tools/GenGen.cpp -g -std=c++17 -I ../../halide/x86-64-linux/include -L ../../halide/x86-64-linux/lib -lHalide -o generate

LD_LIBRARY_PATH=../../halide/x86-64-linux/lib ./$generator_dir/generate -g halide_box_filter -f halide_box_filter -e static_library,h,schedule -o . target=arm-64-linux

For this method, there is no issue when cross compilation and the test file can be run successfully on an android cell phone. I have used "nm -u" command to compare the static libs generated by part 1 cmakelist and the above g++ method. The lib generated by above g++ method doesn't have those undefined reference. How does the difference come from? I thought cmake is suppose to do more than the g++ method, but actually cmake compiled lib missed something. How does the difference come from?