2

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.

1 Answers1

1

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.

DevSolar
  • 67,862
  • 21
  • 134
  • 209
  • I found a "hacky way" which seems to be working -for now-. That is, defining the paths above by using set command as : `set(ACTIVEMQ_CPP "/usr/local/lib/libactivemq-cpp.so")` and `set(ACTIVEMQ_INCLUDE_DIR "/usr/local/include/activemq-cpp-3.8.4/")` and then referring to them in linking section. –  Sep 21 '15 at 13:47
  • 1
    @frageDE: I won't go so far as calling that a misuse of CMake; clearly you want this to work only in your very specific environment. But be aware that you're abandoning all the things that make CMake superior to Make. I am a bit surprised; in the question, you used non-standard paths for the ActiveMQ components. In your comment, it is installed system-wide. In this case, *do* have a look at my modules I linked in the answer, and feel free to adapt them to a `FindActiveMQ.cmake` module of your own, because that *will* work cleanly with just a minor touch for the `include` subdir. – DevSolar Sep 21 '15 at 14:44