지난 포스팅에서 유니버설 메시징 라이브러리 오픈소스인 ZeroMQ에 대해 소개했다. 이번에는 해당 라이브리러를 macOS에 어떻게 설치하여, 사용할 수 있는지 그 과정을 포스팅해보고자 한다.
brew install zmq
이때, homebrew
가 설치되어 있어야 하며, 아래와 같이 설치가 진행된다. homebrew
가 미설치 된 경우라면, 아래 내용을 참고하여 설치를 진행한다.
❓ Homebrew란?
✔️ How to install homebrew?
터미널을 열고 다음과 같이 입력한다.
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
설치 후, Press RETURN to continue or any other key to abort 라는 문장이 나오면 return 키를 누룬 후, 패스워드를 입력하면 설치가 완료된다.
Homebrew를 사용하여 프로그램을 설치하기 전 cask
라는 패키지를 먼저 설치해야 하는데, cask
는 사파리, 크롬과 같이 그래픽을 통해 작업하는 프로그램을 설치할 수 있게 해주는 패키지이다.
brew update
라고 입력하면, homebrew의 업데이트가 존재할 경우, 업데이트를 진행한다.
이제 homebrew가 설치되었다면, 다시 ZMQ를 설치해도록 하자!
공식 튜토리얼에 나와있는 내용은 아니지만, 위의 설치 명령으로 설치 후 예제 파일을 실행시키려고 하니 많은 에러들을 만나게 되었다.
에러들을 해결하기 위해서는 다음과 같은 것들을 설치해주어야 한다.
1️⃣. gcc, g++ 컴파일러
❓❓ make 파일이 gcc로 만들어져 있을 경우, mac의 기본 컴파일러는 clang
이기 때문에, 다음과 같은 에러가 발생한다.
터미널에서 /usr/local/bin
로 들어가, gcc-9
가 설치되어 있나 확인해볼 수 있다.
다음 명령어로 gcc
컴파일러를 설치한다.
brew install gcc
❓❓다음과 같은 에러가 발생한 경우, boost
와 tbb
가 설치되어 있지 않았기 때문이다.
2️⃣. boost
boost
는 C++ 프로그래밍 언어를 위한 선형대수, 의사 난수 발생, 멀티스레딩, 영상 처리, 정규 표현식, 그리고 유닛 테스트와 같은 작업들과 구조들을 지원하는 라이브러리들의 집합이다.brew install boost
3️⃣. tbb
tbb
는 Threading Building Blocks의 약자로 다중 코어 프로세서의 이점을 취하는 소프트웨어 프로그램을 작성할 목적으로 인텔이 개발한 C++ 템플릿 라이브러리이다. 설치후, 다음과 같이 path를 추가해주어야 한다.brew install tbb
export LIBRARY_PATH=/usr/local/lib:$LIBRARY_PATH
설치를 마쳤다면, 예제를 실행시켜 볼 차례다!
아래 Github 저장소에 들어가 해당 오픈소스를 다운받는다.
다운을 받으면 example 디렉토리를 확인할 수 있다. C++로 짜인 코드를 실행시켜보도록 하겠다.
이 예제는 하나의 클라이언트와 하나의 서버를 만든다. 클라이언트는 "Hello"를 서버로 보내고, "World"를 응답으로 받는다. 서버는 5555번 포트에 대해 ZeroMQ 소켓을 열여서 요청을 읽은 후에 각 요청에 대해 "World"로 응답한다. 이를 표현한 그림이 아래 그림이다.
소스코드는 다음과 같다.
hwserver.cpp
//
// Hello World server in C++
// Binds REP socket to tcp://*:5555
// Expects "Hello" from client, replies with "World"
//
#include <zmq.hpp>
#include <string>
#include <iostream>
#include <unistd.h>
int main () {
// Prepare our context and socket
zmq::context_t context (1);
zmq::socket_t socket (context, ZMQ_REP);
socket.bind ("tcp://*:5555");
while (true) {
zmq::message_t request;
// Wait for next request from client
socket.recv (&request);
std::cout << "Received Hello" << std::endl;
// Do some 'work'
sleep (1);
// Send reply back to client
zmq::message_t reply (5);
memcpy ((void *) reply.data (), "World", 5);
socket.send (reply);
}
return 0;
}
hwclient.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;
}
처음 실행시키려고 했을 때, 많은 에러를 만났다 ...
추가해줘야 할 것들이 더 있었나보다..
찾아보니 아래 명령어들을 터미널에 입력하여 추가해줘야 했다..
export PKG_CONFIG_PATH=/usr/local/Cellar/zeromq/4.0.4/lib/pkgconfig/
sudo visudo에 들어가서 Defaults env_keep += "PKG_CONFIG_PATH" 를 입력한다.
sudo npm install zmq
❓❓이제 다시 컴파일을 해보려고 하면 다음과 같은 에러가 또 발생한다.
이 에러를 해결하기 위해 xcode 빌드 설정, vscode에서 실행, reinstall, path 설정등 여러 방법들을 시도해보았는데 결정적인 것은 linking이였다...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
컴파일 시, 명령어는 다음과 같다.
뒤에 -L/usr/local/lib -lzmq
옵션을 주어야 한다.
clang
으로 c 소스코드 컴파일clang -Wall [컴파일할 파일 이름] -o [실행파일 이름] -L/usr/local/lib -lzmq
gcc
, g++
로 컴파일gcc [컴파일할 파일 이름] -o [실행파일 이름] -L/usr/local/lib -lzmq
g++ [컴파일할 파일 이름] -o [실행파일 이름] -L/usr/local/lib -lzmq
✔️-L/usr/local/lib
는 linker에게 path (/usr/local/lib)
를 add 하라고 알려주는 옵션이다.
✔️-lzmq
는 zmq library를 link하도록 해준다.
❓❓만약, 다음과 같은 에러가 발생한다면 소스코드를 열어서 #include <zmq.hpp>
를 #include "zmq.hpp"
로 수정해준다.
error: 'zmq.hpp' file not found with include; use "quotes" instead
이제 컴파일 후, 실행시켜본다...
1️⃣. 서버 실행
g++ hwserver.cpp -o server -L/usr/local/lib -lzmq
./server
2️⃣. 클라이언트 실행
g++ hwclient.cpp -o client -L/usr/local/lib -lzmq
./client
이 두 프로그램은 동작을 위해 ZeroMQ 컨텍스트와 소켓을 하나 만든다. 서버는 자신의 REP(응답) 소켓을 5555번 포트와 묶는다. 서버는 루프 내에서 요청을 대기하고, 요청이 올 때마다 응답한다. 클라이언트는 요청을 보내고 서버로부터 돌아오는 응답을 읽는다.
이번 포스팅에서는 ZMQ를 macOS에 설치하는 방법과 간단한 예제 코드의 컴파일과 실행 및 에러 처리 방법에 대해 알아보았다.
다음 포스팅에서는 ZMQ를 이용한 다른 소스코드를 실행시켜보고, 활용해보는 시간을 갖겠다. 👩🏻💻🍒