
지난 포스팅에서 유니버설 메시징 라이브러리 오픈소스인 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를 이용한 다른 소스코드를 실행시켜보고, 활용해보는 시간을 갖겠다. 👩🏻💻🍒