I have a project in which I want to use activemq producer, for this reason I would like to add activemq libraries in my CMakeLists.txt.
Previously, I was using MakeFile and I had the following code:
APR_INCLUDE=/usr/include/apr-1
CMS_HOME=$(HOME)/Tools/activemq-cpp-library-3.8.4
LD_LIBRARY_PATH:=/libs
obstacleDetection_cpp: src/obstacleDetection.cpp protoc_middleman
g++ -I $(APR_INCLUDE) -I $(CMS_HOME)/src/main -g -o src/obstacleDetection.o -c src/obstacleDetection.cpp
cd libs && cp $(CMS_HOME)/src/main/.libs/libactivemq-cpp.so.18.0.4 . && ln -sf libactivemq-cpp.so.18.0.4 libactivemq-cpp.so.18
g++ -L $(CMS_HOME)/src/main/.libs/ -g -o bin/obstacleDetection src/obstacleDetection.o src-gen/VisionData.pb.cc src-gen/VisionData.pb.h -lactivemq-cpp -lssl -L/usr/local/lib -lprotobuf -pthread
@echo "Success."
Where I set the library paths to variables and refer to them in the linking process.
However, with CMakeLists, it is not that straightforward. I have the following section in my CMakeLists however it does not work:
include_directories(
${catkin_INCLUDE_DIRS}
${OpenCV_INCLUDE_DIRS}
${PROTOBUF_INCLUDE_DIRS}
${CMAKE_CURRENT_BINARY_DIR}
include
~/Tools/activemq-cpp-3.8.4
/usr/include/apr-1
)
target_link_libraries(cameraSubscriber
${catkin_LIBRARIES}
${OpenCV_LIBRARIES}
${PROTOBUF_LIBRARIES}
filters
/usr/local/lib/libactivemq-cpp.a
/usr/lib/libapr-1.a
)
And I get the following error:
fatal error: activemq/library/ActiveMQCPP.h: No such file or directory
compilation terminated.
Does anyone know how to use activemq with CMakeLists? Or anyone knows how to convert Makefile commands into CMakeLists commands? Actually I think the problem is that I am unable to link the library, the absolute path there does not look okay for CMake style, I mean, I am almost sure it is not the way to give the path like that.
CMake is very straightforward if used correctly. Hardcoding local paths in your CMakeLists.txt is somewhat defeating the purpose of CMake though, which is to have a portable configuration. I also suspect that CMake is failing to evaluate ~
correctly in this context.
The "right" thing to do would be to write a FindActiveMQ.cmake
module, and parameterize it on the command line with -DCMAKE_PREFIX_PATH=${HOME}/Tools/activemq-cpp-library-3.8.4
, but I fear instructions for how to write a Find Module would go beyond the scope of a SO answer. Check the documentation for that, if you think you are up for the task.
I would point you to my own CMake framework, more specifically the package helper wrapping the technicalities of Find Module syntax, but I am afraid it assumes a standard layout (with include files in .../include
and library files in .../lib
), which your ActiveMQ installation does not seem to have.
The "hacky" way, if you don't care that much for portability or reusability, is to use find_path()
and find_library()
directly in your CMakeLists.txt
:
find_path( ActiveMQ_INCLUDE_DIR
NAMES ActiveMQCPP.h
HINTS $ENV{HOME}/Tools/activemq-cpp-3.8.4/
PATH_SUFFIXES activemq/library
DOC "ActiveMQ include files" )
find_library( ActiveMQ_LIBRARY
NAMES activemq-cpp
HINTS $ENV{HOME}/Tools/activemq-cpp-3.8.4/
DOC "ActiveMQ library" )
You should then add some checking along the lines of:
if ( ActiveMQ_INCLUDE_DIR AND ActiveMQ_LIBRARY )
include_directories( ${ActiveMQ_INCLUDE_DIR} )
target_link_libraries( cameraSubscriber ${ActiveMQ_LIBRARY} )
else()
message( FATAL_ERROR "..." )
endif()
That is untested; it's basically a paraphrasing of what I wrote in the package helper mentioned above. You might have to tweak it a bit if it doesn't work as-is.