How to import zeromq libraries in cmake?

匿名 (未验证) 提交于 2019-12-03 03:08:02

问题:

I'm just starting to learn how to work with zeromq libraries and using them in different C++ projects. The sample code that I wrote (actually copied from there tutorials)is this:

//  file: main.cpp //  Hello World client in C++ //  Connects REQ socket to tcp://localhost:5555 //  Sends "Hello" to server, expects "World" back // #include <zmq.hpp> #include <string> #include <iostream>  int main () {     //  Prepare our context and socket     zmq::context_t context (1);     zmq::socket_t socket (context, ZMQ_REQ);      std::cout << "Connecting to hello world server…" << std::endl;     socket.connect ("tcp://localhost:5555");      //  Do 10 requests, waiting each time for a response     for (int request_nbr = 0; request_nbr != 10; request_nbr++) {         zmq::message_t request (5);         memcpy (request.data (), "Hello", 5);         std::cout << "Sending Hello " << request_nbr << "…" << std::endl;         socket.send (request);          //  Get the reply.         zmq::message_t reply;         socket.recv (&reply);         std::cout << "Received World " << request_nbr << std::endl;     }     return 0; } 

and by building the output of this file with the command below:

g++ main.cpp -o test -lzmq 

the file will be generated with no problem.

The problem that I have is that I want to build the file using CMake.Thus, I've written a CMakeLists.txt file as below:

cmake_minimum_required(VERSION 3.6) project(test2)   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -lzmq")   set(SOURCE_FILES main.cpp) add_executable(test2 ${SOURCE_FILES}) 

The part that I thought will be enough to build the program is -lzmq but even with that piece included, I get the following error messages:

CMakeFiles/test2.dir/main.cpp.o: In function `zmq::error_t::error_t()': /usr/include/zmq.hpp:62: undefined reference to `zmq_errno' CMakeFiles/test2.dir/main.cpp.o: In function `zmq::error_t::what() const': /usr/include/zmq.hpp:66: undefined reference to `zmq_strerror' CMakeFiles/test2.dir/main.cpp.o: In function `zmq::message_t::message_t()': /usr/include/zmq.hpp:107: undefined reference to `zmq_msg_init' CMakeFiles/test2.dir/main.cpp.o: In function `zmq::message_t::message_t(unsigned long)': /usr/include/zmq.hpp:114: undefined reference to `zmq_msg_init_size' CMakeFiles/test2.dir/main.cpp.o: In function `zmq::message_t::~message_t()': /usr/include/zmq.hpp:129: undefined reference to `zmq_msg_close' CMakeFiles/test2.dir/main.cpp.o: In function `zmq::message_t::data()': /usr/include/zmq.hpp:180: undefined reference to `zmq_msg_data' CMakeFiles/test2.dir/main.cpp.o: In function `zmq::context_t::context_t(int)': /usr/include/zmq.hpp:204: undefined reference to `zmq_init' CMakeFiles/test2.dir/main.cpp.o: In function `zmq::context_t::~context_t()': /usr/include/zmq.hpp:225: undefined reference to `zmq_term' CMakeFiles/test2.dir/main.cpp.o: In function `zmq::socket_t::socket_t(zmq::context_t&, int)': /usr/include/zmq.hpp:251: undefined reference to `zmq_socket' CMakeFiles/test2.dir/main.cpp.o: In function `zmq::socket_t::close()': /usr/include/zmq.hpp:283: undefined reference to `zmq_close' CMakeFiles/test2.dir/main.cpp.o: In function `zmq::socket_t::connect(char const*)': /usr/include/zmq.hpp:314: undefined reference to `zmq_connect' CMakeFiles/test2.dir/main.cpp.o: In function `zmq::socket_t::send(zmq::message_t&, int)': /usr/include/zmq.hpp:321: undefined reference to `zmq_send' /usr/include/zmq.hpp:324: undefined reference to `zmq_errno' CMakeFiles/test2.dir/main.cpp.o: In function `zmq::socket_t::recv(zmq::message_t*, int)': /usr/include/zmq.hpp:331: undefined reference to `zmq_recv' /usr/include/zmq.hpp:334: undefined reference to `zmq_errno' 

Should I set another kind of variable in the CMake file or have I installed the library in a wrong directory? or is there anything else that I should have mentioned? and The system witch I'm working on is Ubuntu 14.04

回答1:

CMake doesn't include direct support for 0mq and 0mq doesn't include direct support for CMake. But, 0mq does support pkg-config and we can use this to help us. Since you mentioned that you're on Ubuntu 14.04, make sure you've done sudo apt-get install libzmq3-dev to install the 0mq libraries, headers, and the pkg-config .pc file.

Then use the following CMakeLists.txt which I've modified from your version above. (I've commented all my changes inline.)

## i have cmake 3.5 cmake_minimum_required(VERSION 3.5) project(test2)  ## use this to globally use C++11 with in our project set(CMAKE_CXX_STANDARD 11)  ## load in pkg-config support find_package(PkgConfig) ## use pkg-config to get hints for 0mq locations pkg_check_modules(PC_ZeroMQ QUIET zmq)  ## use the hint from above to find where 'zmq.hpp' is located find_path(ZeroMQ_INCLUDE_DIR         NAMES zmq.hpp         PATHS ${PC_ZeroMQ_INCLUDE_DIRS}         )  ## use the hint from about to find the location of libzmq find_library(ZeroMQ_LIBRARY         NAMES zmq         PATHS ${PC_ZeroMQ_LIBRARY_DIRS}         )  set(SOURCE_FILES main.cpp) add_executable(test2 ${SOURCE_FILES})  ## add the include directory to our compile directives target_include_directories(test2 PUBLIC ${ZeroMQ_INCLUDE_DIR}) ## at the 0mq library to our link directive target_link_libraries(test2 PUBLIC ${ZeroMQ_LIBRARY}) 

Now you can make your project.

If you want to see what's happening under the hood, do a verbose make.

If you look at the compile line, you'll notice that

  1. C++11 support was added (with the -std=gnu++11 flag)
  2. There's no -I/path/to/zmq flag. That's because Ubuntu dumps zmq.hpp in to /usr/include and CMake is smart enough to know that is a default path, so it does nothing

If you look at the link line, you'll notice that libzmq.so has been included via it's full path. Some people don't like that (myself included) and prefer -L/lib/dir -lmylib instead. Using the full path is "the CMake way", and you'll actually come to appreciate it as you grow with CMake and use it for larger and more complicated projects (you still might not like it though.)

Also note, that since you're on Ubuntu we could have cheated and used dpkg -L libzmq3-dev to find the locations of the files we're interested in then added them to your original CMAKE_CXX_FLAGS line, but that's cheating and more importantly, not portable.



回答2:

A cmake config file has been added to libzmq github repository recently here.

This is not included in the latest release (4.2.1) yet, but I belive it should be in the next release.

I have installed the head version using cmake and then installed cppzmq, which uses find_package(ZeroMQ REQUIRED) to locate libzmq. All worked like a charm.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!