【问题标题】:How to import zeromq libraries in cmake?如何在 cmake 中导入 zeromq 库?
【发布时间】:2017-05-06 05:02:05
【问题描述】:

我刚刚开始学习如何使用 zeromq 库并在不同的 C++ 项目中使用它们。 我写的示例代码(实际上是从那里的教程中复制的)是这样的:

//  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 构建文件。因此,我编写了一个 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

【问题讨论】:

    标签: cmake zeromq


    【解决方案1】:

    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 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 行,但这是作弊等等重要的是,不便携。

    【讨论】:

    • 在我使用sudo apt install libzmq5 [Ubuntu] 或brew install zmq [OS X] 安装最新版本的 ZeroMQ 之前,我在 Mac OS X 和 Ubuntu 上遇到了错误
    【解决方案2】:

    已将 cmake 配置文件添加到 libzmq github 存储库 2017 年 1 月 7 日 here

    这还没有包含在最新版本 (4.2.1) 中,但我相信它应该包含在下一个版本中。

    我已经使用cmake安装了head版本,然后安装了cppzmq,它使用find_package(ZeroMQ REQUIRED)来定位libzmq。一切都像魅力一样。

    编辑:cmake 配置文件包含在版本 4.2.2 here 中。然后在发布4.2.4 时将其移至目录builds/cmake。我没有再次测试它,但find_package(ZeroMQ REQUIRED) 应该从 ibzmq 4.2.2 开始工作。

    【讨论】:

    • 确实,如果您有能力使用 HEAD 或即将发布的版本,这就是要走的路。如果您在使用系统包时遇到问题,那么我之前的回答就是要走的路。它也可以外推到任何支持 pkg-config 但不支持 cmake config 的库。
    【解决方案3】:

    这个也可以

     cmake_minimum_required(VERSION 3.6)
     project(test)     
     add_executable(c main.cpp)
     target_link_libraries(c zmq)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-08-15
      • 2016-06-01
      • 1970-01-01
      • 2017-08-19
      • 2015-03-20
      • 2013-03-26
      • 1970-01-01
      相关资源
      最近更新 更多