PointCloudLibrary / pcl

Point Cloud Library (PCL)
https://pointclouds.org/
Other
9.88k stars 4.61k forks source link

[compile error] Linker error: libpcl_io_ply.a is not added to ${PCL_LIBRARIES}, nor is it linked to libpcl_io. #4422

Open tsijs opened 4 years ago

tsijs commented 4 years ago

When compiling pcl with vcpkg, and using #include <pcl/io/ply_io.h>, there occures a linker error which happens because libpcl_io_ply.a is not added to ${PCL_LIBRARIES}, nor is it linked to libpcl_io.a

Please paste the compilation results/errors.

To Reproduce

Remember to reproduce the error in a clean rebuild (removing all build objects and starting build from scratch)

Your Environment (please complete the following information):

If PCL was compiled from source or failure in compiling PCL itself:

If compiling against PCL:

Possible Solution

It seems that pcl_io is not linked to pcl_io_ply when building pcl statically, hence it needs pcl_io_ply when linked to, but there is no nice way to obtain the location of pcl_io_ply, because it is not available in the libraries cmake variable.

So my naive proposal would be: either make pcl_io with pcl_io_ply or add it to the libraries variable.

wyhao31 commented 3 years ago

Same problem here.

@tsijs , do you have a solution now?

alokpr commented 3 years ago

https://github.com/PointCloudLibrary/pcl/blob/pcl-1.11.1/io/CMakeLists.txt#L3

io subsystem only declares dependency on "common" and "octree" subsystems, so only those dependencies appear in PCLConfig.cmake. The easiest way to fix this would be to merge pcl_io_ply into pcl_io target. Another option might be to make pcl_io_ply as subsubsystem of pcl_io subsystem.

I think there are additional problems with static libraries. Dependencies on third-party libraries like boost, vtk, etc also need to be specified for in EXT_DEPS, which seems to be missing here: https://github.com/PointCloudLibrary/pcl/blob/pcl-1.11.1/io/CMakeLists.txt#L10

I am not sure why pcl project decided to implement custom script to generate PCLConfig.cmake instead of just using cmake install(EXPORT): https://cmake.org/cmake/help/latest/command/install.html#export

tsijs commented 3 years ago

Maybe a little too late to the party, but I worked around the problem by adding the io lib manually in my own cmakelist.

It doesn't deserve an elegance medal, but it works:

set(PCL_PLY_IO_LIBRARY_PATH "${VCPKG_ROOT_DIR}/installed/x64-linux/lib/libpcl_io_ply.a")

target_link_libraries(${PROJECT_NAME} PRIVATE ${PCL_PLY_IO_LIBRARY_PATH} }

jasjuang commented 3 years ago

I just ran into the same problem and can be reproduced with the minimal example below:

./vcpkg install pcl

CMakeLists.txt

set(CMAKE_TOOLCHAIN_FILE $ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake)

cmake_minimum_required(VERSION 3.20)

project(example)

find_package(PCL)

add_executable(${PROJECT_NAME} ${PROJECT_SOURCE_DIR}/main.cpp)

target_link_libraries(${PROJECT_NAME} ${PCL_LIBRARIES})

main.cpp

#include "pcl/io/ply_io.h"
#include "pcl/point_types.h"

int main() {
  std::string ply_file;
  pcl::PointCloud<pcl::PointXYZ> cld;

  pcl::PLYReader Reader;

  Reader.read(ply_file, cld);

  return 0;
}

mkdir build && cd build && cmake .. && make shows the below error:

[ 50%] Building CXX object CMakeFiles/example.dir/main.cpp.o
[100%] Linking CXX executable example
/usr/bin/ld: /home/jasjuang/vcpkg/installed/x64-linux/lib/libpcl_io.a(ply_io.cpp.o): in function `pcl::PLYReader::parse(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)':
ply_io.cpp:(.text+0x2ca3): undefined reference to `pcl::io::ply::ply_parser::parse(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/example.dir/build.make:130: example] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/example.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
JackBoosY commented 2 years ago

This issue can NOT easily fixed.

pcl_io_ply is a submodule of pcl_io, and the build statement is placed in io/CMakeLists.txt.

However, pcl declares dependencies through internal SUBSYS_DEPS, and all subsystems use the related folder names, which means that pcl_io_ply cannot be used as one of the subsystems, and is added as a dependency of pcl_io using the internal dependency processing mode of pcl.

Moreover, pcl does not use the cmake export function, but uses SUBSYS_DEPS to configure PCLConfig.cmake.in to generate PCLConfig.cmake, which means that we cannot fix this problem through target_link_libraries.

themightyoarfish commented 2 years ago

the undefined symbol error for pcl::io::ply::ply_parser::parse(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) suddenly showed up for me with 1.11 with a static build also, despite having successfully used it for shared libraries. Any workarounds?

liuzhy71 commented 2 years ago

same error for me, any progress?

larshg commented 2 years ago

You can add in your CmakeLists something like: target_link_libraries(${PROJECT_NAME} ${PCL_LIBRARIES}) // original from @jasjuang example target_link_libraries(${PROJECT_NAME} pcl_io_ply) // added line that solves the linking error (given the path where the libraries is located is added) Then it builds fine.

dg0yt commented 6 months ago

undefined symbol error for pcl::io::ply::ply_parser::parse(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&)

Still an issue. (Trying to fix the rtabmap vcpkg port for x64-linux static linkage.) pcl_io_ply is a lib with usage requirements, but without pkg-config file and not handled by CMake config/modules.

dg0yt commented 6 months ago

Tentative patch which keeps the separate lib: https://github.com/microsoft/vcpkg/blob/368313ea0e506006ca7930cae74efe14766a82d8/ports/pcl/io_ply.patch

Upstream, please choose between keeping separate libs and merging (https://github.com/miriameng/pcl/commit/25f22aee8285e1e7fb0a1dabaffa5efcc90b1186).

dzenanz commented 6 months ago

I am running into the same issue on Windows. My workaround is additional CMake code: target_link_libraries (interactive_icp debug pcl_io_plyd optimized pcl_io_ply)