2016-12-20 5 views
5

Я только начинаю учиться работать с библиотеками zeromq и использовать их в разных проектах на С ++. пример кода, который я написал (фактически скопирована оттуда учебники) заключается в следующем:Как импортировать библиотеки zeromq в cmake?

// 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; 
} 

и построив вывод этого файла с ниже команды:

g++ main.cpp -o test -lzmq 

файл будет создан с без проблем.

Проблема, что у меня есть, что я хочу, чтобы создать файл с помощью CMake.Thus, я написал CMakeLists.txt файл, как показано ниже:

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}) 

Та часть, я думал, что будет достаточно, чтобы построить программа -lzmq, но даже при этом часть включена, я получаю следующее сообщение об ошибке:

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' 

Должен ли я установить другой тип переменных в файле CMake или я установил библиотеку в другом каталоге? или есть что-нибудь еще, что я должен был упомянуть? и системная ведьма, над которой я работаю, - Ubuntu 14.04

ответ

12

CMake не включает прямую поддержку 0mq и 0mq не включает прямую поддержку CMake. Но 0mq поддерживает pkg-config, и мы можем использовать это, чтобы помочь нам. Поскольку вы упомянули, что находитесь на Ubuntu 14.04, убедитесь, что вы сделали sudo apt-get install libzmq3-dev, чтобы установить библиотеки 0mq, заголовки и файл pkg-config.pc.

Затем используйте следующее CMakeLists.txt, которое я изменил из вашей версии выше. (Я комментировал все мои изменения рядный.)

## 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}) 

Теперь вы можете make ваш проект.

❯ make 
[ 50%] Building CXX object CMakeFiles/test2.dir/main.cpp.o 
[100%] Linking CXX executable test2 
[100%] Built target test2 

Если вы хотите увидеть, что происходит под капотом, сделайте подробный make.

❯ make VERBOSE=1 
/usr/bin/cmake -H/home/nega/foo -B/home/nega/foo/build --check-build-system CMakeFiles/Makefile.cmake 0 
/usr/bin/cmake -E cmake_progress_start /home/nega/foo/build/CMakeFiles /home/nega/foo/build/CMakeFiles/progress.marks 
make -f CMakeFiles/Makefile2 all 
make[1]: Entering directory '/home/nega/foo/build' 
make -f CMakeFiles/test2.dir/build.make CMakeFiles/test2.dir/depend 
make[2]: Entering directory '/home/nega/foo/build' 
cd /home/nega/foo/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/nega/foo /home/nega/foo /home/nega/foo/build /home/nega/foo/build /home/nega/foo/build/CMakeFiles/test2.dir/DependInfo.cmake --color= 
make[2]: Leaving directory '/home/nega/foo/build' 
make -f CMakeFiles/test2.dir/build.make CMakeFiles/test2.dir/build 
make[2]: Entering directory '/home/nega/foo/build' 
[ 50%] Building CXX object CMakeFiles/test2.dir/main.cpp.o 
/usr/bin/c++  -std=gnu++11 -o CMakeFiles/test2.dir/main.cpp.o -c /home/nega/foo/main.cpp 
[100%] Linking CXX executable test2 
/usr/bin/cmake -E cmake_link_script CMakeFiles/test2.dir/link.txt --verbose=1 
/usr/bin/c++  CMakeFiles/test2.dir/main.cpp.o -o test2 /usr/lib/x86_64-linux-gnu/libzmq.so 
make[2]: Leaving directory '/home/nega/foo/build' 
[100%] Built target test2 
make[1]: Leaving directory '/home/nega/foo/build' 
/usr/bin/cmake -E cmake_progress_start /home/nega/foo/build/CMakeFiles 0 

Если вы посмотрите на строке компиляции, вы заметите, что

  1. C++ 11 добавлена ​​поддержки (с -std=gnu++11 флага)
  2. Там нет -I/path/to/zmq флага. Это потому, что Ubuntu отвалов zmq.hpp, чтобы /usr/include и CMake достаточно умен, чтобы знать, что это путь по умолчанию, так что он ничего не делает

Если вы посмотрите на линию связи, вы заметите, что libzmq.so был включен через его полный путь. Некоторым людям это не нравится (включая меня) и предпочитают вместо этого -L/lib/dir -lmylib. Использование полного пути - «путь CMake», и вы действительно оцените его, когда будете расти с помощью CMake и используйте его для более крупных и сложных проектов (вам все равно может не понравиться это.)

Также обратите внимание, что так как вы на Ubuntu, мы могли бы обманутые и использовал dpkg -L libzmq3-dev, чтобы найти расположение файлов, мы заинтересованы в том добавили их к исходной CMAKE_CXX_FLAGS линии, но это обман и что более важно, не переносится.

+0

Я столкнулся с ошибкой в ​​Mac OS X и Ubuntu, пока не установил самую последнюю версию ZeroMQ, используя 'sudo apt install libzmq5' [Ubuntu] или' brew install zmq' [OS X] –

3

Файл конфигурации cmake был недавно добавлен в репозиторий libzmq github here.

Это еще не включено в последнюю версию (4.2.1), но я считаю, что это должно быть в следующем выпуске.

Я установил версию головки с помощью cmake, а затем установил cppzmq, который использует find_package(ZeroMQ REQUIRED), чтобы найти libzmq. Все работало как шарм.

+0

Действительно, это способ если у вас есть возможность использовать HEAD или предстоящий выпуск. Если вы застряли с использованием системных пакетов, мой предыдущий ответ - это путь. Он также может быть экстраполирован в любую библиотеку, поддерживающую pkg-config, но не поддерживающую конфигурацию cmake. – nega