cmakeactivemq-classicactivemq-cpp

ActiveMQ CMS with CMakeLists


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.


Solution

  • 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.