Docker에서 JNA용 리눅스 동적 라이브러리 빌드하기

smpl published on
3 min, 444 words

파일들

다음과 같은 상황이라고 가정한다.

crypto++ 라이브러리를 사용하여 특정한 기능을 제공하는 libcrypt라는 동적 라이브러리를, java에서 jna로 사용하려는 상황이다.

라이브러리 파일이 예시로 다음과 같다고 하고,

// mycrypt.h

#pragma once

#include <cstdlib>

extern "C" {

    int DoSomething (int a, int b);
}
// mycrypt.cc

#include <iostream>

#include "mycrypt.h"

__attribute__((constructor)) void init() {
    // initialize here
}

__attribute__((destructor)) void fini() {
    // finalize here
}

int DoSomething(int a, int b) {
    return a + b;
}

이를 사용하는 샘플은 다음과 같다.

// mycryptsample.cc

#include <iostream>

#include "mycrypt.h"

int main (int argc, char ** argv) {
    int ret = DoSomething(10, 20);
    std::cout << "mycryptsample : " << ret << std::endl;
}
// MyCryptUser.java

import com.sun.jna.Library;
import com.sun.jna.Native;

interface MyCryptLibrary extends Library {
    MyCryptLibrary INSTANCE = Native.load("mycrypt", MyCryptLibrary.class);

    int DoSomething(int a, int b);
}

public class MyCryptUser {
    public static void main(String[] args) {
        int ret = MyCryptLibrary.INSTANCE.DoSomething(10, 20);
        System.out.println("MyCryptUser: " + ret);
    }
}

Dockerfile

아래는 이 코드들을 빌드하고 테스트하고 패키징하는 Dockerfile의 예이다.

FROM ubuntu:16.04 AS builder

WORKDIR /root

RUN apt-get update
RUN apt-get install -y build-essential libcrypto++-dev

COPY . .

RUN g++ -std=c++14 -fPIC -c mycrypt.cc -lcrypto++ -I/usr/include/crypto++
RUN g++ -std=c++14 -shared -o libmycrypt.so mycrypt.o -lcrypto++
RUN g++ -std=c++14 -o mycryptsample mycryptsample.cc -L. -lmycrypt -lcrypto++

FROM ubuntu:16.04 AS testandpackage

VOLUME /output
WORKDIR /deploy

RUN apt-get update
RUN apt-get install -y build-essential openjdk-8-jre openjdk-8-jdk wget libcrypto++9v5

COPY --from=builder /root/libmycrypt.so /deploy/
COPY --from=builder /root/mycrypt.h /deploy/
COPY --from=builder /root/mycryptsample /deploy/
COPY --from=builder /root/MyCryptUser.java /deploy/
COPY --from=builder /root/README.md /deploy/

RUN wget https://repo1.maven.org/maven2/net/java/dev/jna/jna/5.10.0/jna-5.10.0.jar

RUN echo `pwd` > mycrypt.conf
RUN mv mycrypt.conf /etc/ld.so.conf.d/
RUN ldconfig

ENV CLASSPATH="$CLASS_PATH:jna-5.10.0.jar:/usr/local/lib:/usr/local/lib/x86_64-linux-gnu:/lib/x86_64-linux-gnu:/usr/lib/x86_64-linux-gnu:."

RUN javac MyCryptUser.java

RUN ./mycryptsample
RUN java MyCryptUser

CMD ./mycryptsample && java MyCryptUser && tar cvjf /output/mycrypt.tar.bz2 mycrypt.h MyCryptUser.java README.md libmycrypt.so

다음과 같은 shell 명령으로 빌드할 수 있고, 빌드 결과가 output이라는 폴더에 만들어진다.

docker build . -t mycryptbuild:0.1.0
docker run -v output:/output mycryptbuild:0.1.0

참조

다음과 같은 문서들을 참조하였음.