‘boost::placeholders’ has not been declared : boost::placeholders::_1 - c++

I am trying to launch a ROS project but I receive a very strange error: ‘boost::placeholders’ has not been declared.
I have the following settings:
Ubuntu 20.04
ROS Noetic
Boost 1.71
CMake -> cmake version 3.16.3
Below a sample of the error I receive in the terminal:
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);
Below the file that seems to carry this error is reported:
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);
}
Following this source I can confirm I added 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
)
Also I consulted this source and I added #include <boost/bind/bind.hpp> instead of #include <boost/bind.hpp> as per new directive and I added using namespace boost::placeholders;. However non of these solutions worked and another thing I tried was to add #include <boost/bind/placeholders.hpp> and that also didn't work:
#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;
....
}
Always from the same post I tried to add the following line #define BOOST_BIND_NO_PLACEHOLDERS at the beginning of the file but that also didn't work:
#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;
....
}
I dug more and come across this post but unfortunately it was not useful to solve the problem.
This question would have been useful is a proper answer would have been provided as this is extremely close to the problem I have.
EDITS
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"
I am running out of ideas on how to solve it. Thanks for pointing in the right direction for solving this issue.

There was a recent improvement to Boost Bind, see Why boost::bind insists pulling `boost::placeholders` into global namespace?
It looks like you want to define BOOST_BIND_GLOBAL_PLACEHOLDERS unless you want to update the calling code. Check that BOOST_BIND_NO_PLACEHOLDERS is not defined

I have trouble replicating your exact problem on my system. If I clone your minimal example from your Bitbucket but leave the line add_definitions(-DBOOST_BIND_NO_PLACEHOLDERS) in the CMakeLists.txt then it gives me the same error you got but if I remove it I do not have these issues and it compiles fine. If this error persists on your system even though you remove this line, the only plausible reason that I can come up with is that for some obscure reason some other package in your workspace or ROS itself adds this definition which makes the compilation of your package then fail. I would actually try to make a new workspace (or put CATKIN_IGNORE files into the other packages in your workspace and then $ catkin clean the workspace followed by $ catkin build) and see if it still occurs with your Bitbucket code as the only package in your workspace. If it compiles keep adding the packages until you find out which of your other packages might be causing it. If it does not then the only way of solving this dilemma that comes to my mind is adding the line
#undef BOOST_BIND_NO_PLACEHOLDERS
to the top of your two .cpp files talker.cpp and subscriber.cpp (before actually including ros/ros.h). This might though lead to problems when combining it with code that relies on BOOST_BIND_NO_PLACEHOLDERS. In order to reduce the chances of it breaking your code do not add it to header files as then it might leak into code including your header file.

Related

Asio .hpp not found in VSCode, but is included in path

I'm trying to use asio in VSCode with C++. I keep getting the warning:
fatal error: 'asio.hpp' file not found
#include <asio.hpp>
Using the code:
#include <iostream>
#include <asio.hpp>
#include <asio/ts/buffer.hpp>
#include <asio/ts/internet.hpp>
int main(){
asio::error_code ec;
//Create a 'context which is like a platform specific interface
asio::io_context context;
//Get the address of somewhere we wish to connect to
asio::ip::tcp::endpoint endpoint(asio::ip::make_address("93.184.216.34", ec),80);
return 0;
}
In the include path UI settings, I have the following paths listed which should take care of things:
${workspaceFolder}/**
/opt/homebrew/Cellar/asio/**
/opt/homebrew/Cellar/asio/1.24.0_1/include
/opt/homebrew/Cellar/boost/**
/opt/homebrew/Cellar/boost/1.81.0/include/boost
/opt/homebrew/Cellar/boost/1.81.0/include
/Library/Developer/CommandLineTools/SDKs/MacOSX13.1.sdk/usr/include
(there are redundant paths here but I am trying everything at this point)
Finally, it should be able to find the file since the file is there:
ls /opt/homebrew/Cellar/asio/1.24.0_1/include ls /opt/homebrew/Cellar/asio/1.24.0_1/include
Gives:
/opt/homebrew/Cellar/asio/1.24.0_1/include:
asio asio.hpp
I would expect it to just find those files. I have also installed boost using brew. It is available at the boost path included.
I am using Mac M1 with Monterey 12.5.1, and VSCode Version: 1.74.2.
Thanks for the help!
The includePath element in the json file is for intelliSense and not your compiler. If you aren't using CMake you will have to go into tasks.json, there you can specify additional compiler flags.
You want to add a flag: -Ipath/to/asio.

spdlog crash on factory methods

Yesterday I have started including spdlog into a personal project of mine to use for logging. So far I have had some problems with getting library inclusion to work but those are now solved completely.
Now everything compiles just fine, with all headers found however when I try to create loggers or simply set the pattern for logging the code crashes with a segmentation fault. More specifically no matter which function I call from the spdlog namespace for the very first time in the program causes the crash.
I have a class abstracting some parts from spdlog (based on this repo) as follows:
//Logger.hpp
#ifndef TE_LOGGER_HPP
#define TE_LOGGER_HPP
#include <spdlog/spdlog.h>
namespace te {
class Logger {
public:
static void Init();
inline static std::shared_ptr<spdlog::logger> &getCoreLogger() {
return sCoreLogger;
}
inline static std::shared_ptr<spdlog::logger> &getClientLogger() {
return sClientLogger;
}
private:
static std::shared_ptr<spdlog::logger> sCoreLogger;
static std::shared_ptr<spdlog::logger> sClientLogger;
};
}
#endif //TE_LOGGER_HPP
//Logger.cpp
#include "Logger.hpp"
#include <spdlog/sinks/stdout_color_sinks.h>
std::shared_ptr<spdlog::logger> te::Logger::sCoreLogger;
std::shared_ptr<spdlog::logger> te::Logger::sClientLogger;
void te::Logger::Init() {
//The first of any of the following three lines cause a crash
//no matter the order, regardless of the pattern used in set_pattern
spdlog::set_pattern("%v");
sCoreLogger = spdlog::stdout_color_mt("CORE");
sClientLogger = spdlog::stdout_color_mt("CORE");
sCoreLogger->set_level(spdlog::level::trace);
sClientLogger->set_level(spdlog::level::trace);
}
From the stack traces it seems that the issue is with the formatter class in spdlog being set null for some reason somewhere within the library. I am using the latest CLion, C++14 (I am aware that spdlog is C++11, but I need features from 14 later down the line, also setting -std=c++11 doesn't solve the issue) and the latest version of spdlog as of yesterday (pulled straight from their GitHub repo) on Ubuntu 18.04.
EDIT: As per the request in the comments I have created a small project (single cpp file, include spdlog the way I do in the real project, or the same code and library setup as in the real project referenced from the main.cpp file and linked to accordingly) that aims to reproduce the issue and here are my findings:
* The issue is not present when I use spdlog directly in the executable
* The issue is present if the Logger class is moved into a shared library and linked to from there
Here is the error message I am getting:
Process finished with exit code 139 (interrupted by signal 11: SIGSEGV)
And the CMakeLists.txt files I am using (I nest the library's one into the project since as of now CLion does not support "multiple projects in the same solution" like for example VS does):
#CMakeLists.txt for Library
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(TokenEngine VERSION 0.0.1 LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 14)
set(SOURCE_FILES src/Application.cpp src/Application.hpp src/EntryPoint.hpp src/Logger.cpp src/Logger.hpp)
#include_directories("${CMAKE_CURRENT_SOURCE_DIR}/libs/")
add_library(TokenEngine SHARED ${SOURCE_FILES})
target_include_directories(TokenEngine PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/libs/spdlog-1.x/include")
#Expose the public API of the engine to any project that might use it
target_include_directories(TokenEngine PUBLIC include)
#CMakeLists.txt for top level project
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra")
add_definitions(-DTE_PLATFORM_LINUX)
project(Build CXX)
add_subdirectory(TokenEngine)
add_subdirectory(Sandbox)
You are using the same name for both loggers, when you run it you'll get:
$ ./logger
libc++abi.dylib: terminating with uncaught exception of type spdlog::spdlog_ex: logger with name 'CORE' already exists
Abort trap: 6
If you change the name of the client logger to something else it works fine:
sCoreLogger = spdlog::stdout_color_mt("CORE");
sClientLogger = spdlog::stdout_color_mt("CLIENT");
The problem is probably that spdlog’s static objects are defined twice - from inside the shared library and from client code that includes your logger header (which incldes spdlog.h).
Try to remove the include to spdlog.h from the header file and (and use forward declaration of spdlog::logger instead), and include spdlog.h only from your Logger.cpp file.
Edit:
spdlog::logger cannot be forward declared across compilation unit boundries.
The solution is to wrap the logger with some simple class defined in logger.cpp and only export it in logger.h

Building project with ARUCO fails

I'm trying to build a project with arUco.
I am using openCV v.3.1, which apparently includes aruco. However, I get the error:
opencv2/aruco/dictionary.hpp: No such file or directory
#include "opencv2/aruco/dictionary.hpp"
^
I then downloaded arUco, built it, and tried to build the example described at the bottom of http://www.uco.es/investiga/grupos/ava/node/26 . I get the error:
fatal error: aruco/aruco.h: No such file or directory
#include <aruco/aruco.h>
^
The CMakeLists.txt used is:
cmake_minimum_required(VERSION 2.8)
project(aruco_testproject)
SET(CMAKE_MODULE_PATH ${CMAKE_INSTALL_PREFIX}/lib/cmake/ )
MESSAGE(${CMAKE_MODULE_PATH})
find_package(aruco REQUIRED )
add_executable(aruco_simple aruco_simple.cpp)
target_link_libraries(aruco_simple ${aruco_LIBS})
I've copied Findaruco.cmake to /usr/local/lib/cmake/
If anyone could help, that'd be fantastic. I've been looking for a solution for a while and I feel really stuck. Thanks a lot!
You are missing the include_directories stanza. Also I think the correct variable name suffix for the library should be _LIBRARIES, not _LIBS, but afaik, cmake is unable to enforce any rule with rogue cmake modules, so the best bet is probably to try several common suffixes. That's one of cmake's atrocities.
cmake_minimum_required(VERSION 2.8)
project(aruco_testproject)
SET(CMAKE_MODULE_PATH ${CMAKE_INSTALL_PREFIX}/lib/cmake/ )
MESSAGE(${CMAKE_MODULE_PATH})
find_package(aruco REQUIRED )
add_executable(aruco_simple aruco_simple.cpp)
include_directories(${ARUCO_INCLUDE_DIR} ${ARUCO_INCLUDE_DIRS})
target_link_libraries(aruco_simple ${ARUCO_LIBRARY} ${ARUCO_LIBRARIES})
For the header inclusion, #include <aruco/aruco.h> looks fine, but not #include "opencv2/aruco/xxx".

CLion doesn't resolve headers from external library

Some time ago I started a big header library in C++1x using XCode. The current layout of the library is () something like (partial output from ls -R sponf)
sponf/sponf:
ancestors sponf.h sponf_utilities.h
categories sponf_children.h utilities
children sponf_macros.h
sponf/sponf/ancestors:
function.h meter.h set.h simulation.h
sponf/sponf/categories:
free_space.h prng.h random_distribution.h series.h
sponf/sponf/children:
distributions histogram.h random simulations
meters numeric series spaces
sponf/sponf/children/distributions:
arcsine_der.h exponential.h
box_muller.h uniform.h
sponf/sponf/children/meters:
accumulator.h timer.h
#... other subdirs of 'children' ...
sponf/sponf/utilities:
common_math.h limits.h string_const.h
#... other directories ...
I wanted to port this project to CLion, which seems a really good IDE (based on the similar AndroidStudio IDE) but I'm getting some troubles.
Small test program
I tried this small program as a test:
#include <iostream>
#include <sponf/sponf.h>
using namespace std;
int main() {
using space = sponf::spaces::euclidean_free_space<double, 3>;
sponf::simulations::random_walk<space> rw;
rw.step(1);
std::cout << rw.position.value << std::endl;
return 0;
}
The program compiles and runs fine. However, CLion does not recognize the spaces namespace (declared in one of the children files), nor the simulations namespace; they are both marked red and I cannot inspect their content, nor navigate to their definitions by ⌘-clicking, etc. etc...
Relevant parts of the library
Looking in "sponf.h" we find
#ifndef sponf_h
#define sponf_h
/* The classes below are exported */
#pragma GCC visibility push(default)
// include some of the standard library files
// ...
#include <Eigen/Eigen>
#include "sponf_macros.h"
#include "sponf_utilities.h"
#include "sponf_children.h"
#pragma GCC visibility pop
#endif
while in "sponf_children.h" (which is located at the top level, next to "sponf.h") we find
#ifndef sponf_locp_sponf_children_h
#define sponf_locp_sponf_children_h
namespace sponf {
// include some of the children
// ...
#include "children/spaces/euclidean_free_space.h"
#include "children/simulations/random_walk.h"
// include remaining children
// ...
}
#endif
Each "child" header will then include its corresponding "ancestor" or "category" header (which defines the superclass of the "child" itself).
The reaction of CLion
Despite the autocompletition prediction, which easily finds all the subdirectories and the headers, all the include directives in this last file get marked red and ⌘-clicking on any of them leads to a popup message
Cannot find declaration to go to
while the right ribbon of the editor signal many errors like
',' or ) expected
) expected
Declarator expected
Expecting type
Missing ;
Unexpected symbol
which are not the same for each include statement (each generates from 2 to all of these errors).
On the other hand, CLion is perfectly able to find all Eigen headers, which have pretty much the same structure!
I have put both libs in /opt/local/include and changed CMakeLists.txt accordingly
cmake_minimum_required(VERSION 2.8.4)
project(sponf)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")
include_directories(/opt/local/include/sponf /opt/local/include/eigen3)
set(SOURCE_FILES main.cpp)
add_executable(sponf ${SOURCE_FILES})
Why can't CLion properly parse the project structure? XCode, after having included /opt/local/include/sponf and /opt/local/include/eigen3 in the HEADER_SEARCH_PATHS env. variable of the project, is able to find any header while compiling the same exact program.
Is there anything else I need to know? Am I doing it wrong or is it that CLion isn't that mature yet and this is just a sorry bug? This is my first approach to the CLion and the CMake toolchain, so any kind of information about it will be greatly appreciated!
Sorry for the very long question, I didn't manage to shrink it further... Thanks in advance guys, see you soon!
Here what I did in windows using cigwin64. I wanted to use Eigen library include in my project.
Eigen library is places in /usr/include/eigen then edited CMakeLists.txt and add
include_directories("/usr/include/eigen")
into it. Now CLion can find all source files in eigen lib. May be this what you wanted too.
Downgrade to Clion 2016.1.4 fixes the problem

Boost build error with websocketpp and MySQL on Windows

I am trying to build a C++ app that uses both websocketpp and MySQL. I have encountered 2 build problems using VS 2010 C++ Express.
1) A problem with the boost libraries. It produces many errors like this:
1>c:\program files (x86)\boost\boost_1_50\boost\thread\win32\thread_data.hpp(210): error C2146: syntax error : missing ')' before identifier 'rel_time'
Here's the relevant snippet from thread_data.hpp starting with line 210:
inline BOOST_SYMBOL_VISIBLE void sleep(TimeDuration const& rel_time)
{
interruptible_wait(detail::pin_to_zero(rel_time.total_milliseconds()));
}
2) A conflict with the word VERSION which is documented here and I believe is independent.
To make a clear and simple example of the boost build problems, I'm using the websocketpp example: echo_server.cpp to which I added these includes:
#include "stdafx.h"
Boost lib includes recommended by "Building a program with websocketpp" on the websocketpp site.
#include <boost/regex.hpp>
#include <boost/random.hpp>
#include <boost/system/api_config.hpp>
#include <boost/system/config.hpp>
#include <boost/system/error_code.hpp>
#include <boost/system/system_error.hpp>
#include <boost/system/windows_error.hpp>
and the MySQL header includes. Adding these 2 boostincludes triggers the build errors. If I comment out these 2 includes, it builds without errors:
#include <my_global.h>
#include <mysql.h>
Any suggestions on how to deal with the boost problems?
I don't think this is the same build problem as this one, "Trying to build websocket++ with MinGW: last few linker errors — what could it be?"
Concerning the first error, check if there are any macros interfering with the code. Right-click and go to definition or #define the macro yourself at the beginning of the file and see where it gets redefined. In really hard cases, look at the preprocessor output via a compiler flag.
Concerning the rest, you don't provide any versions for Boost and MySQL. Then, there is my_global.h (or is that part of MySQL?) and stdafx.h, which are both under your control but you don't show them here. Also, try to reduce the issue to the smallest possible piece of code. In short, provide a reproducible example.