Help us understand the problem. What is going on with this article?

C++/JavaとWin/Linuxの組み合わせにおけるビルドについて整理する

はじめに

本記事では、C++とJavaという2つのプログラミング言語について、ビルド周りの知識を整理します。
具体的には、各言語における「基本的なビルド方法」、「共有ライブラリの利用方法」、「ビルドツール」について整理します。
その際、WindowsとLinuxとで相違がある場合には、その点についても触れます。

本記事の投稿目的は、投稿者自身が知識を整理することであり、内容に間違いが含まれる可能性があります。
間違いを見つけた方はコメントなどで指摘をお願いします。

基本的なビルド方法

本節では、コマンドラインからビルドを行う基本的な方法について整理します。
「ビルド = コンパイル + リンク」として説明します。

C++

main.cpp, hoge.cpp, hoge.hという3つのファイルからプロジェクトが構成されるとします。
コンパイルは、

g++ -c main.cpp hoge.cpp

リンクは、

g++ main.o hoge.o

というコマンドで行うことができ、実行ファイル(Linuxではa.out, Windowsではa.exe)が生成されます。
-cは「コンパイルのみを行う」オプションであり、このオプションを省くと一気に実行ファイルの生成まで済ませることができます。

g++ main.cpp hoge.cpp

Java

Main.java, Hoge.javaという2つのファイルからプロジェクトが構成されるとします。
コンパイルは、

javac Main.java

というコマンドで行うことができ、Main.classとHoge.classというファイルが生成されます。
依存関係は自動解決してくれるので、Hoge.javaを引数に加える必要はありません。
また、リンクは実行時に行うため、コマンドで明示的にリンクを行う必要はありません。
実行は、

java Main

というコマンドで行います。

共有ライブラリの利用方法

共有ライブラリの利用方法についてOpenCVを例に説明します。
OpenCVを例とした理由は投稿者にとって身近なライブラリだというだけなので、OpenCVをよく知らない方は別のライブラリに置き換えて読んでいただければと思います。

C++(Linux)

インクルードパス、ライブラリパス、共有ライブラリファイルの3つをg++のオプションで指定します。
例えば、インクルードパス:/usr/local/include/opencv4, ライブラリパス:/usr/local/lib, 共有ライブラリファイル:libopencv_core.soの場合は、以下のようにします。

g++ main.cpp -I/usr/local/include/opencv4 -L/usr/local/lib -lopencv_core

C++(Windows)

Windowsの場合、-lオプションでインポートライブラリ(.libファイル)を指定します。
インポートライブラリファイル名がopencv_world420.libの場合、以下のコマンドでビルドします。

g++ main.cpp -IC:/opencv/build/include -LC:/opencv/build/x64/lib -lopencv_world420

実行時は.libファイルと対となる.dllファイル(共有ライブラリ本体)にパスを通す必要があります。
.libファイルと.dllファイルの関係については、以下のサイトが参考になるかと思います。
http://exlight.net/devel/windows/dll/windll.html

Java(Linux)

Javaでは、jarファイルが上記のインポートライブラリのような役割を担っているため、以下のように、classpathにjarファイルを指定してビルドを行います。

javac -cp /usr/local/share/java/opencv4/opencv-430.jar Main.java

そして、実行時には共有ライブラリ本体である.soファイルへのパスをjava.library.pathとして与える必要があります。
(説明は省略しますが、ソースコード上でもSystem.loadLibrary関数で.soファイルをロードする必要があります)
また、実行時にもclasspathが必要で、かつ、実行したいclassファイルのパス(.)も指定する必要があります。

java -cp .:/usr/local/share/java/opencv4/opencv-430.jar -Djava.library.path=/usr/local/share/java/opencv4 Main

詳細は以下のページが参考になるかと思います。
https://stackoverflow.com/questions/28727766/how-to-add-an-external-library-opencv-jar-file-to-the-java-build-path-from-th

Java(Windows)

Windowsの場合、.soファイルの代わりに.dllファイルをロードし、classpathの区切り文字が":"ではなく";"となります。

javac -cp C:/opencv/build/java/opencv-430.jar Main.java
java -cp .;C:/opencv/build/java/opencv-420.jar -Djava.library.path=C:/opencv/build/java/x64 Main

ビルドツール

本節では、C言語のビルドツールであるCMakeとJavaのビルドツールであるGradleを紹介します。

CMake

CMakeの説明をする前に、makeについて触れておきます。
makeはビルドツールの草分け的存在であり、Makefileにビルドルールを書いておくことで、ビルドを自動化できます。

CMakeはC言語のソースコードをインストールする際に、CMake→make→make installという手順でよく利用されます。
この各手順では、以下のような作業がなされています。

  • CMake : CMakeLists.txtに書かれたルールにしたがって、Makefileを作成する
  • make : Makefileに書かれたルールに従ってビルドする
  • make install : Makefileに書かれたルールに従って、ビルド済ファイルのコピーなどを行う

OpenCVを使う例だと、CMakeLists.txtは以下のような内容になります。
(pkg_configを利用しない場合)

cmake_minimum_required(VERSION 3.10)
project(Main)

add_executable(Main main.cpp)

target_include_directories(Main
    PRIVATE
    /usr/local/include/opencv4
)

target_link_libraries(Main
    PRIVATE
    /usr/local/lib/libopencv_core.so
)

Gradle

Gradleについては自分用のメモとして、build.gradleの中身のみ載せておきます。

apply plugin: 'java'

dependencies {
    compile files("/usr/local/share/java/opencv4/opencv-430.jar")
}

おわりに

本記事では、C++とJavaという2つのプログラミング言語について、ビルド周りの知識を整理しました。
元々はIDEで隠蔽されているビルド処理などについても触れるつもりだったのですが、必要性がいまいち分からなくなってきたので、この辺りで終わりたいと思います。
結果的に20年前の記事みたいな内容になってしまいましたが、参考にしていただければ幸いです。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした