【发布时间】:2021-09-25 13:23:26
【问题描述】:
我正在尝试启动一个 ROS 项目,但收到一个非常奇怪的错误:‘boost::placeholders’ has not been declared。
我有以下设置:
-
Ubuntu 20.04 -
ROS
Noetic -
Boost 1.71 -
CMake->cmake version 3.16.3
下面是我在终端中收到的错误示例:
In file included from /opt/ros/noetic/include/ros/node_handle.h:34,
from /opt/ros/noetic/include/ros/ros.h:45,
/opt/ros/noetic/include/ros/publisher.h: In member function ‘boost::function<void(const boost::shared_ptr<ros::SubscriberLink>&)> ros::Publisher::getLastMessageCallback()’:
/opt/ros/noetic/include/ros/publisher.h:179:70: error: ‘boost::placeholders’ has not been declared
179 | return boost::bind(&Impl::pushLastMessage, impl_.get(), boost::placeholders::_1);
下面似乎带有这个错误的文件报错:
template<class M, class T>
Subscriber subscribe(const std::string& topic, uint32_t queue_size, void(T::*fp)(M), T* obj,
const TransportHints& transport_hints = TransportHints())
{
SubscribeOptions ops;
ops.template initByFullCallbackType<M>(topic, queue_size, boost::bind(fp, obj, boost::placeholders::_1));
ops.transport_hints = transport_hints;
return subscribe(ops);
}
在this source 之后,我可以确认我添加了C++14:
cmake_minimum_required(VERSION 2.8.3)
project(lidar_boat_detection)
set(CMAKE_BUILD_TYPE Debug)
add_compile_options(-std=c++14 -g)
find_package(PCL 1.8 REQUIRED)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS})
add_definitions(${PCL_DEFINITIONS})
find_package(Boost REQUIRED COMPONENTS
system
filesystem
date_time
thread
)
find_package(catkin REQUIRED COMPONENTS
roscpp
pcl_conversions
pcl_ros
std_msgs
message_generation
)
我还咨询了this source,并根据新指令添加了#include <boost/bind/bind.hpp>,而不是#include <boost/bind.hpp>,并添加了using namespace boost::placeholders;。然而,这些解决方案都不起作用,我尝试的另一件事是添加 #include <boost/bind/placeholders.hpp>,但这也不起作用:
#ifndef ROSCPP_PUBLISHER_HANDLE_H
#define ROSCPP_PUBLISHER_HANDLE_H
#include "ros/forwards.h"
#include "ros/common.h"
#include "ros/message.h"
#include "ros/serialization.h"
//#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/thread/mutex.hpp>
using namespace boost::placeholders;
namespace ros
{
class NodeHandleBackingCollection;
....
}
总是从same post 我尝试在文件开头添加以下行#define BOOST_BIND_NO_PLACEHOLDERS,但这也没有用:
#ifndef ROSCPP_PUBLISHER_HANDLE_H
#define ROSCPP_PUBLISHER_HANDLE_H
#define BOOST_BIND_NO_PLACEHOLDERS
#include "ros/forwards.h"
#include "ros/common.h"
#include "ros/message.h"
#include "ros/serialization.h"
//#include <boost/bind.hpp>
#include <boost/bind/bind.hpp>
#include <boost/thread/mutex.hpp>
using namespace boost::placeholders;
namespace ros
{
class NodeHandleBackingCollection;
....
}
我挖了更多,遇到了this post,但不幸的是并没有解决问题。
This question 会很有用,因为这与我遇到的问题非常接近。
编辑
Creating Package: template_package_msgs
-- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy
CMake Error at /usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake:117 (find_package):
Could not find a package configuration file provided by "boost_bind"
(requested version 1.71.0) with any of the following names:
boost_bindConfig.cmake
boost_bind-config.cmake
Add the installation prefix of "boost_bind" to CMAKE_PREFIX_PATH or set
"boost_bind_DIR" to a directory containing one of the above files. If
"boost_bind" provides a separate development package or SDK, be sure it has
been installed.
Call Stack (most recent call first):
/usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake:182 (boost_find_component)
/usr/share/cmake-3.16/Modules/FindBoost.cmake:443 (find_package)
template_package/template_package_msgs/CMakeLists.txt:9 (find_package)
-- Configuring incomplete, errors occurred!
See also "/home/emanuele/sonar_ws/build/CMakeFiles/CMakeOutput.log".
See also "/home/emanuele/sonar_ws/build/CMakeFiles/CMakeError.log"
我对如何解决它的想法已经不多了。感谢您指出解决此问题的正确方向。
【问题讨论】:
-
我不认为对 ROS 库代码进行更改是一个好主意,但您能否将代码恢复为初始形式,然后 将
boost::placeholders::_1替换为_1。您也可以尝试再次恢复您的更改并将add_definitions(-DBOOST_BIND_NO_PLACEHOLDERS)添加到您的CMakeLists.txt文件,而不是将其添加到 ROS 标头本身。这样,您可以确保在包含任何其他 Boost 标头之前绝对尊重它。 -
#include <boost/bind.hpp对于 Boost 1.71 应该是正确的。它处理预处理器定义,例如BOOST_BIND_NO_PLACEHOLDERS。您可以通过打开usr/include/boost来检查是否是这种情况,并检查bind.hpp是否存在以及文件的内容是什么。 -
我 101% 同意您不修改 ROS 库代码!但是我是最后的手段,因为我尝试了所有我可能认为没问题的方法。例如,昨天我卸载/重新安装了 ROS 三次,卸载了
boost的每个实例,今天我只重新安装了 ROSNoetic(因为它带有正确版本的boost 1.71)我用 @987654356 检查了这个@ 安装后立即Noetic;仔细检查我也做了ldconfig -p | grep libboost) -
为了确保我在安装
Noetic之前删除了boost的任何实例,我什至做了sudo apt autopurge $(dpkg -l | grep boost | grep 1.71 | awk '{print $2}')。最后,我尝试了您对add_definitions(-DBOOST_BIND_NO_PLACEHOLDERS)的所有正确CMakeLists.txt文件的建议,但没有任何改变。 -
我去检查了
usr/include/boost,可以确认bind.hpp在那里。对我来说最后要尝试的是艰难的方法:将boost::placeholders::_1替换为_1。我不太喜欢这样做,因为修改 ROS 库代码并不好。但我真的不知道出了什么问题......