[ZeroMQ] Install on macOS

Hα ყҽσɳɠ·2020년 3월 14일
0

project2

목록 보기
3/10
post-thumbnail

Intro

지난 포스팅에서 유니버설 메시징 라이브러리 오픈소스인 ZeroMQ에 대해 소개했다. 이번에는 해당 라이브리러를 macOS에 어떻게 설치하여, 사용할 수 있는지 그 과정을 포스팅해보고자 한다.


Install on macOS


1. MacOS 터미널에 다음과 같은 명령어를 입력하여 설치할 수 있다.

brew install zmq

이때, homebrew가 설치되어 있어야 하며, 아래와 같이 설치가 진행된다. homebrew가 미설치 된 경우라면, 아래 내용을 참고하여 설치를 진행한다.

❓ Homebrew란?

  • macOS용 패키지 관리자이다. 터미널(Terminal)에서 명령어를 작성하여 자신이 필요한 프로그램을 설치, 삭제, 업데이트를 손쉽게 관리할 수 있게 해준다.
    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를 설치해도록 하자!

2. 라이브리러리 실행에 필요한 것들을 추가 설치하여야 한다.

공식 튜토리얼에 나와있는 내용은 아니지만, 위의 설치 명령으로 설치 후 예제 파일을 실행시키려고 하니 많은 에러들을 만나게 되었다.
에러들을 해결하기 위해서는 다음과 같은 것들을 설치해주어야 한다.

1️⃣. gcc, g++ 컴파일러

❓❓ make 파일이 gcc로 만들어져 있을 경우, mac의 기본 컴파일러는 clang이기 때문에, 다음과 같은 에러가 발생한다.

  • 터미널에서 /usr/local/bin로 들어가, gcc-9가 설치되어 있나 확인해볼 수 있다.

  • 다음 명령어로 gcc 컴파일러를 설치한다.

    brew install gcc

❓❓다음과 같은 에러가 발생한 경우, boosttbb가 설치되어 있지 않았기 때문이다.

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


Running the example code


설치를 마쳤다면, 예제를 실행시켜 볼 차례다!
아래 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를 이용한 다른 소스코드를 실행시켜보고, 활용해보는 시간을 갖겠다. 👩🏻‍💻🍒

profile
𝑯𝒐𝒏𝒆𝒔𝒕𝒚 𝑰𝒏𝒕𝒆𝒈𝒓𝒊𝒕𝒚 𝑬𝒙𝒄𝒆𝒍𝒍𝒆𝒏𝒄𝒆

0개의 댓글