Running a python script at build time in CMake, requires no dependencies - cmake

I have a python script h2py.py that converts a header file .hpp to .py file.
I want this python script to be run every time I build my project with CMake.
There is no other project or file that has a dependency on the file generated by the script.
So far I have tried this:
find_package(PythonInterp REQUIRED)
add_custom_target(
run ALL
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/include/converter/h2py.py ${CMAKE_CURRENT_SOURCE_DIR}/include/converter/
COMMENT "Converting .hpp file to .py file"
)
add_dependencies(converter run)
But this does not generate the .py equivalent of the .hpp file (specified within the script)
EDIT : When I run the python script h2py.py in a terminal, it generates the .py eqvivalent of the .hpp file, just as intended. But it does not generate the .py file when I run the CMake file.
This is the whole CMake file:
cmake_minimum_required(VERSION 2.8.3)
project(converter)
set(CMAKE_BUILD_TYPE release)
add_compile_options(-std=c++11)
## Find catkin macros and libraries
## if COMPONENTS list like find_package(catkin REQUIRED COMPONENTS xyz)
## is used, also find other catkin packages
find_package(catkin REQUIRED
roscpp
geometry_msgs
eigen_conversions
std_msgs
tf_conversions
tf
genmsg
message_generation
sensor_msgs
rospy
gazebo_msgs
)
catkin_package(
#DEPENDS Eigen libpcl-all-dev gnuplot
CATKIN_DEPENDS roscpp sensor_msgs tf_conversions tf geometry_msgs message_generation
INCLUDE_DIRS include
LIBRARIES ${PROJECT_NAME}
)
###########
## Build ##
###########
## Specify additional locations of header fils
## Your package locations should be listed before other locations
include_directories(
include
${catkin_INCLUDE_DIRS}
)
## Declare a C++ library
add_library(${PROJECT_NAME}
src/${PROJECT_NAME}/motion_covariance.cpp
src/${PROJECT_NAME}/tf_utils.cpp
)
target_link_libraries(${PROJECT_NAME} ${catkin_LIBRARIES} ${Boost_LIBRARIES} )
find_package(PythonInterp REQUIRED)
add_custom_target(
run ALL
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/include/converter/h2py.py ${CMAKE_CURRENT_SOURCE_DIR}/include/converter/
COMMENT "Converting .hpp file to .py file"
)
add_dependencies(converter run)

As per #Tsyvarev's comment, problem was solved by setting the WORKING_DIRECTORY option to the add_custom_command!

Related

CMake - How to get include directories of external project?

I tried to used https://github.com/julianxhokaxhiu/SteamworksSDKCI to use steam api on a simple SFML application (helloworld).
I wanted to use cmake to learn it, but I am struggling to understand how the provided CMakeLists and Find*.cmake file are expected to be used.
Currently, I have modified the CMakeLists to change the INSTALL_DIR
INSTALL_DIR "${CMAKE_BINARY_DIR}/../../vendor"
and my CMakeLists is :
cmake_minimum_required(VERSION 3.19)
project(SfmlWithCMake VERSION 1.0)
include(FetchContent)
set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake_steam")
# Configure external project
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_steam)
execute_process(
COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR}/cmake_steam
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_steam
)
# Build external project
execute_process(
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/cmake_steam
)
set(BUILD_SHARED_LIBS OFF)
FetchContent_Declare(
SFML
GIT_REPOSITORY https://github.com/SFML/SFML.git
GIT_TAG 2.5.1
)
FetchContent_MakeAvailable(SFML)
find_package(STEAMWORKSSDK REQUIRED)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED true)
# Generate config.h
configure_file(config.h.in config.h)
add_executable(
SfmlWithCMake
main.cpp
)
get_target_property(STEAMSDK STEAMWORKSSDK::STEAMWORKSSDK INCLUDE_DIRECTORIES)
target_include_directories(
SfmlWithCMake
PRIVATE
"${PROJECT_BINARY_DIR}"
"${STEAMSDK}"
)
target_link_libraries(
SfmlWithCMake
sfml-graphics
STEAMWORKSSDK::STEAMWORKSSDK
-static gcc stdc++ winpthread -dynamic
)
install(TARGETS SfmlWithCMake DESTINATION bin)
How to get include directories?
I do not succeed to add the steam include to the target_include_directories.
Here the ${STEAMSDK} is my last attempt to get the directory.
If I replace this by ${PROJECT_BINARY_DIR}/vendor/include, everything works.
Also, why does the SFML include are automatically added to my target include directories and not the steam one?
Am I using the Find*.cmake file the right way?
I understood that ExternalProject_Add was performed at build time and thus, as the find_package is needed at configue time, I added the two "execute_process". But, the readme on github only says to do the find package and add the target to target_link_libraries...
Thanks.

Correct way to build debian using Cmake and catkin?

I'm trying to build a debian using CMake/Cpack but am running into an issue. The problem is that I am getting unwanted files in my debian. It is caused by including a subdirectory, which contains a CMakeLists.txt that invokes catkin commands for ROS msg generation.
If I look at the contents of the debian I see generated header files in /usr/include/ and message files in /usr/share. But I only want my debian to have the files in /opt/bin which I specified using install().
Below is a simplified example. If I run the following commands:
mkdir build
cd build
cmake ..
make
cpack
The result is a deb package containing /opt/my-pkg/bin/main (which is great), but it also contains several files in /usr/local, /usr/lib, /usr/share that I don't want to be in the debian. I'm sure there must be a way using CMake/CPack to only create a debian with the specific files I want, but I'm not sure how to do it.
FILE TREE
+ my_project
+ CMakeLists.txt
+ main
+ CMakeLists.txt
+ main.cpp
+ my_msgs
+ CMakeLists.txt
+ package.xml
+ msg
+ BoundingBox.msg
# Top level CMakeLists.txt
cmake_minimum_required(VERSION 3.2 FATAL_ERROR)
project(my_project VERSION 1.0 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 11)
# put all executables into bin directory and all libraries into lib directory
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
# the directory name all targets will be installed to in the debian
set(install_dir "/opt/my-pkg/bin")
# LIST OF ALL DIRECTORIES TO BE BUILT
set(DIRS
my_msgs
main
)
foreach(dir ${DIRS})
add_subdirectory(${dir} ${dir})
endforeach()
# CPACK debian settings
set(CPACK_GENERATOR "DEB")
set(CPACK_DEBIAN_PACKAGE_MAINTAINER "Matthew Mosley")
include(CPack)
# my_msgs/CMakeLists.txt (this is the CMakeLists.txt that is generating extra unwanted files in my debian)
project(my_msgs)
find_package(catkin REQUIRED
geometry_msgs
message_generation
std_msgs
sensor_msgs
)
add_message_files(FILES BoundingBox.msg)
generate_messages(
DEPENDENCIES
geometry_msgs
std_msgs
sensor_msgs)
# my_msgs/package.xml
<?xml version="1.0"?>
<package>
<name>my_msgs</name>
<version>0.0.0</version>
<description> my_msgs package</description>
<license>BSD</license>
<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>std_msgs</build_depend>
<build_depend>uuid_msgs</build_depend>
<build_depend>geometry_msgs</build_depend>
<run_depend>roscpp</run_depend>
<run_depend>std_msgs</run_depend>
<run_depend>uuid_msgs</run_depend>
<run_depend>geometry_msgs</run_depend>
<export>
</export>
</package>

Combining two CMakeLists.txt file (ROS and Libtorch)

I am trying to combine two CMakeLists.txt files to compile a C++ program that has both ROS and Libtorch dependencies. The individual files are provided below:
Libtorch CMakeLists.txt file:
cmake_minimum_required(VERSION 3.0 FATAL_ERROR)
project(example-app)
find_package(Torch REQUIRED)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}")
add_executable(example-app example-app.cpp)
target_link_libraries(example-app "${TORCH_LIBRARIES}")
set_property(TARGET example-app PROPERTY CXX_STANDARD 14)
# The following code block is suggested to be used on Windows.
# According to https://github.com/pytorch/pytorch/issues/25457,
# the DLLs need to be copied to avoid memory errors.
if (MSVC)
file(GLOB TORCH_DLLS "${TORCH_INSTALL_PREFIX}/lib/*.dll")
add_custom_command(TARGET example-app
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
${TORCH_DLLS}
$<TARGET_FILE_DIR:example-app>)
endif (MSVC)
I found this here: https://pytorch.org/cppdocs/installing.html
ROS CMakeListis.txt file:
cmake_minimum_required(VERSION 2.8.3)
project(fly_bot_cpp)
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
geometry_msgs
tf
gazebo_msgs
)
include_directories(
include
${catkin_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
)
add_executable(example src/example.cpp)
target_link_libraries(example ${catkin_LIBRARIES})
The program example-app.cpp has both libraries of ROS and LibTorch.
So here is what i tried to do:
cmake_minimum_required(VERSION 2.8.3)
project(fly_bot_cpp)
set(CMAKE_PREFIX_PATH="home/jarvis/libtorch;/opt/ros/melodic")
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
geometry_msgs
tf
rospy
message_generation
)
find_package(Torch REQUIRED)
include_directories(
include
${catkin_INCLUDE_DIRS}
${Boost_INCLUDE_DIRS}
)
add_executable(test_quad src/test_quad.cpp)
target_link_libraries(test_quad ${catkin_LIBRARIES} "${TORCH_LIBRARIES}")
set_property(TARGET test_quad PROPERTY CXX_STANDARD 14)
The code test_quad.cpp (previously referred to as example-app.cpp) contains ros header files and torch header files:
#include "ros/ros.h"
#include <torch/torch.h>
.
.
.
However, I get the following error.
fatal error: torch/torch.h: No such file or directory
#include <torch/torch.h>
^~~~~~~~~~~~~~~
compilation terminated.
Can someone please help me out??
Thank you so much.
Remove the quotes around ${TORCH_LIBRARIES} in your target_link_libraries.
The line should look like this
target_link_libraries(test_quad ${catkin_LIBRARIES} ${TORCH_LIBRARIES})
This should resolve the torch header.
Please also take a look at this post to find some more answers to where you might get stuck in the future-https://answers.ros.org/question/347885/combining-cmakeliststxt-of-libtorch-and-cmakeliststxt-of-ros-package/#
I hope this answer is helpful to someone new coming onboard to ros and libtorch :)

Unknown Cmake command qt5_wrap_ui

I downloaded nitroshare.tar.gz file as i want to install it on my Kali Linux.
I followed up instructions as said on there github page to install it & downloaded all the packages that are required for the installation.
When i use cmake command it is showing me this error:
Unknown cmake command qt5_wrap_ui
Here is CMakeList.txt file:
cmake_minimum_required(VERSION 3.7)
configure_file(config.h.in "${CMAKE_CURRENT_BINARY_DIR}/config.h")
set(SRC
application/aboutdialog.cpp
application/application.cpp
application/splashdialog.cpp
bundle/bundle.cpp
device/device.cpp
device/devicedialog.cpp
device/devicelistener.cpp
device/devicemodel.cpp
icon/icon.cpp
icon/trayicon.cpp
settings/settings.cpp
settings/settingsdialog.cpp
transfer/transfer.cpp
transfer/transfermodel.cpp
transfer/transferreceiver.cpp
transfer/transfersender.cpp
transfer/transferserver.cpp
transfer/transferwindow.cpp
util/json.cpp
util/platform.cpp
main.cpp
)
if(WIN32)
set(SRC ${SRC} data/resource.rc)
endif()
if(APPLE)
set(SRC ${SRC}
data/icon/nitroshare.icns
transfer/transferwindow.mm
)
set_source_files_properties("data/icon/nitroshare.icns" PROPERTIES
MACOSX_PACKAGE_LOCATION Resources
)
endif()
if(QHttpEngine_FOUND)
set(SRC ${SRC}
api/apihandler.cpp
api/apiserver.cpp
)
endif()
if(APPINDICATOR_FOUND)
set(SRC ${SRC}
icon/indicatoricon.cpp
)
endif()
qt5_wrap_ui(UI
application/aboutdialog.ui
application/splashdialog.ui
device/devicedialog.ui
settings/settingsdialog.ui
transfer/transferwindow.ui
)
# Update the TS files from the source directory
file(GLOB TS data/ts/*.ts)
add_custom_target(ts
COMMAND "${Qt5_LUPDATE_EXECUTABLE}"
-silent
-locations relative
"${CMAKE_CURRENT_SOURCE_DIR}"
-ts ${TS}
)
# Create a directory for the compiled QM files
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/data/qm")
# Create commands for each of the translation files
set(QM_XML)
set(QM)
foreach(_ts_path ${TS})
get_filename_component(_ts_name "${_ts_path}" NAME)
get_filename_component(_ts_name_we "${_ts_path}" NAME_WE)
set(_qm_name "${_ts_name_we}.qm")
set(_qm_path "${CMAKE_CURRENT_BINARY_DIR}/data/qm/${_qm_name}")
set(QM_XML "${QM_XML}<file>qm/${_qm_name}</file>")
list(APPEND QM "${_qm_path}")
add_custom_command(OUTPUT "${_qm_path}"
COMMAND "${Qt5_LRELEASE_EXECUTABLE}"
-compress
-removeidentical
-silent
"${_ts_path}"
-qm "${_qm_path}"
COMMENT "Generating ${_ts_name}"
)
endforeach()
# Create a target for compiling all of the translation files
add_custom_target(qm DEPENDS ${QM})
# Configure the i18n resource file
set(QRC_QM "${CMAKE_CURRENT_BINARY_DIR}/data/resource_qm.qrc")
configure_file(data/resource_qm.qrc.in "${QRC_QM}")
qt5_add_resources(QRC
data/resource.qrc
"${QRC_QM}"
)
add_executable(nitroshare WIN32 MACOSX_BUNDLE ${SRC} ${UI} ${QRC})
target_compile_features(nitroshare PRIVATE
cxx_lambdas
cxx_nullptr
cxx_strong_enums
cxx_uniform_initialization
)
# In order to support Retina, a special tag is required in Info.plist.
if(APPLE)
set_target_properties(nitroshare PROPERTIES
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/Info.plist.in"
MACOSX_BUNDLE_ICON_FILE "nitroshare.icns"
MACOSX_BUNDLE_GUI_IDENTIFIER "com.NathanOsman.NitroShare"
MACOSX_BUNDLE_BUNDLE_NAME "NitroShare"
)
target_link_libraries(nitroshare "-framework ApplicationServices")
endif()
target_link_libraries(nitroshare Qt5::Widgets Qt5::Network Qt5::Svg)
if(Qt5WinExtras_FOUND)
target_link_libraries(nitroshare Qt5::WinExtras)
endif()
if(Qt5MacExtras_FOUND)
target_link_libraries(nitroshare Qt5::MacExtras)
endif()
if(QHttpEngine_FOUND)
target_link_libraries(nitroshare QHttpEngine)
endif()
if(APPINDICATOR_FOUND)
target_include_directories(nitroshare PRIVATE ${APPINDICATOR_INCLUDE_DIRS})
target_link_libraries(nitroshare ${APPINDICATOR_LIBRARIES})
endif()
include(GNUInstallDirs)
install(TARGETS nitroshare
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
BUNDLE DESTINATION .
)
if(WIN32)
# If windeployqt is available, use it immediately after the build completes to
# ensure that the dependencies are available.
include(DeployQt)
if(WINDEPLOYQT_EXECUTABLE)
windeployqt(nitroshare)
endif()
# If QHttpEngine was used, include it in the installer
if(QHttpEngine_FOUND)
add_custom_command(TARGET nitroshare POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E
copy_if_different "$<TARGET_FILE:QHttpEngine>" "$<TARGET_FILE_DIR:nitroshare>"
COMMENT "Copying QHttpEngine..."
)
endif()
# If Inno Setup is available, provide a target for building an EXE installer.
find_package(InnoSetup)
if(INNOSETUP_EXECUTABLE)
configure_file(dist/setup.iss.in "${CMAKE_CURRENT_BINARY_DIR}/setup.iss")
add_custom_target(exe
COMMAND "${INNOSETUP_EXECUTABLE}"
/Q
/DTARGET_FILE_NAME="$<TARGET_FILE_NAME:nitroshare>"
"${CMAKE_CURRENT_BINARY_DIR}/setup.iss"
DEPENDS nitroshare
COMMENT "Building installer..."
)
endif()
endif()
if(APPLE)
# If QHttpEngine was used, copy the dynlib over and correct its RPATH
if(QHttpEngine_FOUND)
add_custom_command(TARGET nitroshare POST_BUILD
COMMAND "${CMAKE_COMMAND}" -E
make_directory "$<TARGET_FILE_DIR:nitroshare>/../Frameworks"
COMMAND "${CMAKE_COMMAND}" -E
copy_if_different
"$<TARGET_FILE:QHttpEngine>"
"$<TARGET_FILE_DIR:nitroshare>/../Frameworks/$<TARGET_SONAME_FILE_NAME:QHttpEngine>"
COMMAND install_name_tool
-change
"$<TARGET_SONAME_FILE_NAME:QHttpEngine>"
"#rpath/$<TARGET_SONAME_FILE_NAME:QHttpEngine>"
"$<TARGET_FILE:nitroshare>"
COMMENT "Copying QHttpEngine and correcting RPATH..."
)
endif()
# If macdeployqt is available, use it immediately after the build completes to
# copy the Qt frameworks into the application bundle.
include(DeployQt)
if(MACDEPLOYQT_EXECUTABLE)
macdeployqt(nitroshare)
endif()
# Create a target for building a DMG that contains the application bundle and a
# symlink to the /Applications folder.
set(sym "${CMAKE_BINARY_DIR}/out/Applications")
set(dmg "${CMAKE_BINARY_DIR}/nitroshare-${PROJECT_VERSION}-osx.dmg")
add_custom_target(dmg
COMMAND rm -f "${sym}" "${dmg}"
COMMAND ln -s /Applications "${sym}"
COMMAND hdiutil create
-srcfolder "${CMAKE_BINARY_DIR}/out"
-volname "${PROJECT_NAME}"
-fs HFS+
-size 30m
"${dmg}"
DEPENDS nitroshare
COMMENT "Building disk image..."
)
endif()
# On Linux, include the icons, manpage, .desktop file, and file manager extensions when installing.
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/dist/icons"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}"
)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/dist/nitroshare.1"
DESTINATION "${CMAKE_INSTALL_MANDIR}/man1"
)
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/dist/nitroshare.desktop"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications"
)
# Configure and install Python extensions for Nautilus-derived file managers
foreach(_file_manager Nautilus Nemo Caja)
string(TOLOWER ${_file_manager} _file_manager_lower)
set(_py_filename "${CMAKE_CURRENT_BINARY_DIR}/dist/nitroshare_${_file_manager_lower}.py")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/dist/nitroshare.py.in" "${_py_filename}")
install(FILES "${_py_filename}"
DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/${_file_manager_lower}-python/extensions"
RENAME nitroshare.py
)
endforeach()
endif()
CMake doesn't know the function qt5_wrap_ui because you did not import Qt5 or any of the functions it defines.
Before calling qt5_wrap_ui, add this:
find_package(Qt5 COMPONENTS Widgets REQUIRED)
I used this line
find_package(Qt5Widgets)
In my Cmakelist.txt file
I found this on their Document Page of Qt5

ROS catkin_make executable is not generated in devel

I created a ROS package and added to the CMakeLists.txt the relevant lines to create an executable.
add_executable(exe_name src/file.cpp)
target_link_libraries(exe_name $LIBRARIES)
When I run catkin_make in the root of the workspace the executable is generated in WORKSPACE/build/PACKAGE_NAME/
instead of in
WORKSPACE/devel/lib/PACKAGE_NAME/
The problem is now when I run rosrun PACKAGE_NAME exe_name the executable name (exe_name) is not found. Any ideas why this might happen?
Edit - added the complete CMakeLists.txt
cmake_minimum_required(VERSION 2.8.3)
project(flea3ros)
find_package(catkin REQUIRED COMPONENTS
roscpp
rospy
std_msgs
sensor_msgs
cv_bridge
image_transport
)
find_package(OpenCV 2)
include_directories(
${catkin_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
/usr/include/flycapture
)
add_executable(flea3syncros src/asyncRos.cpp)
add_executable(flea3ros src/GigEGrabEx.cpp)
add_executable(flea3config src/GigEConfig.cpp)
add_executable(saveImages src/save_images.cpp)
target_link_libraries(flea3ros ${catkin_LIBRARIES} ${OpenCV_LIBS} flycapture)
target_link_libraries(flea3syncros ${catkin_LIBRARIES} ${OpenCV_LIBS} flycapture)
target_link_libraries(flea3config ${catkin_LIBRARIES} ${OpenCV_LIBS} flycapture)
target_link_libraries(saveImages ${catkin_LIBRARIES} ${OpenCV_LIBS})
The catkin_package macro is missing in your CMakeLists.txt. Add this after the find_package section:
###################################
## catkin specific configuration ##
###################################
## The catkin_package macro generates cmake config files for your package
## Declare things to be passed to dependent projects
## INCLUDE_DIRS: uncomment this if you package contains header files
## LIBRARIES: libraries you create in this project that dependent projects also need
## CATKIN_DEPENDS: catkin_packages dependent projects also need
## DEPENDS: system dependencies of this project that dependent projects also need
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES compute_cdist
# CATKIN_DEPENDS roscpp visualization_msgs robot_model_helper compute_cdist
# DEPENDS assimp Eigen mlpack
)
(You can remove the comments of course, I just copied the whole block so that the description is contained)