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は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
コンパイル行を見ると、
-std=gnu++11
フラグ付き)-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
行に追加した可能性もありますが、それは不正行為であり、さらに重要なことに、移植性はありません。
Cmake設定ファイルが2017年1月7日にlibzmq githubリポジトリに追加されました ここ 。
これは最新リリース(4.2.1)にはまだ含まれていませんが、次のリリースに含まれるはずです。
Cmakeを使用してヘッドバージョンをインストールし、次にfind_package(ZeroMQ REQUIRED)
を使用してlibzmqを見つける cppzmq をインストールしました。すべてが魅力のように機能しました。
編集:cmake構成ファイルはリリース4.2.2に含まれています ここ 。次に、リリース時にディレクトリ_builds/cmake
_に移動されました 4.2.4 。私はそれを再度テストしませんでしたが、find_package(ZeroMQ REQUIRED)
はibzmq 4.2.2以降で機能するはずです。
これも機能します
cmake_minimum_required(VERSION 3.6)
project(test)
add_executable(c main.cpp)
target_link_libraries(c zmq)