Elsaの技術日記(徒然なるままに)

主に自分で作ったアプリとかの報告・日記を記載

MENU

CMakeで複数の実行ファイルを生成するあれこれ

今回はCMakeを用いて複数の実行ファイルを生成したり、生成する実行ファイルを切り替える方法についてまとめておきたいと思います。
以前より気にはなっていたのですが、調べるの億劫で出来ていませんでした。。
ちょっと用事があったのでこの機に調べてみることに!!



■経緯

今回ちょうどC++言語でいくつかのアプリを作成しているのですが、
まぁ同じような処理を多々やっている。
どうせなら、共通処理は同じコードを使いまわしたいと考えたのですが、、、
ライブラリ作って管理するのは面倒だし、、
ということでこちらのフォルダ構成で別々にコンパイルすれば?とも考えたのですが、、
CMakeファイルが2種類必要。。
f:id:Elsammit:20211128182626p:plain

ということで1つのCMakeファイルで、
複数の実行ファイルを生成したり、生成するファイルを切り替えたり出来ないか?と考えたのが始まりです。

■使用環境

今回のフォルダ構成はこちらとします。
f:id:Elsammit:20211128182640p:plain

今回使用するコードはこちらになります。

ファイル名:calc.h

#include <stdio.h>

int add(int a,int b);
int sub(int a,int b);

ファイル名:calc.cpp

#include "calc.hpp"

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

int sub(int a,int b){
    return a-b;
}


ファイル名:main1.cpp

#include <stdio.h>
#include "common/calc.hpp"

int main(){
    printf("%d \n", add(1,2));
}


ファイル名:main1.cpp

#include <stdio.h>
#include "common/calc.hpp"

int main(){
    printf("%d \n", add(1,2));
}

ファイル名:main2.cpp

#include <stdio.h>
#include "common/calc.hpp"

int main(){
    printf("%d \n", sub(1,2));
}

■CMakeファイルで複数の実行ファイルを生成

まずは1つのCMakeファイルで複数のコードを実行する方法についてまとめます。
今回のケースの場合、CMakeLists.txtはこちらのようになります。

cmake_minimum_required(VERSION 3.5.1)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")

file(GLOB SOURCES "common/*.cpp")

set(PROJECT_NAME1 main1)
project(${PROJECT_NAME1})

set(PROJECT_NAME2 main2)
project(${PROJECT_NAME2})

add_executable(${PROJECT_NAME1} main1.cpp ${SOURCES}) 
add_executable(${PROJECT_NAME2} main2.cpp ${SOURCES}) 

実施していることは、

set(PROJECT_NAME1 main1)
project(${PROJECT_NAME1})

set(PROJECT_NAME2 main2)
project(${PROJECT_NAME2})

にて実行ファイル名を各アプリ毎に指定し、

add_executable(${PROJECT_NAME1} main1.cpp ${SOURCES}) 
add_executable(${PROJECT_NAME2} main2.cpp ${SOURCES}) 

にて実行ファイルを生成する。
になります。
ここで、${SOURCES}は、

file(GLOB SOURCES "common/*.cpp")

にて定義している通り、共通コード部分であるcommonフォルダを指しております。

こちらを実行するとそれぞれのアプリに対してコンパイルが実行され2種類の生成物(実行ファイル)が生成されます。
※今回のコードですとmain1, main2が生成。

生成されたコードを実行すると正しく実行出来ることが確認できるかと思います。

■CMake実行時に生成する実行ファイルを切り替える

では次にcmake実行時に生成する実行ファイルを切り替える場合についてまとめていきます。

CMakeでは引数を与えることが出来ます。
例えば、

cmake . -DHOGE=1

とすると、HOGEという変数に1を代入してcmakeを実行する意味になります。
また、CMakeではif文も使用できるので、今回のケースですと、

cmake_minimum_required(VERSION 3.5.1)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")

file(GLOB SOURCES "common/*.cpp")

if("${HOGE}" EQUAL 1)
    set(PROJECT_NAME1 main1)
    project(${PROJECT_NAME1})
    add_executable(${PROJECT_NAME1} main1.cpp ${SOURCES}) 
elseif("${HOGE}" EQUAL 2)
    set(PROJECT_NAME2 main2)
    project(${PROJECT_NAME2})
    add_executable(${PROJECT_NAME2} main2.cpp ${SOURCES}) 
endif()

とし、main1を生成させたい場合には、

cmake . -DHOGE=1
make

main2を生成させたい場合には、

cmake . -DHOGE=2
make

とすればOK。

実行してみると確かに、生成されるコードが切り替わることが確認できるかと思います。

■最後に

今回はCMakeファイルで複数の実行ファイルを生成したり、生成される実行ファイルを切り替えたりしてみました。
まだチャレンジ出来ていないけど、共通コードをあまり変更しないならオブジェクトファイルを利用すればコンパイルがもっと早く・楽にできそうだな。
後で時間がある時に試してみます。