I work on ROS and I am blocked in CMAKE step.
So explain
build
devel
src
package_a
node_a
source
node_a.cpp
CMakeList.txt
package.xml
package_b
msg
msg_between_a_b.msg
node_b
source
node_b.cpp
CMakeList.txt
package.xml
I am blocked in the step of CMakeList.txt for package_a.
Package a need to know the message defined in package_b.
Error message from TERM console.
Add the installation prefix of "package_b" to CMAKE_PREFIX or set
"package_b_DIR" to a directory containing one of the above files. If
"package_b" provides a separate development package or SDK, be sure it
has been installed.
I am (very) interesting of "package_b_DIR".
That is what I write in CMalkeList.txt:
# SEARCH package that already EXIST in /opt/ros
find_package(catkin REQUIRED COMPONENTS
message_generation
rostime
roscpp
std_msgs
rosconsole
roscpp_serialization)
# Add package PACKAGE_B (usefull) for MSG
find_package(catkin REQUIRED COMPONENTS
package_b)
Very very thanks in advance !
Problem solved
1. ROS shall find package_b.
If true, you can find this file via this command:
find ./ -type f -name "*Config.cmake"
Result:
./build/package_b/catkin_generated/installspace/package_bConfig.cmake
./devel/share/package_b/cmake/package_bConfig.cmake
If not, open CMakeList.txt and check IF:
catkin_package(
)
Check success of build via catkin_make.
2. Inform that package a need package b
After inform package_a that need package_b.
This information is in the package.xml of package_a:
Find <build_depend> and inform that need package_b.
<build_depend>package_b</build_depend>
Related
I am making a project that has a deps folder with all its dependencies, currently it includes a git clone of SDL2 and SDL2_ttf. I'd like to get this project to work without having to install SDL2 or SDL2_ttf separately using home brew for example. My current approach is doing the follow, however, it seems like SDL2_ttf is failing to find the directory of SDL2, how can I fix it?
CMakelists.txt
cmake_minimum_required(VERSION 3.19)
project(app)
add_executable(app MACOSX_BUNDLE src/main.cpp)
# SDL2
add_subdirectory(deps/SDL2)
add_dependencies(app SDL2)
# SDL2_ttf
add_subdirectory(deps/SDL2_ttf)
add_dependencies(app SDL2_ttf)
Error message
CMake Error at deps/SDL2_ttf/CMakeLists.txt:12 (find_package):
By not providing "FindSDL2.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "SDL2", but
CMake did not find one.
Could not find a package configuration file provided by "SDL2" with any of
the following names:
SDL2Config.cmake
sdl2-config.cmake
Add the installation prefix of "SDL2" to CMAKE_PREFIX_PATH or set
"SDL2_DIR" to a directory containing one of the above files. If "SDL2"
provides a separate development package or SDK, be sure it has been
installed.
P.S. I tried doing SET(SDL2_DIR deps/SDL2) in my CMakeLists.txt as suggested in the error but that doesn't seem to be working, I get the same error message.
SDL2 does contain SDL2Config.cmake, I'm using the latest master of these repos:
https://github.com/libsdl-org/SDL
https://github.com/libsdl-org/SDL_ttf
My CMakeLists.txt file contains commands, which should be executed by make install, and all this works fine. The sample CMakeLists.txt below is a short excerpt from my actual CMake file (the tm0001.cpp content is not important here - it might be any C++ program):
cmake_minimum_required(VERSION 3.12)
project(tm0001)
set(CMAKE_CXX_STANDARD 11)
add_executable(${PROJECT_NAME} tm0001.cpp)
install(
TARGETS ${PROJECT_NAME}
DESTINATION /usr/local/bin
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
)
install(CODE "message(\"-- This must be called during installation only\")")
set(CPACK_PACKAGE_CONTACT "HEKTO")
set(CPACK_GENERATOR "DEB")
include(CPack)
I see the message command is executed by make package as well, which is not I want.
How to tell CMake not to execute installation scripts by the make package command? I couldn't find any way to do that with the CMake if command.
As it already said in the comment, it's an extremely bad idea to "work w/ systemd" (and doing anything not related to build or packaging of your project) from install commands. The install command (even SCRIPT and CODE signatures) are intended to be used for install actions and not for any other side effects.
The correct way to act here is to produce a native package (DEB/RPM) w/ post-install script, where using the system-provided macros (like described here), you can install your package properly. Take a look to CPACK_DEBIAN_PACKAGE_CONTROL_EXTRA for the way to provide package install actions.
The other bad thing is to use the hardcoded path (/usr/bin/). And BTW, a better place for the (pure) daemon app I suggest /usr/sbin/. Take a look to GNUInstallDirs module shipped w/ CMake for further references.
What I did was to specify install commands with CODE/SCRIPT as separate component e.g. install(CODE ... COMPONENT post-install).
Then also added other non-code install commands as a different component e.g. install(FILES ... COMPONENT files-install)
The CPack then needs to be configured to package only files-install component (solution to this can be found easily - hint: use CPACK_COMPONENTS_ALL_IN_ONE_PACKAGE, CPACK_COMPONENTS_ALL and CPACK_(RPM/DEB/...)_COMPONENT_INSTALL variables).
Of course then the resulting package won't run these CODE components during installing the package - they need to be added separately as a post install script.
I'm answering my own question, because the existing answer doesn't address my main problem. I couldn't find any way (on the CMake level) to block install commands from running during make package - even the postinst script is called by this command.
Fortunately, I could modify the postinst script itself to do nothing in case it's called not by the dpkg:
if [ -z ${DPKG_ADMINDIR} ]; then
echo "postinst: missing 'dpkg' environment (not an error during packaging)"
exit 0
fi
It's a trick of course, but it worked for me.
After creating a new package and code in it, I got the one below;
[rosrun] Couldn't find executable named tf_result below
/home/aybakana/catkin_ws/src/pcl_tutorials
I tried all sourcing stuff etc. but it does not work.
Does anyone know why it happens?
I figured it out that the reason is that I deleted the part below from CMakeLists.txt file.
catkin_package( ## if you dont add this, executables are not found
INCLUDE_DIRS include
LIBRARIES pcl_tutorials
CATKIN_DEPENDS geometry_msgs nav_msgs pcl_msgs roscpp rospy std_msgs
DEPENDS system_lib
)
For me, this occurred when I made invalid changes to my CMakeLists.txt. Ensure that the app can compile then try running catkin_make again.
If not, then try removing your devel and build folders and rebuild your application. Don't forget to source your setup.bash file: source ./devel/setup.bash before running your node again.
I am building a project using ROS and thus, catkin_make to build my ROS nodes and libraries.
The problem I'm facing is:
I am using a git submodule in one package (package A) (and thus, I have a hierarchical include folder structure) and I have difficulties referencing a header file within that submodule.
In order to build the package B, which is dependent on package A, I have added the INCLUDE_DIRS statement to the catkin_package command in package A:
catkin_package(
INCLUDE_DIRS my-submodule/include
...
)
The content of that directory is:
my-submodule/my-header.h
(I have put the header files under a folder, named after the submodule, as many tutorials stated that within ROS you should use this convention).
The include statement in a file from package-B reads like this:
...
#include <my-submodule/my-header.h>
...
This works fine - package B is being built (as I am using one combined workspace to build this).
But: When I switch to the target system, where I only install package A, and then try to build package B (on that target system), it does not build because the include paths are not setup correctly.
The INSTALL statement for package A looks like this
install(DIRECTORY my-submodule/include
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION}
FILES_MATCHING PATTERN "*.h"
PATTERN ".svn" EXCLUDE
)
This is mainly, because the installed folder structure on the target system looks like this:
.../ros/include/my-package-A/include/my-submodule/my-header.h
So, the install process actually puts that submodule's include-path under the package-A-include path (which is a different path structure compared to when I build the packages directly in one combined workspace).
And the CFLAGS for compilation only set the include directory to the folder:
.../ros/include
And thus, breaking my include statement in my package-B file:
#include <my-submodule/my-header.h>
Do you have any idea how to solve this?
I am sure there are more people than me, trying to reference header files from a submodule within a package.
Assuming you have a file my-submodule/include/my-submodule/my-header.h inside your package A, then two small changes to your install() statement should fix this:
install(DIRECTORY my-submodule/include/
DESTINATION ${CATKIN_GLOBAL_INCLUDE_DESTINATION}
FILES_MATCHING PATTERN "*.h"
PATTERN ".svn" EXCLUDE
)
First, add a slash to the path (.../include/ instead of .../include), which causes the contents of the include folder to be installed instead of the include folder itself (Otherwise you'll end up with ../ros/install/include/include/my-submodule/my-header.h)
Secondly, use ${CATKIN_GLOBAL_INCLUDE_DESTINATION} (which points to .../ros/install/include/) instead of ${CATKIN_PACKAGE_INCLUDE_DESTINATION} (which points to .../ros/install/my-package-A/include/) as destination.
The alternative would be to fix catkin, as
catkin_package(
INCLUDE_DIRS my-submodule/include
...
)
should theoretically already export my-submodule/include, so you can pick it up in package B with
find_package(catkin REQUIRED DEPENDS my-package-A)
catkin_package(
CATKIN_DEPENDS my-package-A
)
include_directories(${catkin_INCLUDE_DIRS})
Unfortunately, for some reason this is explicitely not possible when using catkin config --install. See https://answers.ros.org/question/335846/install_dirs-not-working-as-expected-when-using-install/.
I am currently trying to generate more than one debian package from my project. My only problem with this is setting the name, description, group and so forth of the packages.
# --------------------------------------------------------------
# Required CMake version
# --------------------------------------------------------------
CMAKE_MINIMUM_REQUIRED (VERSION 2.8)
# --------------------------------------------------------------
# Project name
# --------------------------------------------------------------
PROJECT (MyProject)
# --------------------------------------------------------------
# Find all source and header files
# --------------------------------------------------------------
FILE (GLOB all_H "*.h")
FILE (GLOB all_SRC "*.cpp")
# --------------------------------------------------------------
# Set compiler flags
# --------------------------------------------------------------
SET (CMAKE_CXX_FLAGS "-Wall -Wextra -O0 -g3")
# --------------------------------------------------------------
# Add a shared library
# --------------------------------------------------------------
ADD_LIBRARY (mylib SHARED ${all_H} ${all_SRC})
# --------------------------------------------------------------
# Configure components
# --------------------------------------------------------------
SET (CPACK_DEB_COMPONENT_INSTALL 1)
# --------------------------------------------------------------
# Install
# --------------------------------------------------------------
INSTALL(TARGETS mylib DESTINATION ../lib COMPONENT main)
INSTALL(FILES ${all_H} DESTINATION ../include COMPONENT dev)
# --------------------------------------------------------------
# CPack package and package_source targets
# --------------------------------------------------------------
SET (CPACK_GENERATOR "TGZ;DEB")
SET (CPACK_SET_DESTDIR ON)
SET (CPACK_PACKAGE_NAME "mypackage")
SET (CPACK_PACKAGE_VENDOR "me")
SET (CPACK_PACKAGE_DESCRIPTION_SUMMARY "this is my package description")
SET (CPACK_DEBIAN_PACKAGE_DESCRIPTION "this is my package description
here comes detailed description text.")
INCLUDE (CPack)
The manual has some properties and commands for CPack Components but I doesn't seem to find the right ones or the right place to change at least name and description for every single package/component.
I tried using SET (CPACK_COMPONENT_MAIN_DISPLAY_NAME "main display name") and SET (CPACK_COMPONENT_main_DISPLAY_NAME "main display name") as well as cpack_add_component() before INCLUDE(CPack) (which gives me an error) and after (which seems to be ignored).
Did anybody get this to work and knows the right way to do this?
From last few days I am searching for such solution.
Let me first explain first my requirement and then how did i managed to solve problem.
I want to create 4 package from my single project
Master package: Which contains all binary,static/shared libraries,header files,configuration files and scripts.
Runtime package: Which contains only executable which are required to run my application i.e. binary ,shared library and scripts.
Configuration package: Which contains basic skeleton and place holder for configuration file.
Development packages: Which contains shared/static library and header files.
Generating Master package is easy one and straight forward. But If I use that way then I am unable to use other packages. So after struggling and scraping documents and mail archives, I came to one solution or workaround.
In my solution I am creating One extra custom target for each package I want to create. On that target I am creating other cmake project, which has list of files(Absolute location of file) to be install in that package, build that project and last create package by calling cpack.
Here is my solution.
There may be better/scale-able solution than this, If any one come across that please let me know.
I'm a bit late to the party but in CMake before version 3.5 components packaging was not supported for CPack debian packages.
From version 3.5 on quite a few per component features were added so the easiest way to solve you problem would be to bump the version of CMake and set the variables described in the documentation:
https://cmake.org/cmake/help/v3.5/module/CPackDeb.html or a newer one
https://cmake.org/cmake/help/v3.9/module/CPackDeb.html