My goal is to cross-compile an application which exists on Windows using an external SDK toolchain being build on Linux machine in order to have an executable code for my ARM platform
I am using VisualStudio CMake project on Windows machine.
I am using an external SDK in order to cross-compile my C++ program for Linux arm architecture.
I have build this SDK using Yocto project on my Linux machine ( NOT THE ARM PLATFORM ! )
My CMake toolchain file path on my Linux machine is :
/opt/poky-atmel/2.5.3/sysroots/x86_64-pokysdk-linux/usr/share/cmake/OEToolchainConfig.cmake
I can see that there are multiple cross-compilers that may be used by my SDK under this path :
/opt/poky-atmel/2.5.3/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi
I can mention arm-poky-linux-gnueabi-gcc compiler which I want to use to cross-compile my application and execute it on my ARM platform.
Before including the path of this cross-compiler to my VisualStudio CMakeSettings file, I have tried to use it on my Linux machine ( which hosts my SDK ) in order to compile a simple code and execute it on the ARM platform. I have succeded to do that!
A little remarque that I must source and setup the environment in order to export the important paths and variables of the SDK toolchain so I can compile my code.
Now, after I have been sure about the good work of my SDK cross compiler, I have to use it in VisualStudio on my windows machine and that's for the same purpose ( cross compiling my code in order to use it on my ARM architecture ).
After opening a CMake project on VisualStudio and connecting to my Linux system following these steps :
Remote Connection
I have modified all the settings I need in order to achieve my goal.
You can see here my c++ .cpp file code which is using the Boost library :
#include "CMakeProject4.h"
#include <boost/lambda/lambda.hpp>
#include <iostream>
#include <iterator>
#include <algorithm>
using namespace std;
int main()
{
typedef std::istream_iterator<int> in;
std::cout << "Type in any number: ";
std::for_each(
in(std::cin), in(), std::cout
<< (boost::lambda::_1 * 10)
<< "\nType in another number: ");
}
This is my CMakeList.txt :
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED OFF)
set(Boost_USE_STATIC_RUNTIME OFF)
list(APPEND CMAKE_PREFIX_PATH /opt/poky-atmel/2.5.3/sysroots/cortexa5hf-neon-poky-linux-gnueabi/usr/include)
set(Boost_NO_BOOST_CMAKE ON)
message(STATUS "CMAKE_TOOLCHAIN_FILE='${CMAKE_TOOLCHAIN_FILE}'")
set(CROSS_COMPILER_DIR /opt/poky-atmel/2.5.3/sysroots/x86_64-pokysdk-linux/usr)
set(CMAKE_C_COMPILER ${CROSS_COMPILER_DIR}/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc)
set(CMAKE_CXX_COMPILER ${CROSS_COMPILER_DIR}/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc)
message(STATUS "CMAKE_C_COMPILER='${CMAKE_C_COMPILER}'")
message(STATUS "CMAKE_CXX_COMPILER='${CMAKE_CXX_COMPILER}'")
find_package(Boost 1.66.0)
if(Boost_FOUND)
message (STATUS "success!")
add_executable (CMakeProject4 "CMakeProject4.cpp" "CMakeProject4.h")
include_directories(${Boost_INCLUDE_DIRS})
target_link_libraries(CMakeProject4 ${Boost_LIBRARIES})
endif()
This is my CMakeSettings.json file :
{
"configurations": [
{
"addressSanitizerRuntimeFlags": "detect_leaks=0",
"buildCommandArgs": "",
"cmakeCommandArgs": "cmake -DBoost_DEBUG=ON -DCMAKE_CXX_COMPILER=/opt/poky-atmel/2.5.3/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc",
"cmakeExecutable": "/home/ubuntu/CMake/Executable",
"cmakeToolchain": "/opt/poky-atmel/2.5.3/sysroots/x86_64-pokysdk-linux/usr/share/cmake/OEToolchainConfig.cmake",
"configurationType": "RelWithDebInfo",
"ctestCommandArgs": "",
"generator": "Unix Makefiles",
"inheritEnvironments": [ "linux_arm" ],
"name": "Linux-Release",
"remoteBuildRoot": "/home/ubuntu/CMake/RemoteBR",
"remoteCMakeListsRoot": "/home/ubuntu/CMake/RemoteCML",
"remoteCopyBuildOutput": false,
"remoteCopySources": true,
"remoteCopySourcesExclusionList": [ ".vs", ".git", "out" ],
"remoteCopySourcesMethod": "rsync",
"remoteInstallRoot": "/home/ubuntu/CMake/RemoteIL",
"remoteMachineName": "867574967;192.168.1.12 (username=ubuntu, port=22, authentication=PrivateKey)",
"rsyncCommandArgs": "-t --delete --delete-excluded",
"variables": [
{
"name": "Boost_INCLUDE_DIRS",
"value": "/opt/poky-atmel/2.5.3/sysroots/cortexa5hf-neon-poky-linux-gnueabi/usr/include",
"type": "PATH"
},
{
"name": "Boost_LIBRARIES",
"value": "/opt/poky-atmel/2.5.3/sysroots/cortexa5hf-neon-poky-linux-gnueabi/usr/lib",
"type": "PATH"
},
{
"name": "Boost_INCLUDE_DIR",
"value": "/opt/poky-atmel/2.5.3/sysroots/cortexa5hf-neon-poky-linux-gnueabi/usr/include",
"type": "PATH"
}
]
}
]
}
As you can see I am setting my SDK compilers bin paths to CMAKE_CXX_COMPILER variable.
This is also OEToolchainConfig.cmake file which I find on my Linux machine :
set( CMAKE_SYSTEM_NAME Linux )
set( CMAKE_C_FLAGS $ENV{CFLAGS} CACHE STRING "" FORCE )
set( CMAKE_CXX_FLAGS $ENV{CXXFLAGS} CACHE STRING "" FORCE )
set( CMAKE_ASM_FLAGS ${CMAKE_C_FLAGS} CACHE STRING "" FORCE )
set( CMAKE_LDFLAGS_FLAGS ${CMAKE_CXX_FLAGS} CACHE STRING "" FORCE )
set( CMAKE_FIND_ROOT_PATH $ENV{OECORE_TARGET_SYSROOT} $ENV{OECORE_NATIVE_SYSROOT} )
set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER )
set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY )
set( CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY )
# Set CMAKE_SYSTEM_PROCESSOR from the sysroot name (assuming processor-distro-os).
if ($ENV{SDKTARGETSYSROOT} MATCHES "/sysroots/([a-zA-Z0-9_-]+)-.+-.+")
set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_MATCH_1})
endif()
# Include the toolchain configuration subscripts
file( GLOB toolchain_config_files "${CMAKE_TOOLCHAIN_FILE}.d/*.cmake" )
foreach(config ${toolchain_config_files})
include(${config})
endforeach()
I have sourced the environment on my Linux machine and then I try to compile.
This is the command I use to compile my code :
cmake -DBoost_DEBUG=ON -DCMAKE_CXX_COMPILER=/opt/poky-atmel/2.5.3/sysroots/x86_64-pokysdk-linux/usr/bin/arm-poky-linux-gnueabi/arm-poky-linux-gnueabi-gcc
But, this message occurs from CMake saying that the compiler is broken and some other things that CMake can not find :
CMake message
This is my CMakeCache file where you can see what variables ( compilers and other things .. ) used by my project :
CMakeCache
The first thing I guess, the environment was not setup correctly or VisualStudio is not seeing the environment variable after sourcing the environment from my Linux machine. This is just an opinion.
I don't know realy what is the problem here and why I can not compile my code.
I will appreciate your help!
Thank you!
EDIT
I add the log files :
Here is the CMakeError.log file :
CMakeError.log
Here is CMakeOutput.log file :
CMakeOutput.log
My guess here would be that the OEToolchainConfig.cmake file uses environment variables to find e.g. the target sysroot, the $ENV{OECORE_TARGET_SYSROOT} part, and that is why it's not working.
You write that you have sourced the environment-setup script on your linux machine, but that won't have any effect on the environment when you're trying to build from VS from Windows.
Either see if there's a way that you can make the build via VS use the environment script, or simply see what values the environment variables used in OEToolchainConfig.cmake have on the linux machine after sourcing the setup script, and replace the $ENV{} parts of OEToolchainConfig.cmake with the actual values instead.
I had the same problem as you and this post helped find out a solution for this.
Error messages like:
ld: cannot find crt1.o: No such file or directory
are linker errors likely due to not having specified a sysroot in your build command.
In VS 2022 I have been able to cross-compile a simple hello world program.
Here is the relevant section of my CMakePresets.json:
{
"name": "linux-debug",
"displayName": "Linux Debug",
"generator": "Unix Makefiles",
"toolchainFile": "/opt/fslc-framebuffer/2.4.1/sysroots/x86_64-fslcsdk-linux/usr/share/cmake/OEToolchainConfig.cmake",
"environment": {
"CXX": "/opt/fslc-framebuffer/2.4.1/sysroots/x86_64-fslcsdk-linux/usr/bin/arm-fslc-linux-gnueabi/arm-fslc-linux-gnueabi-g++ -march=armv7-a -mthumb -mfpu=neon -mfloat-abi=hard --sysroot=/opt/fslc-framebuffer/2.4.1/sysroots/armv7at2hf-neon-fslc-linux-gnueabi",
"CFLAGS": "-O2 -pipe -g -feliminate-unused-debug-types",
"CXXFLAGS": "-O2 -pipe -g -feliminate-unused-debug-types",
"OECORE_TARGET_SYSROOT": "/opt/fslc-framebuffer/2.4.1/sysroots/armv7at2hf-neon-fslc-linux-gnueabi",
"OECORE_NATIVE_SYSROOT": "/opt/fslc-framebuffer/2.4.1/sysroots/x86_64-fslcsdk-linux",
"SDKTARGETSYSROOT": "/opt/fslc-framebuffer/2.4.1/sysroots/armv7at2hf-neon-fslc-linux-gnueabi"
},
"binaryDir": "${sourceDir}/out/build/${presetName}",
"installDir": "${sourceDir}/out/install/${presetName}",
"cacheVariables": {
"CMAKE_BUILD_TYPE": "Debug"
},
"condition": {
"type": "equals",
"lhs": "${hostSystemName}",
"rhs": "Linux"
},
"vendor": {
"microsoft.com/VisualStudioRemoteSettings/CMake/1.0": {
"sourceDir": "$env{HOME}/.vs/$ms{projectDirName}"
}
}
}
Note that I added the reference to my toolchain file (key: toolchainFile) and set up the environment variables as needed (these would be set by sourcing your SDK).
So, no need to source the SDK first, just tell VS where to find the toolchainFile and make sure all relevant environment variables are set.
Related
I'm trying to build a Qt installer for my app using CMake and CPack with it's CPackIFW plugin. I'm using Windows. I've defined the main application component and a library, they both appear in the installer and are installed correctly. I also have a CPack pre-build script that runs windeployqt and adds the DLLs required by the application. However, as the DLLs are copied into the same folder as the main executable, I can't make them separate components. Is there a way to separate my artifacts from Qt DLLs and still be able to run the application after installation?
Here's my CMakeLists:
cmake_minimum_required(VERSION 3.22)
project(untitled-bot VERSION 0.1 LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt6 REQUIRED COMPONENTS Core Widgets HttpServer TextToSpeech Sql)
qt_standard_project_setup()
set(app_icon_resource_windows "${CMAKE_CURRENT_SOURCE_DIR}/main.rc")
set(PROJECT_SOURCES
# sources here
)
qt_add_executable(untitled-bot
MANUAL_FINALIZATION
${PROJECT_SOURCES}
${app_icon_resource_windows}
)
set(executable_path "\${QT_DEPLOY_BIN_DIR}/$<TARGET_FILE_NAME:untitled-bot>")
qt_finalize_executable(untitled-bot)
add_subdirectory(external/lua)
target_link_libraries(untitled-bot
PRIVATE lua::lib
PRIVATE Qt6::Widgets
PRIVATE Qt6::HttpServer
PRIVATE Qt6::TextToSpeech
PRIVATE Qt6::Sql
)
target_include_directories(
untitled-bot
PRIVATE external/sol
)
set_target_properties(untitled-bot PROPERTIES
WIN32_EXECUTABLE TRUE
)
add_custom_target(copy_assets
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_LIST_DIR}/scripts ${CMAKE_CURRENT_BINARY_DIR}/scripts
)
add_dependencies(untitled-bot copy_assets)
include(GNUInstallDirs)
install(TARGETS untitled-bot
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT main_app
)
install(TARGETS lua
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT main_app
)
#I think this should have added the dependencies component to the installer, but it didn't; however, the runtime DLLs are still added by `windeployqt` so this step can be omitted, I guess
set(CMAKE_INSTALL_SYSTEM_RUNTIME_COMPONENT runtime_dependencies)
include(InstallRequiredSystemLibraries)
set(CPACK_GENERATOR "IFW")
set(CPACK_IFW_ROOT "I:/Qt/Tools/QtInstallerFramework/4.4/")
set(CPACK_PACKAGE_VERSION_MAJOR "1")
set(CPACK_PACKAGE_VERSION_MINOR "0")
set (CPACK_IFW_PACKAGE_NAME "application")
set (CPACK_IFW_PACKAGE_TITLE "application Installer")
set (CPACK_IFW_PACKAGE_WIZARD_STYLE "Modern")
set (CPACK_IFW_PACKAGE_WIZARD_SHOW_PAGE_LIST ON)
set(CPACK_RESOURCE_FILE_LICENSE ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.txt)
find_program(WINDEPLOYQT windeployqt HINTS "${_qt_bin_dir}")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/deploy-qt-windows.cmake.in" "${CMAKE_CURRENT_SOURCE_DIR}/deploy-qt-windows.cmake" #ONLY)
set(CPACK_PRE_BUILD_SCRIPTS ${CMAKE_CURRENT_SOURCE_DIR}/deploy-qt-windows.cmake)
set(CPACK_IFW_VERBOSE true)
include(CPack)
include(CPackIFW)
message(STATUS "${WORK_BIN_DIR}")
# this appears in the installer and is installed correctly; however, Qt DLLs are also part of the "main application" component
cpack_add_component(main_app DISPLAY_NAME "Main Application" DESCRIPTION "aaa" REQUIRED)
# this doesn't appear in the installer
cpack_add_component(runtime_dependencies DISPLAY_NAME "runtime dependencies" DESCRIPTION "bbb" REQUIRED)
# List controlling which components are installed
get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS)
# I also tried using set(CPACK_COMPONENTS_ALL "main_app;runtime_dependencies") but it doesn't add runtime libraries to the selection list
#set(CPACK_COMPONENTS_ALL main_app)
# in my case this only shows main_app
message(STATUS "CPACK_COMPONENTS_ALL = " ${CPACK_COMPONENTS_ALL})
# Install the runtime libs
cpack_ifw_configure_component(runtime_dependencies ESSENTIAL FORCED_INSTALLATION)
# The main app component HAS to be installed
cpack_ifw_configure_component(main_app ESSENTIAL FORCED_INSTALLATION)
# Adds license info to package.xml file
# Also copies licence.txt to 'meta' directory to display the license text in the installer.
cpack_ifw_configure_component(main_app LICENSES "GPLv3" ${CPACK_RESOURCE_FILE_LICENSE})
deploy-qt-windows.cmake.in:
set(WINDEPLOYQT "#WINDEPLOYQT#")
execute_process(COMMAND ${WINDEPLOYQT} "--no-quick-import" "--no-translations" "--no-system-d3d-compiler" "--no-opengl-sw" "${CPACK_TEMPORARY_INSTALL_DIRECTORY}/packages/main_app/data/bin")
It copies the required Qt libraries to the bin directory containing the application exe and they are picked up by CPack as part of the main app component.
Can you help me fix this?
Update: edited the original question to remove one of the problems, the one stated in the title still persists
I'm using Visual Studio 2022 with VCPKG to build a simple test program that opens a OpenCV VideoCapture object with a gstreamer pipeline to a RTSP feed.
#include <iostream>
#include <opencv2/opencv.hpp>
int main()
{
auto path = "rtspsrc location=rtsp://username:password#192.168.0.115 ! rtph264depay ! h264parse ! nvh264dec ! videoconvert ! appsink";
auto cap = new cv::VideoCapture(path, cv::CAP_GSTREAMER);
std::cout << "Hello World!\n";
}
This is my vcpkg manifest
{
"$schema": "https://raw.githubusercontent.com/microsoft/vcpkg/master/scripts/vcpkg.schema.json",
"name": "opencvtest",
"version": "0.0.1",
"dependencies": [
{
"name": "opencv",
"default-features": true,
"features": [ "gstreamer" ]
},
{
"name": "gstreamer",
"default-features": true,
"features": [ "plugins-good","plugins-base","plugins-ugly","x264" ]
}
]
}
I can build the program just fine but when run, it complains about not finding the rtspsrc element.
[ WARN:0#0.014] global H:\vcpkg\buildtrees\opencv4\src\4.5.5-923325adf5.clean\modules\videoio\src\cap_gstreamer.cpp (1127) cv::GStreamerCapture::open OpenCV | GStreamer warning: Error opening bin: no element "rtspsrc"
[ WARN:0#0.014] global H:\vcpkg\buildtrees\opencv4\src\4.5.5-923325adf5.clean\modules\videoio\src\cap_gstreamer.cpp (862) cv::GStreamerCapture::isPipelinePlaying OpenCV | GStreamer warning: GStreamer: pipeline have not been created
This seems reasonable since the build output directory doesn't seem to have all the seemingly necessary gstreamer dll's present, such as gstrtsp*.dll.
How can I get vcpkg to include all the necessary gstreamer dlls into my build output directory? What is the correct way to use OpenCV/gstreamer with vcpkg?
The vcpkg port of gstreamer does not build the rtsp plugin (which includes the rtspsrc element) by default.
You will need to edit the portfile.cmake.
Doing this in a production environment requires you to create your own vcpkg repository, where you can adjust the portfile.cmake and thus the build options how ever you want.
If this is something you will need to do I can describe this in more detail.
Short version:
add -Dgst-plugins-good:rtsp=enabled to the vcpkg_configure_meson build step described in the portfile.cmake of gstreamer.
I am trying to install the ROS-Velodyne drivers(https://github.com/ros-drivers/velodyne) in windows to capture the point cloud from velodyne LiDAR but getting error while running catkin_make.
Since these drivers require pcap library, i installed WinPcap in my system and updated the cmake of velodyne driver to find the required headers and link the library.
But on running the cmake, i am getting error on "target_link_libraries" (image shown)
Cannot specify link libraries for target "velodyne_driver" which is not
built by this project
Following is the cmake file of velodyne_driver package:
cmake_minimum_required(VERSION 2.8.3)
project(velodyne_driver)
# Set minimum C++ standard to C++11
if (NOT "${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT}")
message(STATUS "Changing CXX_STANDARD from C++98 to C++11")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif ("${CMAKE_CXX_STANDARD_COMPUTED_DEFAULT}" STREQUAL "98")
message(STATUS "Changing CXX_STANDARD from C++98 to C++11")
set(CMAKE_CXX_STANDARD 11)
endif()
set(${PROJECT_NAME}_CATKIN_DEPS
diagnostic_updater
dynamic_reconfigure
nodelet
roscpp
tf
velodyne_msgs)
find_package(catkin REQUIRED COMPONENTS ${${PROJECT_NAME}_CATKIN_DEPS} roslint)
# This driver uses Boost threads
find_package(Boost REQUIRED COMPONENTS thread)
# kinger: libpcap provides no pkg-config or find_package module:
#message (STATUS "****** Starting PCAP Search in folder: ********")
set( PCAP_DIR "C:/workspace/WpdPack" )
#message (STATUS ${PCAP_DIR})
#kinger: Include file FindPCAP.cmake
include(FindPCAP.cmake)
#find_package( PCAP REQUIRED )
message (STATUS "******* FIND PCAP TASK FINISHED **********")
message (STATUS ${PCAP_FOUND})
message (STATUS ${PCAP_INCLUDE_DIRS})
message (STATUS ${PCAP_LIBRARY_DIRS})
message (STATUS ${PCAP_LIBRARIES})
#set(libpcap_LIBRARIES -lpcap)
if(PCAP_FOUND)
# Include Directories
include_directories( ${PCAP_INCLUDE_DIRS} )
# Library Directories (Option)
link_directories( ${PCAP_LIBRARY_DIRS} )
# Dependencies
target_link_libraries( ${PROJECT_NAME} ${PCAP_LIBRARIES} )
endif()
include_directories(include ${Boost_INCLUDE_DIR} ${catkin_INCLUDE_DIRS})
# Generate dynamic_reconfigure server
generate_dynamic_reconfigure_options(cfg/VelodyneNode.cfg)
# objects needed by other ROS packages that depend on this one
catkin_package(CATKIN_DEPENDS ${${PROJECT_NAME}_CATKIN_DEPS}
INCLUDE_DIRS include
LIBRARIES velodyne_input)
# compile the driver and input library
add_subdirectory(src/lib)
add_subdirectory(src/driver)
install(DIRECTORY include/${PROJECT_NAME}/
DESTINATION ${CATKIN_PACKAGE_INCLUDE_DESTINATION})
install(FILES nodelet_velodyne.xml
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION})
install(DIRECTORY launch/
DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch)
install(PROGRAMS src/vdump
DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})
roslint_cpp()
if (CATKIN_ENABLE_TESTING)
# these dependencies are only needed for unit testing
find_package(roslaunch REQUIRED)
find_package(rostest REQUIRED)
# Download packet capture (PCAP) files containing test data.
# Store them in devel-space, so rostest can easily find them.
catkin_download_test_data(
${PROJECT_NAME}_tests_class.pcap
http://download.ros.org/data/velodyne/class.pcap
DESTINATION ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_SHARE_DESTINATION}/tests
MD5 65808d25772101358a3719b451b3d015)
catkin_download_test_data(
${PROJECT_NAME}_tests_32e.pcap
http://download.ros.org/data/velodyne/32e.pcap
DESTINATION ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_SHARE_DESTINATION}/tests
MD5 e41d02aac34f0967c03a5597e1d554a9)
catkin_download_test_data(
${PROJECT_NAME}_tests_vlp16.pcap
http://download.ros.org/data/velodyne/vlp16.pcap
DESTINATION ${CATKIN_DEVEL_PREFIX}/${CATKIN_PACKAGE_SHARE_DESTINATION}/tests
MD5 f45c2bb1d7ee358274e423ea3b66fd73)
# unit tests
add_rostest(tests/pcap_node_hertz.test)
add_rostest(tests/pcap_nodelet_hertz.test)
add_rostest(tests/pcap_32e_node_hertz.test)
add_rostest(tests/pcap_32e_nodelet_hertz.test)
add_rostest(tests/pcap_vlp16_node_hertz.test)
add_rostest(tests/pcap_vlp16_nodelet_hertz.test)
# parse check all the launch/*.launch files
roslaunch_add_file_check(launch)
# unit test
catkin_add_gtest(time_test tests/timeconversiontest.cpp)
target_link_libraries(time_test
${catkin_LIBRARIES}
${Boost_LIBRARIES}
${PCAP_LIBRARIES})
endif (CATKIN_ENABLE_TESTING)
UPDATE: Resolved the above issue. It was related to target_link_libraries where we need to provide the "target" and not the "project". I updated the cmake by adding this line:
set(libpcap_LIBRARIES ${PCAP_LIBRARIES})
Now, the build fails at 59% with following error:
C:\opt\ros\noetic\x64\include\diagnostic_updater/update_functions.h(188): error C2589: 'constant': illegal token on right side of '::'
Looks like this is an open issue: https://github.com/ms-iot/ROSOnWindows/issues/280
I'm happy to see that you are using ROS on Windows! I'd love to know more about your project.
We (Azure Edge Robotics, who maintain ROS on Windows) don't currently have a Velodyne lidar, so have not attempted to port it.
It looks like the Velodyne Lidar ROS node has not been enabled on Windows. It looks like there are several linux specific commands in the cmake file which need windows equivalents.
We have a porting guide for Windows here - https://ms-iot.github.io/ROSOnWindows/GettingStarted/PortingANode.html
It there is a winpcap vcpkg which can be leveraged in the port:
https://github.com/microsoft/vcpkg/tree/master/ports/winpcap
I've created this on the ROSonWindows github to track:
Catkin_make on the velodyne drivers fails in the windows 10 environemnt
I am trying to create a Windows installer using CPACK and NSIS. I am using Windows 10, CMake GUI, NSIS, and Visual Studio Community Edition.
It works great except that I can't find the options so that the default install location will be:
C:\package-version.patch (e.g. C:\apbs-3.0)
The apbs software is a collaboration effort and is cross platform but it does not like "spaces" in pathnames so the default location for NSIS on Windows 10 x64 is:
C:\Program Files\package version (e.g. C:\Program Files\apbs 3.0\)
The closest I have gotten to is:
C:\\apbs 3.0
using the following configuration:
string(TOLOWER ${PROJECT_NAME} PACKAGE_NAME)
set(CPACK_PACKAGE_NAME "${PACKAGE_NAME}")
set(CPACK_PACKAGE_DESCRIPTION "${PACKAGE_DESC}")
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/../LICENSE.md")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md")
set(CPACK_PACKAGING_INSTALL_PREFIX "${PACKAGE_NAME}")
set(CPACK_PACKAGE_VERSION "${APBS_VERSION}")
set(CPACK_PACKAGE_VERSION_PATCH "0")
set(CPACK_PACKAGE_VENDOR "${VENDOR}")
set(CPACK_PACKAGE_CONTACT "${CONTACT}")
set(CPACK_PACKAGE_FILE_NAME "${PACKAGE_NAME}-${APBS_VERSION}")
set(CPACK_STRIP_FILES ON)
if(WIN32)
# From: https://martinrotter.github.io/it-programming/2014/05/09/integrating-nsis-cmake/
list(APPEND CPACK_GENERATOR "NSIS")
set(CPACK_PACKAGING_INSTALL_PREFIX "\\\\${PACKAGE_NAME}-${APBS_VERSION}")
set(CPACK_NSIS_INSTALL_ROOT "C:\\\\")
endif()
include (CPack)
Is there a magic/undocumented set of CPACK variables to eliminate the extra '\' and replace the "space" with a '-' so that I can get the default install to be?
C:\apbs-3.0\
The following got me the install directory, C:\APBS-3.0.0
set(CMAKE_MAJOR_VERSION "3")
set(CMAKE_MINOR_VERSION "0")
set(CMAKE_MICRO_VERSION "0")
set(PACKAGE_NAME "${PROJECT_NAME}")
set(CPACK_PACKAGE_NAME "${PACKAGE_NAME}")
set(CPACK_PACKAGE_DESCRIPTION "APBS - Adaptive Poisson Boltzmann Solver")
set(CPACK_RESOURCE_FILE_LICENSE "${PROJECT_SOURCE_DIR}/../LICENSE.md")
set(CPACK_PACKAGE_DESCRIPTION_FILE "${PROJECT_SOURCE_DIR}/README.md")
set(CPACK_SOURCE_IGNORE_FILES "${PROJECT_BINARY_DIR};/.git/;.gitignore")
set(CPACK_PACKAGE_VERSION_MAJOR "${CMAKE_MAJOR_VERSION}")
set(CPACK_PACKAGE_VERSION_MINOR "${CMAKE_MINOR_VERSION}")
set(CPACK_PACKAGE_VERSION_PATCH "${CMAKE_MICRO_VERSION}")
set(CPACK_PACKAGE_VENDOR "PNNL")
set(CPACK_PACKAGE_CONTACT "APBS - https://github.com/Electrostatics/apbs-pdb2pqr")
set(CPACK_PACKAGE_FILE_NAME "${PACKAGE_NAME}-${APBS_VERSION}")
set(CPACK_STRIP_FILES ON)
if(WIN32)
# From: https://martinrotter.github.io/it-programming/2014/05/09/integrating-nsis-cmake/
SET(CPACK_NSIS_PACKAGE_NAME "${PACKAGE_NAME}-${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_MICRO_VERSION}")
SET(CPACK_NSIS_DISPLAY_NAME "${PACKAGE_NAME}-${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_MICRO_VERSION}")
SET(CPACK_PACKAGE_INSTALL_DIRECTORY "${PACKAGE_NAME}-${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_MICRO_VERSION}")
SET(CPACK_NSIS_INSTALL_ROOT "C:")
set(CPACK_PACKAGE_INSTALL_REGISTRY_KEY "${PACKAGE_NAME}-${MAJOR_VERSION}.${MINOR_VERSION}.${MICRO_VERSION}")
list(APPEND CPACK_GENERATOR "NSIS")
endif()
Hopefully this can help others looking for similar solutions.
I have a problem with setting up a visibility of my shared library. I would like to ask for help in resolving my issue as described below:
I have a bunch of source files which I would like to build as shared library:
+Base
|_Parameter
| |_Parameter.h
| |_Parameter_Exception.h
| |_Parameter_Exception.cpp
|_Data
| |_DataInput.h
| |_DataInput_Exception.h
| |_DataInput_Exception.cpp
...
Well there are some more files in there but I think it does not influence my problem description.
I am using CMake in order to build this SHARED library. Here is part of my CMakeLists.txt which deals with building the library.
project( Base )
cmake_minimum_required(VERSION 3.5
set( Base_HEADERS
Parameter/Parameter.h
Parameter/Parameter_Exception.h
Data/DataInput.h
Data/DataInput_Exception.h
)
set( Base_SOURCES
Parameter/Parameter_Exception.cpp
Data/DataInput_Exception.cpp
)
set( LIBRARY_OUTPUT_PATH ${CMAKE_RUNTIME_OUTPUT_DIRECTORY} )
add_library( Base SHARED ${Base_SOURCES} ${Base_HEADERS} )
generate_export_header( ${PROJECT_NAME} EXPORT_FILE_NAME ${PROJECT_NAME}_Export.h )
This setup builds libBase.so shared library without any problem. It is important to mention that I have set some visibility related flags to be used during linking:
set( CMAKE_SHARED_LINKER_FLAGS "-Wl,--no-undefined -fvisibility=hidden -fvisibility-inlines-hidden" )
As configured in Base library CMakeLists.txt partly listed above:
Base_Export.h header containig GCC visibility attributes macros is
generated by CMake. It is then included in my sources listed in the
tree up there.
By default all the symbols shall be hidden as set in
linker flags (-fvisibility=hidden)
For example a piece of Parameter_Exception.h:
#include "Base_Export.h"
class SomeException : public std::exception
{
public:
SomeException( void ) {}
...
};
Please notice I have not set any visibility attribute here (by a macro defined in Base_Export). So I would assume, the symbol of SomeException class shall be hidden to all the DSO "users" (due to -fvisibility=hidden)
But it doesn't seem so. Unfortunately:
Once I use the library, it the exception is usable although the symbol should be hidden. I would expect link failure cause by this code snippet "outside the library":
#include "Parameter/Parameter_Exception.h"
...
try
{
...
}
/* THIS SHOULD FAIL IN LINKING DUE TO UNDEFINED SYMBOL, RIGHT? */
catch( const SomeException & e )
{
...
}
I have also tried to look for the symbol in the libBase.so using the command:
readelf -Ws libBase.so
it lists enormously long text:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 000000000008b7e0 0 SECTION LOCAL DEFAULT 9
....
but what I have noticed here is that in "Vis" column up there there is always DEFAULT which implies a default visibility ( __attribute__((visibility("default"))) ) to me BUT I would expect to see HIDDEN in there ( __attribute__((visibility("hidden"))) )
So what am I doing wrong? Or my understanding is not correct? I know all the linked flags are propagated correctly but seem to have no effect.
My toolchain configuration as listed by CMake configuration script (GCC version that supports visibility attributes):
...
-- The CXX compiler identification is GNU 5.3.1
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
...
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_VISIBILITY - Success
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY
-- Performing Test COMPILER_HAS_HIDDEN_INLINE_VISIBILITY - Success
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR
-- Performing Test COMPILER_HAS_DEPRECATED_ATTR - Success
-- Configuring done
-- Generating done
Many thanks in advance to anybody willing to help me and possibly others having the same trouble as I do.
Thanks again, Martin
CMake has direct support for symbol visibility handling, so you shouldn't need to touch CMAKE_SHARED_LINKER_FLAGS or CMAKE_CXX_FLAGS at all. You can set the visibility on a per-target basis like this:
set_target_properties(Base PROPERTIES
C_VISIBILITY_PRESET hidden
CXX_VISIBILITY_PRESET hidden
VISIBILITY_INLINES_HIDDEN YES
)
CMake will then ensure the relevant flags are added for you. Rather than having to set these properties for each target, it is usually more convenient to set the associated variables to set the defaults for all subsequently created targets (and this is what I generally recommend and use in projects I work on):
cmake_minimum_required(VERSION 3.5)
project(Base)
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_CXX_VISIBILITY_PRESET hidden)
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
add_library(Base SHARED ...)
When used in conjunction with the GenerateExportHeader module (which you already appear to be using), you get support not just for gcc/clang, but also Visual Studio, making it a nice cross-platform way of controlling symbol visibility. You don't need to know the relevant compiler flags or attributes, CMake will handle them for you and give you equivalent behavior across all the compilers.
-fvisibility=hidden and -fvisibility-inlines-hidden are compiler options,
not linker options. Set them in CMAKE_CXX_FLAGS