ã¯ããã«
ïŒæã®ã¯ããé ãCMakeã䜿ã£ãŠãã«ããèªååããããšæããè²ã ã°ã°ã£ãŠCMakeLists.txtãäœã詊è¡é¯èª€ããã®ã§ããããã®æã¯çµå±æå¿µããŸããããšããã®ããabcãšããã¹ãããããããšãããšãã°ã°ããŠåŸããã解説ã¯abcã®aãbãæããŠãããªãcãã解説ããããã®ãå€ããåå¿è ã«ã¯ãã€ãã£ãããã§ããç¹ã«cmake.orgã®ãã¥ãŒããªã¢ã«ã¯ãŸãã«ãã®å žåã§ããã¥ãŒããªã¢ã«ã®Step 1ããããŠé·éããŠãæ¬åœã«äœãå¿ èŠãªã®ããããã«ããã»ã»ã»orz
ãšããããä»åŠæåããŠããHigh Performance Computingãšããè¬çŸ©ã§è¡ãããCMakeã®äœ¿ãæ¹ã®è§£èª¬ããããæãããŠããã£ãšããéã«èªäœã©ã€ãã©ãªãCMakeã§ã³ã³ãã€ã«ããããšãã§ããããã«ãªããCMakeã®äŸ¿å©ãã«æåããŠããŸããŸãããç§ãšåããCMakeåå¿è ãšããæ¹ã«ãã®æåãå ±æãã¹ããããã«äœ¿ãæ¹ããŸãšããŠãããŸããç§èªèº«ã¯c++ã䜿ã£ãŠããã®ã§ãäžèšã§ã¯c++ã®å ŽåãšããŠèª¬æããŠããŸããOSã¯Ubuntu 16.04LTSãã³ã³ãã€ã©ã¯g++ 5.4.0ã§ãã
ããã§ã¯èªåã§ã³ãã³ãã©ã€ã³ãããã«ãããå ŽåãšCMakeã®å Žåã察æ¯ãããŠèª¬æããŠããŸãããããããšãCMakeã®åã³ãã³ããšã®å¯Ÿå¿ãããããçè§£ãããããšããããŸããã
ããããããæ¹ãããããšããããããäœ¿ãæ¹ãããããšããå Žåã¯ã³ã¡ã³ããé ããã°å¹žãã§ãã
é¢é£èšäº
CMakeã®äœ¿ãæ¹ïŒãã®ïŒïŒ
CMakeã®äœ¿ãæ¹ïŒãã®ïŒïŒ
åèè³æ
æ¬èšäºãæžãã«ãããCMakeã®å
¬åŒããã¥ã¡ã³ããåç
§ããŸããã
ãã®ä»ã«ã¯ãããããªYoutubeã®åç»ãåèã«ããŠããŸãã
ãŸãç§èªèº«ã¯è³Œå
¥ããŠããŸããããProfessional CMake: A Practical Guideãšããæ¬ã¯CMakeã®co-maintainerã®äžäººãæžããæ¬ã ããã§ãããé«åºŠãªå
容ãå匷ãããå Žåã¯ãã¡ããããããã§ãã
ã¹ãããïŒïŒå®è¡ãã¡ã€ã«ãäœæ
ã³ãã³ãã©ã€ã³ãããã«ã
ãŸãg++ã³ã³ãã€ã©ã䜿ã£ããã«ãã®åºæ¬ã確èªããŸãããã¡ããã³ã³ãã¯ãã«ãŸãšããããŠããŠããããããããªãšæããŸãã詳现ã¯gcc.gnu.orgã®output optionsãoption summaryãèªãã§å匷ããŸãããã
ãŸãäžèšã®ãããªç°¡åãªãœãŒã¹ã³ãŒãããããšããŸãã
.
âââ main.cpp
âââ hello.hpp
âââ hello.cpp
âââ hoge.py
#include "hello.hpp"
int main() {
hello();
}
#ifndef HELLO_H
#define HELLO_H
void hello();
#endif
#include <iostream>
#include "hello.hpp"
void hello() {
std::cout << "Hello!" << std::endl;
}
ãŸããããæ®éã«ã³ãã³ããæã¡èŸŒãã§ãã«ãããŸãã
$ g++ -c main.cpp hello.cpp # ãœãŒã¹ãã¡ã€ã«ãã³ã³ãã€ã«ããŠãªããžã§ã¯ããã¡ã€ã«ïŒmain.o, hello.oïŒãçæ
$ g++ -o a.out main.o hello.o # ãªããžã§ã¯ããã¡ã€ã«ããªã³ã¯ããŠa.outãšããå®è¡ãã¡ã€ã«ãçæ
ãããšãã£ã¬ã¯ããªã®äžã¯æ¬¡ã®ããã«ãªã£ãŠããã¯ãã§ãã
.
âââ a.out
âââ main.cpp
âââ main.o
âââ hello.hpp
âââ hello.cpp
âââ hello.o
ãã®a.outãå®è¡ããã°Hello!ãšè¡šç€ºãããŸãã
$ ./a.out
Hello!
ãããã¯æ¬¡ã®ããã«ãããšããªããžã§ã¯ããã¡ã€ã«ã¯çæããããçŽæ¥å®è¡ãã¡ã€ã«ãäœãããŸãã
$ g++ main.cpp hello.cpp
CMakeã䜿ã£ãŠã¿ã
ã§ã¯å
çšã®æãç°¡åãªäŸãCMakeã䜿ã£ãŠãã«ãããŠã¿ãŸããããCMakeã䜿ã£ããã«ãã®èšå®ã¯CMakeLists.txtãšããããã¹ããã¡ã€ã«ã«èšè¿°ããŸãããã£ã¬ã¯ããªã®äžèº«ã¯æ¬¡ã®ããã«ãªããŸãã
.
âââ CMakeLists.txt
âââ main.cpp
âââ hello.hpp
âââ hello.cpp
CMakeLists.txtã®å
å®¹ã¯æ¬¡ã®ããã«ãªããŸãã
# CMakeã®ããŒãžã§ã³ãèšå®
cmake_minimum_required(VERSION 3.13)
# ãããžã§ã¯ãåãšäœ¿çšããèšèªãèšå®
project(test_cmake CXX)
# a.outãšããå®è¡ãã¡ã€ã«ãmain.cppãšhello.cppããäœæ
add_executable(a.out main.cpp hello.cpp)
CMakeã䜿ã£ãŠãã«ããããšãã¯ã次ã®ããã«å¿ ããœãŒã¹ãã£ã¬ã¯ããªãšã¯å¥ã«ãã«ãå°çšã®ãã£ã¬ã¯ããªãäœæãããã®äžã§ãã«ãããŸãã
$ cmake -S . -B build
$ cmake --build build
æçµçãªãã£ã¬ã¯ããªæ§æã¯ä»¥äžã®ããã«ãªã£ãŠããã¯ãã§ãã
.
âââ CMakeLists.txt
âââ main.cpp
âââ hello.hpp
âââ hello.cpp
âââ build/
âââ a.out
âââ ...
ãã®ãããªCMakeLists.txtã®èšå®ã®å Žåãå®è¡ãã¡ã€ã«ãçæãããéäžã®ãªããžã§ã¯ããã¡ã€ã«ã¯ïŒãã®ä»è²ã ïŒã®ãã£ã¬ã¯ããªã®äžã«çæãããŸãã
ããŠãããã§æçµçã«åŸããããã£ã¬ã¯ããªã®äžèº«ãæ¯ã¹ãŠã¿ãŸããããæ®éã«ã³ãã³ãã©ã€ã³ãããã«ãããå ŽåããœãŒã¹ã³ãŒããšãªããžã§ã¯ããã¡ã€ã«ããã³å®è¡ãã¡ã€ã«ãæ··åšããå
ã®ç¶æ
ã«æ»ãã®ãé¢åã§ãããšãããCMakeã䜿ã£ãå Žåããã«ãçµæã¯å
šãŠbuildãã£ã¬ã¯ããªå
ã«ä¿åãããŠãããããbuildãã£ã¬ã¯ããªãåé€ããã ãã§å®¹æã«å
ã®ç¶æ
ã«æ»ãããšãã§ããŸããããã¯out-of-sourceãã«ããšåŒã°ããŠããŸãããã¡ãã®èšäºïŒCMake : out-of-sourceãã«ãã§å¹žãã«ãªãïŒã§è©³ãã解説ãããŠããŸãã
ã¹ãããïŒïŒéçã»å ±æã©ã€ãã©ãªãäœæ
ã³ãã³ãã©ã€ã³ãããã«ã
ããŠãã©ã€ãã©ãªãäœã£ãŠããå Žåã¯ãéçã»å ±æã©ã€ãã©ãªïŒ*.a, *.soïŒãäœæããŠãããå¿ èŠã«å¿ããŠå®è¡ãã¡ã€ã«ã«ãªã³ã¯ããããšã«ãªããŸãããŸããã®äœæ¥ãã³ãã³ããæã¡èŸŒãã§ãã£ãŠã¿ãŸãããã
ã¹ãããïŒã®äŸã«good_morning.hppãgood_morning.cppãšãããã¡ã€ã«ãå ãã£ããšèããŸãã
.
âââ main.cpp
âââ hello.hpp
âââ hello.cpp
âââ good_morning.hpp
âââ good_morning.cpp
#ifndef GOOD_MORNING_H
#define GOOD_MORNING_H
void good_morning();
#endif
#include <iostream>
#include "good_morning.hpp"
void good_morning() {
std::cout << "Good morning!" << std::endl;
}
main.cppãæ¬¡ã®ããã«ä¿®æ£ããŸãã
#include "hello.hpp"
#include "good_morning.hpp"
int main () {
hello();
good_morning();
}
éçã©ã€ãã©ãªãäœæ
hello.cppãšgood_morning.cppãã³ã³ãã€ã«ããŠãªããžã§ã¯ããã¡ã€ã«ãçæããããšãéçã©ã€ãã©ãªlibgreetings.aãäœæããmain.cppãã³ã³ãã€ã«ããéã«ãªã³ã¯ããŠå®è¡ãã¡ã€ã«ãäœæããŸãã
$ g++ -c hello.cpp good_morning.cpp # ãªããžã§ã¯ããã¡ã€ã«(hello.o, good_morning.o)ã®äœæ
$ ar rvs libgreetings.a hello.o good_morning.o # éçã©ã€ãã©ãª(libgreetings.a)ã®äœæ
$ g++ main.cpp libgreetings.a # main.cppãã³ã³ãã€ã«ããŠlibgreetings.aãšãªã³ã¯ãå®è¡ãã¡ã€ã«a.outãäœæ
æçµçãªãã£ã¬ã¯ããªæ§æã¯ä»¥äžã®ããã«ãªããŸãã
.
âââ a.out
âââ main.cpp
âââ hello.hpp
âââ hello.cpp
âââ hello.o
âââ good_morning.hpp
âââ good_morning.cpp
âââ good_morning.o
âââ libgreetings.a
å ±æã©ã€ãã©ãªãäœæ
hello.cppãšgood_morning.cppãã³ã³ãã€ã«ããŠãªããžã§ã¯ããã¡ã€ã«ãçæããããšãå
±æã©ã€ãã©ãªlibgreetings.soãäœæããmain.cppãã³ã³ãã€ã«ããéã«ãªã³ã¯ããŠå®è¡ãã¡ã€ã«ãäœæããŸãã
$ g++ -fPIC -c hello.cpp good_morning.cpp # ãªããžã§ã¯ããã¡ã€ã«(hello.o, good_morning.o)ã®äœæ
$ g++ -shared hello.o good_morning.o -o libgreetings.so # å
±æã©ã€ãã©ãªïŒlibgreetings.soïŒã®äœæ
$ g++ main.cpp -L. -lgreetings -Xlinker -rpath -Xlinker . # main.cppãã³ã³ãã€ã«ããŠlibgreetings.soãšãªã³ã¯ãå®è¡ãã¡ã€ã«a.outãäœæ
æçµçãªãã£ã¬ã¯ããªæ§æã¯ä»¥äžã®ããã«ãªããŸãã
.
âââ a.out
âââ main.cpp
âââ hello.hpp
âââ hello.cpp
âââ hello.o
âââ good_morning.hpp
âââ good_morning.cpp
âââ good_morning.o
âââ libgreetings.so
ã©ã¡ãã®a.outãå®è¡ããŠã
$ ./a.out
Hello!
Good morning!
ãšè¡šç€ºãããã¯ãã§ãã
CMakeã䜿ã£ãŠã¿ã
ããŠãåãããšãCMakeã䜿ã£ãŠãã£ãŠã¿ãŸããããã¹ãããïŒãšåãããCMakeLists.txtãå ããŸãã
.
âââ CMakeLists.txt
âââ main.cpp
âââ hello.hpp
âââ hello.cpp
âââ good_morning.hpp
âââ good_morning.cpp
CMakeLists.txtã®å
å®¹ã¯æ¬¡ã®ããã«ãªããŸãã
éçã©ã€ãã©ãªãäœæ
cmake_minimum_required(VERSION 3.13)
project(test_cmake CXX)
# hello.cppãšgood_morning.cppãã³ã³ãã€ã«ããŠéçã©ã€ãã©ãªlibgreetings.aãäœæ
add_library(greetings STATIC hello.cpp good_morning.cpp)
# a.outãšããå®è¡ãã¡ã€ã«ãmain.cppããäœæ
add_executable(a.out main.cpp)
# a.outãäœæããéã«libgreetings.aããªã³ã¯
target_link_libraries(a.out greetings)
ã¹ãããïŒãšåæ§ã«buildãã£ã¬ã¯ããªãäœããã«ããããšããã£ã¬ã¯ããªã®æ§æã¯ä»¥äžã®ããã«ãªãã¯ãã§ãã
.
âââ CMakeLists.txt
âââ main.cpp
âââ hello.hpp
âââ hello.cpp
âââ good_morning.hpp
âââ good_morning.cpp
âââ build/
âââ a.out
âââ libgreetings.a
âââ ...
å ±æã©ã€ãã©ãªãäœæ
cmake_minimum_required(VERSION 3.13)
project(test_cmake CXX)
# hello.cppãšgood_morning.cppãã³ã³ãã€ã«ããŠå
±æã©ã€ãã©ãªlibgreetings.soãäœæ
add_library(greetings SHARED hello.cpp good_morning.cpp)
add_executable(a.out main.cpp)
# a.outãäœæããéã«libgreetings.soããªã³ã¯
target_link_libraries(a.out greetings)
buildãã£ã¬ã¯ããªãäœããã«ããããšããã£ã¬ã¯ããªã®æ§æã¯ä»¥äžã®ããã«ãªãã¯ãã§ãã
.
âââ CMakeLists.txt
âââ main.cpp
âââ hello.hpp
âââ hello.cpp
âââ good_morning.hpp
âââ good_morning.cpp
âââ build/
âââ a.out
âââ libgreetings.so
âââ ...
CMakeã䜿ã£ãŠãã«ãããå Žåãéçã»å ±æã©ã€ãã©ãªãäœæãããšãã®éã㯠ãã£ãã®äžèªïŒSTATIC/SHAREDïŒã§ã ã
add_library(greetings [SHARED|STATIC] hello.cpp good_morning.cpp)
ãŸãã³ãã³ãã©ã€ã³ã§ãã«ãããå Žåã¯ãç¹ã«å ±æã©ã€ãã©ãªããªã³ã¯ãããšãã«ãªã³ã¯ãªãã·ã§ã³ãè²ã é¢åãªã®ã§ããã CMakeã䜿ããšå šéšèªåã§ãã£ãŠãããŸã ãçŽ æŽãããã
éçã»å ±æã©ã€ãã©ãªã®æå®ã«ã€ããŠ
åç¯ã§ã¯STATIC/SHAREDãadd_libraryã«çŽæ¥æå®ããŸãããç¡æå®ã«ãããšã©ããªãã®ã§ããããã
add_library(greetings hello.cpp good_morning.cpp)
ãã®å Žåãadd_libraryã§æå®ãããã¿ãŒã²ããïŒããã§ã¯greetingsïŒãå
±æãŸãã¯éçã®ã©ã¡ãã§ã³ã³ãã€ã«ããããã¯ãã°ããŒãã«ãªãã·ã§ã³BUILD_SHARED_LIBSã®ON/OFFïŒããã©ã«ãã¯OFFïŒã§æ±ºãŸããŸããCMakeã䜿ã£ãŠãã«ãããéã«æ¬¡ã®ããã«æå®ããããšãå¯èœã§ãã
$ cmake -S . -B build -DBUILD_SHARED_LIBS=ON
$ cmake --build build
äžè¬çã«ã¯ãåã©ã€ãã©ãªããšã«éçã»å ±æã©ã€ãã©ãªã®ã©ã¡ãã§ãã«ããããéžæã§ãããªãã·ã§ã³ãäœæããŠããã¹ãã§ãã
# GREETINGS_BUILD_SHARED_LIBSãšãããªãã·ã§ã³ãäœæãããã©ã«ããOFFã«èšå®ã
option(GREETINGS_BUILD_SHARED_LIBS "build greetings as a shared library" OFF)
if (GREETINGS_BUILD_SHARED_LIBS)
add_library(greetings SHARED hello.cpp good_morning.cpp)
else()
add_library(greetings STATIC hello.cpp good_morning.cpp)
endif()
ãããããšå ã»ã©åæ§ã«ã³ãã³ãã©ã€ã³ããæå®ããããšãå¯èœã§ãã
$ cmake -S . -B build -DGREETINGS_BUILD_SHARED_LIBS=ON
$ cmake --build build
ã¹ãããïŒïŒãµããã£ã¬ã¯ããªã«ãœãŒã¹ã忣ããŠããå Žå
ããŠãå®éã®ã©ã€ãã©ãªã«ãããŠã¯ãã¹ãããïŒã»ïŒã®ããã«ã©ã€ãã©ãªã®ã«ãŒããã£ã¬ã¯ããªçŽäžã«ãœãŒã¹ã³ãŒããäžæ¬ã§ãããŠãããªã©ãšããããšã¯ãããŸãããå ã»ã©ã®ãããªç°¡åãªãã®ãªãå¥ã«æ§ããªãã®ã§ããããã£ãšå€§ããªã©ã€ãã©ãªã®å Žåã¯ãœãŒã¹ã³ãŒãããã®åœ¹å²ããšã«å¥ã ã®ãã£ã¬ã¯ããªã«çœ®ããŠãããªããšãããããããªãããšã«ãªããŸãã
ã¹ãããïŒã®äŸã®ãã£ã¬ã¯ããªæ§æãäžèšã®ããã«èŠãªããããã®ã䜿ã£ãŠè§£èª¬ããŸãã
.
âââ include/
â âââ hello.hpp
â âââ good_morning.hpp
âââ src/
â âââ hello.cpp
â âââ good_morning.cpp
âââ test/
âââ main.cpp
ã³ãã³ãã©ã€ã³ããã³ã³ãã€ã«
ããŠããããã³ãã³ãã©ã€ã³ãããã«ãããŠã¿ãŸããããã«ãŒããã£ã¬ã¯ããªçŽäžã«ãããã®ãšããå ±æã©ã€ãã©ãªãäœæããŠå®è¡ãã¡ã€ã«ã«ãªã³ã¯ããããæ¹ããšããŸãã
$ cd src
$ g++ -fPIC -c hello.cpp good_morning.cpp -I../include
$ g++ -shared *.o -o libgreetings.so
$ cd ../test
$ g++ main.cpp -I../include -L../src -lgreetings -Xlinker -rpath -Xlinker ../src
ã¹ãããïŒãšç°ãªããä»åºŠã¯-Lãªãã·ã§ã³ã«å ããŠ-Iãªãã·ã§ã³ã§ã€ã³ã¯ã«ãŒããã¡ã€ã«ãæ¢ããã£ã¬ã¯ããªãæå®ããå¿
èŠããããŸããã¹ãããïŒã§-Iãªãã·ã§ã³ãå¿
èŠãªãã£ãã®ã¯ãã«ã¬ã³ããã£ã¬ã¯ããªã¯ããã©ã«ãã§ã€ã³ã¯ã«ãŒããã¡ã€ã«ãæ¢ãå ŽæãšããŠèªèãããããã§ãã
ãã£ã¬ã¯ããªæ§æã¯ä»¥äžã®ããã«ãªããŸãã
.
âââ include/
â âââ hello.hpp
â âââ good_morning.hpp
âââ src/
â âââ hello.cpp
â âââ hello.o
â âââ good_morning.cpp
â âââ good_morning.o
â âââ libgreetings.so
âââ test/
âââ a.out
âââ main.cpp
CMakeã䜿ã£ãŠã¿ã
ããŠããµããã£ã¬ã¯ããªãååšããå Žåãåãã£ã¬ã¯ããªããšã«CMakeLists.txtãäœããŸãã
.
âââ CMakeLists.txt
âââ include/
â âââ hello.hpp
â âââ good_morning.hpp
âââ src/
â âââ CMakeLists.txt
â âââ hello.cpp
â âââ good_morning.cpp
âââ test/
âââ CMakeLists.txt
âââ main.cpp
ã«ãŒããã£ã¬ã¯ããªã«ããCMakeLists.txtã§ã¯ãµããã£ã¬ã¯ããªã®ç»é²ãããŸãã
cmake_minimum_required(VERSION 3.13)
project(test_cmake CXX)
# ãµããã£ã¬ã¯ããªãç»é²
add_subdirectory(src)
add_subdirectory(test)
/src/CMakeLists.txtããã³/test/CMakeLists.txtã§ã¯ããããã®ãã£ã¬ã¯ããªã«ãããã¡ã€ã«ã®ã³ã³ãã€ã«æ¹æ³ãæå®ããŠãããŸãã
add_library(greetings
SHARED
hello.cpp
good_morning.cpp
)
# greetingã©ã€ãã©ãªã®ã€ã³ã¯ã«ãŒããã£ã¬ã¯ããªãæããŠããã
# PROJECT_SOURCE_DIRã¯ãã®ãããžã§ã¯ãã®ã«ãŒããã£ã¬ã¯ããªã®çµ¶å¯Ÿãã¹
target_include_directories(greetings
PUBLIC ${PROJECT_SOURCE_DIR}/include
)
add_executable(a.out main.cpp)
# a.outãã³ã³ãã€ã«ããéã«greetingsããªã³ã¯ãã
target_link_libraries(a.out greetings)
add_libraryããã³add_executableã®æåã®å€æ°ããã¿ãŒã²ããããšåŒã³ãŸãã
ããŒã¯ãŒãPRIVATE/PUBLIC/INTERFACEã®æå³ã¯ãã¿ãŒã²ããïŒgreetingsïŒã®ã¿ã«å¿
èŠïŒ=PRIVATEïŒãªã®ããã¿ãŒã²ããïŒgreetingsïŒããã³ããã«äŸåããã¿ãŒã²ããïŒa.outïŒã«ãå¿
èŠïŒ=PUBLICïŒãªã®ãããããã¯ã¿ãŒã²ããã«ã¯å¿
èŠãªããããã«äŸåããã¿ãŒã²ããã«ã¯å¿
èŠïŒ=INTERFACEïŒãªã®ããæããŸãã
| ããŒã¯ãŒã | ã¿ãŒã²ããã«å¿ èŠ | ãã®ã¿ãŒã²ããã«äŸåããã¿ãŒã²ããã«å¿ èŠ |
|---|---|---|
| PRIVATE | ||
| PUBLIC | ||
| INTERFACE |
ãã®å Žåãã€ã³ã¯ã«ãŒããã£ã¬ã¯ããª${PROJECT_SOURCE_DIR}/includeã¯greetingsã®ã³ã³ãã€ã«ã ãã§ãªããa.outã®ã³ã³ãã€ã«ã«ãå¿
èŠãªãããPUBLICãæå®ããŸãã
INTERFACEã¯ããããŒã®ã¿ã®ã©ã€ãã©ãªã«å¯ŸããŠäœ¿ããŸãã
ããŠããã§æºåã¯å®äºã§ããä»ãŸã§ãšåæ§ã«buildãã£ã¬ã¯ããªãäœæããŠcmakeãå®è¡ããŠãã«ãããããšãã§ããŸãã