pcl
pcl copied to clipboard
[cmake] Is it possible to use FetchContent to bring in PCL?
Describe the bug
I am trying to bring PCL dependency with CMakes FetchContent
Functionality.
Context
FetchContent
will download PCL repo at config time and MakeAvailable
populates the source folder of pcl.
Then PCL will be built along the original project.
--- CMakeLists.txt ---
cmake_minimum_required(VERSION 3.0.2)
project(fetch_content_example)
include(FetchContent)
FetchContent_Declare(
PCL
GIT_REPOSITORY https://github.com/PointCloudLibrary/pcl.git
GIT_TAG pcl-1.12.0# release-1.12.0
)
FetchContent_MakeAvailable(PCL)
add_library(${PROJECT_NAME}_parser
src/parser.cpp
)
target_link_libraries(${PROJECT_NAME}_parser pcl_common)
--- src/parser.hpp ---
#ifndef PARSER_H
#define PARSER_H
# pragma once
#include <pcl/point_types.h>
# code
--- src/parser.cpp ---
# Implementation
After invoking cmake and then start to build the project, PCL builds succesfully but when building src/parser.cpp
an error occurs of fatal error: pcl/point_types.h: No such file or directory #include <pcl/point_types.h>
.
I tried multiple include structures such as
#include <pcl/pcl/point_types.h>
#include <pcl-1.12.0/pcl/point_types.h>
with the same error.
Expected behavior I don't know if it should be supported (other than building from source and installing it) but I would expect to be able to find the header files.
Current Behavior
No build produced To Reproduce Files containing the code above. mkdir && cd build cmake .. make -j8
Your Environment (please complete the following information):
- OS: [e.g. Ubuntu 18.04]
- Compiler: [:eg GCC 7.5]
- PCL Version [e.g. tag pcl-1.12.0]
I have never used FetchContent before, so the problem might only occur if that is used, but you could check out this tutorial on how to use PCL via CMake. Especially the command include_directories(${PCL_INCLUDE_DIRS})
might be missing. I know in modern CMake it is possible to simply specify a target as a dependency via target_link_libraries
and also automatically be aware of all header directories, but I can't guarantee that PCL supports that already.
Yes i am aware of that possibility to use PCL with CMAKE. I just wanted to try it and since FetchContent is a 'fairly' new feature of CMake, report it. According to docs of FetchContent_Declare()
and FetchContent_MakeAvailable()
there is no need for include_directories
(if not mistaken), as it automagically calls add_subdirectory()
under the hood.
I don't know though if that' something you would want to look at, but i guess it can be a good source to bring PCL from in projects when there is no PCL library available.
Is there a guide on how to make a CMake project work with FetchContent?
@SunBlack As my goto expert of CMake, perhaps you can shine a light on OP's issues
Have to try it myself. Maybe I have next time week for this experiment (the next two working days looks bad).
Another error, i have encountered, is that if i bring multiple projects with FetchContent
that define the same target like uninstall
or docs
, CMake will fail with
CMake Error at /home/***/ros_ws/git_ws/build/fetch_content_example/_deps/kindr-src/CMakeLists.txt:138 (add_custom_target):
add_custom_target cannot create target "uninstall" because another target
with the same name already exists. The existing target is a custom target
created in source directory
"/home/***/ros_ws/git_ws/build/fetch_content_example/_deps/pcl-src".
See documentation for policy CMP0002 for more details.
Example CMakeLists.txt (rest same with original on 1st comment) with FetchContent
of PCL and kindr library
FetchContent_Declare(
PCL
GIT_REPOSITORY https://github.com/PointCloudLibrary/pcl.git
GIT_TAG pcl-1.12.0# release-1.12.0
)
FetchContent_Declare(
kindr
GIT_REPOSITORY https://github.com/ANYbotics/kindr
GIT_TAG 1.2.0
)
FetchContent_MakeAvailable(PCL kindr)
Checked it now.
I printed the content of pcl_common
just before your call to target_link_libraries
via this script. There INCLUDE_DIRECTORIES
contains the correct include directory (<buildDir>/_deps/pcl-src/common/include
) (and as IMPORTED
is false INCLUDE_DIRECTORIES
should be imho correct). Nevertheless MSVC doesn't show any any include directories. I debugged it a little bit within CMake now, but it seems this is resolved just in the generation step. But as the PCL is even within resolved within this steps, it doesn't make fun to debug it. So I suggest to ask for help within the CMake issue tracker.
In general I wouldn't recommend to use FetchContent
im combination with the PCL. As you can see, you pollute your workspace with targets like the INSTALL
target, which may conflict with other projects.
If you want to simplify the setup of your project, use vcpkg (Windows) or pkg (Unix).
Thanks for checking it out.
I figured it would be pain to debug this out, and probably there is no need to support this feature of CMake.
Yeah the best course of action i guess it is vckpg or others, but that's just that. You must require the users to have it to ease the process, where CMake is your config/build tool anyways.
In general find_package(PCL REQUIRED)
should be enough as it automatically find the PCL components in case they are installed via libpcl-dev
(Unix). On Windows just pass the directory to the PCL install dir and everything is fine (or use vcpkg). On this way the other devs doesn't have to compile PCL multiple times in case they have multiple copies on your project on the disk.
Even there are a few projects which doesn't recommend this way (e.g. GoogleTest), I prefer this way as I mostly have multiple copies of a single project on the disc.
Yes i completely understand the problems involved ( i think). I was just curious and if it can be an option to fetch pcl like this why not offer it.
I get what your saying about multiple copies ( i guess diff versions) but fetchcontent
can be used if find_package()
fails meaning PCL is not already installed. Moreover libpcl-dev
is mostly outdated on older OS Linux machines so FetchContent
can bring any version you want by specifying the commit hash or tag.
GoogleTest cmake quickstart uses FetchContent
unless i read an outdated one.
@xkaraman I have used Fetch Content and I think you should link the Fetch content "target" into your main project
--- CMakeLists.txt ---
cmake_minimum_required(VERSION 3.0.2)
project(fetch_content_example)
include(FetchContent)
.
.
.
target_link_libraries(${PROJECT_NAME}_parser PCL)
This will enable all include/library content