DrawingProcess
๋“œํ”„ DrawingProcess
DrawingProcess
์ „์ฒด ๋ฐฉ๋ฌธ์ž
์˜ค๋Š˜
์–ด์ œ
ยซ   2025/06   ยป
์ผ ์›” ํ™” ์ˆ˜ ๋ชฉ ๊ธˆ ํ† 
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
  • ๋ถ„๋ฅ˜ ์ „์ฒด๋ณด๊ธฐ (964)
    • Profile & Branding (22)
      • Career (15)
    • IT Trends (254)
      • Conference, Faire (Experien.. (31)
      • News (187)
      • Youtube (19)
      • TED (8)
      • Web Page (2)
      • IT: Etc... (6)
    • Contents (97)
      • Book (66)
      • Lecture (31)
    • Project Process (94)
      • Ideation (0)
      • Study Report (34)
      • Challenge & Award (22)
      • 1Day1Process (5)
      • Making (5)
      • KRC-FTC (Team TC(5031, 5048.. (10)
      • GCP (GlobalCitizenProject) (15)
    • Study: ComputerScience(CS) (72)
      • CS: Basic (9)
      • CS: Database(SQL) (5)
      • CS: Network (14)
      • CS: OperatingSystem (3)
      • CS: Linux (39)
      • CS: Etc... (2)
    • Study: Software(SW) (95)
      • SW: Language (29)
      • SW: Algorithms (1)
      • SW: DataStructure & DesignP.. (1)
      • SW: Opensource (15)
      • SW: Error Bug Fix (43)
      • SW: Etc... (6)
    • Study: Artificial Intellige.. (149)
      • AI: Research (1)
      • AI: 2D Vision(Det, Seg, Tra.. (35)
      • AI: 3D Vision (70)
      • AI: MultiModal (3)
      • AI: SLAM (0)
      • AI: Light Weight(LW) (3)
      • AI: Data Pipeline (7)
      • AI: Machine Learning(ML) (1)
    • Study: Robotics(Robot) (33)
      • Robot: ROS(Robot Operating .. (9)
      • Robot: Positioning (8)
      • Robot: Planning & Control (7)
    • Study: DeveloperTools(DevTo.. (83)
      • DevTool: Git (12)
      • DevTool: CMake (13)
      • DevTool: NoSQL(Elastic, Mon.. (25)
      • DevTool: Container (17)
      • DevTool: IDE (11)
      • DevTool: CloudComputing (4)
    • ์ธ์ƒ์„ ์‚ด๋ฉด์„œ (64)
      • ๋‚˜์˜ ์ทจ๋ฏธ๋“ค (7)
      • ๋‚˜์˜ ์ƒ๊ฐ๋“ค (42)
      • ์—ฌํ–‰์„ ๋– ๋‚˜์ž~ (10)
      • ๋ถ„๊ธฐ๋ณ„ ํšŒ๊ณ  (5)

๊ฐœ๋ฐœ์ž ๋ช…์–ธ

โ€œ ๋งค์ฃผ ๋ชฉ์š”์ผ๋งˆ๋‹ค ๋‹น์‹ ์ด ํ•ญ์ƒ ํ•˜๋˜๋Œ€๋กœ ์‹ ๋ฐœ๋ˆ์„ ๋ฌถ์œผ๋ฉด ์‹ ๋ฐœ์ด ํญ๋ฐœํ•œ๋‹ค๊ณ  ์ƒ๊ฐํ•ด๋ณด๋ผ.
์ปดํ“จํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์ด๋Ÿฐ ์ผ์ด ํ•ญ์ƒ ์ผ์–ด๋‚˜๋Š”๋ฐ๋„ ์•„๋ฌด๋„ ๋ถˆํ‰ํ•  ์ƒ๊ฐ์„ ์•ˆ ํ•œ๋‹ค. โ€

- Jef Raskin

๋งฅ์˜ ์•„๋ฒ„์ง€ - ์• ํ”Œ์ปดํ“จํ„ฐ์˜ ๋งคํ‚จํ† ์‹œ ํ”„๋กœ์ ํŠธ๋ฅผ ์ฃผ๋„

์ธ๊ธฐ ๊ธ€

์ตœ๊ทผ ๊ธ€

์ตœ๊ทผ ๋Œ“๊ธ€

ํ‹ฐ์Šคํ† ๋ฆฌ

hELLO ยท Designed By ์ •์ƒ์šฐ.
DrawingProcess

๋“œํ”„ DrawingProcess

Study: DeveloperTools(DevTool)/DevTool: CMake

[CMake] An Introduction to Modern CMake ์ •๋ฆฌ

2022. 6. 24. 16:06
๋ฐ˜์‘ํ˜•
๐Ÿ’ก ๋ณธ ๋ฌธ์„œ๋Š” 'An Introduction to Modern CMake'์— ๋Œ€ํ•ด ์ •๋ฆฌํ•ด๋†“์€ ๊ธ€์ž…๋‹ˆ๋‹ค.
CMake๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋ถ€ํ„ฐ CMake์˜ ๊ตฌ์„ฑ ๋ฐ CMakeLists.txt ํŒŒ์ผ ์ž‘์„ฑ๋ฒ•๊นŒ์ง€ ๋‹ค๋ฃจ๊ณ  ์žˆ์œผ๋‹ˆ CMake๋ฅผ ์ž…๋ฌธํ•˜์—ฌ ํ™œ์šฉํ•˜๋Š” ์ž…์žฅ์—์„œ ๋งŽ์€ ๋„์›€์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

1. CMake ๋ž€

1.1 CMake ๋„์ž…

CMake๋Š” Kitware์—์„œ ๊ฐœ๋ฐœํ•˜๊ณ  ์žˆ์œผ๋ฉฐ, cmake.org์—์„œ ํ•™์Šตํ•˜๊ณ  ๋‹ค์šด๋กœ๋“œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ „ํ†ต์ ์ธ C/C++ ๋นŒ๋“œ ๋„๊ตฌ๋Š” make์ž…๋‹ˆ๋‹ค. make๋Š” Makefile์„ ์ž‘์„ฑํ•ด ์ฃผ์–ด์•ผ ํ•˜๋Š”๋ฐ, Makefile ์ž‘์„ฑ์‹œ ์˜์กด๊ด€๊ณ„๋ฅผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๊ธฐ์ˆ ํ•ด์•ผ ํ•˜๋ฉฐ, ๊ฐœ๋ฐœ์ž๋Š” ์ •ํ™•ํ•œ ์˜์กด์„ฑ์„ ์œ„ํ•ด ์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋“ค์—ฌ๋‹ค๋ณด๋ฉฐ ๋งŽ์€ ๋…ธ๋™์„ ํˆฌ์ž…ํ•˜์—ฌ ์ž‘์„ฑํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Makefile ์ž‘์„ฑ์‹œ ์‹ค์ˆ˜๋กœ ์˜์กด๊ด€๊ณ„๋ฅผ ๋น ๋œจ๋ฆฌ๋ฉด ๋ณ€๊ฒฝ์ด ์—…๋ฐ์ดํŠธ ๋˜์ง€ ์•Š๊ฑฐ๋‚˜, ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋‚˜ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜๋Š” ๊ทธ ์›์ธ์„ ํŒŒ์•…ํ•˜๊ธฐ๋„ ์–ด๋ ต์Šต๋‹ˆ๋‹ค. make ์‚ฌ์šฉ์‹œ clean ๊ตฌ์„ฑ์„ ์ž์ฃผ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ํ•˜๋Š” ์ด์œ ๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

CMake๋Š” ์†Œ์ŠคํŒŒ์ผ์„ ํŒŒ์‹ฑํ•˜์—ฌ ์˜์กด๊ด€๊ณ„๋ฅผ ํŒŒ์•…ํ•˜์—ฌ ์ž๋™์œผ๋กœ Makefile๋“ค์ด ์ž‘์„ฑ๋˜๋„๋ก ๋•๋Š” ๊ฒƒ์ด 1์ฐจ ๋ชฉํ‘œ ์ž…๋‹ˆ๋‹ค.

1.2 CMake ๋‹จ๊ณ„

CMake๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ cmake์— ์˜ํ•ด CMakeLists.txt๋ฅผ ํŒŒ์‹ฑํ•˜๊ฑฐ๋‚˜ Makefile๋“ค์„ ์ƒ์„ฑํ•˜๋Š” ๊ตฌ์„ฑ(Configure) ๋‹จ๊ณ„์™€, make์— ์˜ํ•œ ๋นŒ๋“œ (Build) ๋‹จ๊ณ„ + ์„ค์น˜(install) ๋‹จ๊ณ„๋กœ ๋‚˜๋ˆ  ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Configure ๋‹จ๊ณ„: CMakeLists.txt๋ฅผ ํŒŒ์‹ฑํ•˜๊ณ  ์‹คํ–‰ํ•˜์—ฌ Makefile ์ด๋‚˜ Ninja, vsproj๋“ฑ์„ ์ƒ์„ฑํ•˜๋Š” ๋‹จ๊ณ„์ด๋ฉฐ, ์ด ํŒŒ์ผ๋“ค์„ ์ž๋™์œผ๋กœ ๊ตฌ์„ฑํ•˜๋Š” ๊ฒƒ์ด cmake์˜ ๊ธฐ๋ณธ ๋ชฉํ‘œ ์ž…๋‹ˆ๋‹ค. ์ด ๊ธ€์€ Makefile๋งŒ์„ ๊ตฌ์„ฑํ•˜๋Š” ๊ณผ์ •์„ ๋‹ค๋ฃน๋‹ˆ๋‹ค.

  • cmake ..: CMakeLists.txt -> Cmake๋ฅผ ์ด์šฉํ•˜์—ฌ Makefile ์ƒ์„ฑ

build ๋‹จ๊ณ„: ๋‹ค๋ฅธ ์™ธ๋ถ€ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Makefile์„ ์ƒ์„ฑํ•˜์˜€์œผ๋ฉด make๋ฅผ ์‹คํ–‰ ํ•ฉ๋‹ˆ๋‹ค.

  • make: Makefile์„ ์ด์šฉํ•˜์—ฌ ์‹คํ–‰ ํŒŒ์ผ ์ƒ์„ฑ.

install ๋‹จ๊ณ„: 

  • sudo make install: 

+ ๋นŒ๋“œ ์˜ต์…˜ (CMAKE_BUILD_TYPE)

๋‹ค์–‘ํ•œ ๋ชจ๋“œ์˜ ๋นŒ๋“œ์˜ต์…˜์œผ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ ํƒํ•œ ๋นŒ๋“œ์˜ต์…˜์— ๋”ฐ๋ผ ์ปดํŒŒ์ผ ๋ฐ ๋งํฌ ์˜ต์…˜์ด ์ถ”๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.

  • Debug(`-O0 -g`): ๋””๋ฒ„๊น…์„ ์œ„ํ•œ ๋นŒ๋“œ.
    • No optimization, asserts enabled, [custom debug (output) code enabled], debug info included in executable (so you can step through the code with a debugger and have address to source-file:line-number translation).
  • Release(`-O3 -DNDEBUG`): ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ ๋นŒ๋“œ.
    • high optimization level, no debug info, code or asserts.
  • RelWithDebInfo(`-O2 -g -DNDEBUG`): ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ ๋นŒ๋“œ์ด์ง€๋งŒ ๋””๋ฒ„๊น… ์ •๋ณด ํฌํ•จ.
    • optimized, *with* debug info, but no debug (output) code or asserts.
  • MinSizeRel(`-Os -DNDEBUG`): ๋ฐฐํฌ๋ฅผ ์œ„ํ•œ ๋นŒ๋“œ์ธ๋ฐ ์ตœ์†Œ ํฌ๊ธฐ๋กœ ์ตœ์ ํ™”.
    • same as Release but optimizing for size rather than speed.

2. CMake ์‹คํ–‰ํ•˜๊ธฐ: CMakeLists.txt

2.1 CMake ์‹คํ–‰ํ•˜๊ธฐ: Make ๋นŒ๋“œ ์‹œ์Šคํ…œ ์ด์šฉ

CMake ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ํ”„๋กœ์ ํŠธ์—๋Š” ๋ฐ˜๋“œ์‹œ ํ”„๋กœ์ ํŠธ ์ตœ์ƒ์œ„ ๋””๋ ‰ํ† ๋ฆฌ์— *CMake ํŒŒ์ผ์ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„œ CMake ํŒŒ์ผ์€ ๋Œ€๋ถ€๋ถ„ 'CMakeLists.txt' ๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์ž‘์„ฑํ•˜๋ฉฐ, ๋นŒ๋“œ ํŒŒ์ผ์„ ์ƒ์„ฑํ•˜๋Š”๋ฐ ํ•„์š”ํ•œ ์ •๋ณด๋“ค์ด ๋“ค์–ด ์žˆ์Šต๋‹ˆ๋‹ค.  

์ปดํŒŒ์ผ ๊ณผ์ •: CMakeLists.txt -> Cmake๋ฅผ ์ด์šฉํ•˜์—ฌ Makefile ์ƒ์„ฑ -> Makefile์„ ์ด์šฉํ•˜์—ฌ ์‹คํ–‰ ํŒŒ์ผ ์ƒ์„ฑ.

// ํ”„๋กœ์ ํŠธ์˜ ์ตœ์ƒ๋‹จ CMakeLists.txt 
$ mkdir build; cd build
$ cmake ..
$ make
์ฃผ์˜!!!: ๋ฐ˜๋“œ์‹œ ๋นŒ๋“œ ํŒŒ์ผ ์šฉ ๋””๋ ‰ํ† ๋ฆฌ(/build)๋ฅผ ๋งŒ๋“  ๋‹ค์Œ์— ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ์—์„œ CMake ๋ฅผ ์‹คํ–‰ํ•ฉ์‹œ๋‹ค.
CMake ๋Š” ์‹คํ–‰์‹œ ์—ฌ๋Ÿฌ๊ฐ€์ง€ ํŒŒ์ผ๋“ค (์บ์‹œ ์šฉ๋„๋กœ) ์„ ์ƒ์„ฑํ•˜๋Š”๋ฐ ์ด ๋•Œ๋ฌธ์— ํ”„๋กœ์ ํŠธ ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ๋‚œ์žฅํŒ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

2.1.1 CMakeList.txt ๋ณ€๊ฒฝ ํ›„ ์žฌ๋นŒ๋“œ: rm build/CMakeCache.txt

// pwd: ํ”„๋กœ์ ํŠธ์˜ ์ตœ์ƒ๋‹จ์˜ CMakeLists.txtํŒŒ์ผ์ด ์žˆ๋Š” ๊ณณ
$ cd build
$ rm CMakeCache.txt
  • CMakeCache.txt๋งŒ ์ง€์›Œ์ ธ๋„ cmake .. ์‹œ ์žฌ๋นŒ๋“œ๋จ.

2.1.2 CMakeList.txt ์ด์™ธ์˜ ํŒŒ์ผ ๋ณ€๊ฒฝ ํ›„ ์žฌ๋นŒ๋“œ: make clean

// pwd: ํ”„๋กœ์ ํŠธ์˜ ์ตœ์ƒ๋‹จ์˜ CMakeLists.txtํŒŒ์ผ์ด ์žˆ๋Š” ๊ณณ
$ cd build
$ make clean

makefile๋‚ด์— clean ์˜ต์…˜์œผ๋กœ clean์‹œ ์‚ญ์ œ๋  ํŒŒ์ผ์„ ๋ช…์‹œํ•ฉ๋‹ˆ๋‹ค.

all: $(BUILD) 
clean: ; rm -f *.o $(BUILD)

2.2 CMake: Make ์ด์™ธ์˜ ๋นŒ๋“œ ์‹œ์Šคํ…œ ์ด์šฉ

CMake ์—์„œ ๋”ฐ๋กœ ์„ค์ •ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด ๋””ํดํŠธ๋กœ make ๊ฐ€ ์„ ํƒ๋˜์ง€๋งŒ ๊ฒฝ์šฐ์— ๋”ฐ๋ผ ๋นŒ๋“œ ์‹œ์Šคํ…œ์— ๋งž๋Š” ๋‹ค๋ฅธ ๋นŒ๋“œ ํ”„๋กœ๊ทธ๋žจ(sln, vcxproj, MakeFiles, ninja ...)์„ ์„ ํƒํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. 

$ cmake .. -DCMAKE_GENERATOR=Ninja

์œ„ CMAKE_GENERATOR ์ธ์ž๋กœ ์›ํ•˜๋Š” ๋นŒ๋“œ ์‹œ์Šคํ…œ์„ ํ˜ธ์ถœํ•˜๋„๋ก ์ „๋‹ฌํ•˜๋ฉด ๋˜๋Š”๋ฐ, ์ „์ฒด ๋ชฉ๋ก์€ ์—ฌ๊ธฐ ์—์„œ ๋ณด์‹ค ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋Œ€ํ‘œ์ ์œผ๋กœ...

  • "Unix Makefiles" (๋””ํดํŠธ)
  • "Ninja"
  • "Visual Studio 16 2019"

+ ๋นŒ๋“œ ์‹œ์Šคํ…œ/ํˆด์ฒด์ธ ์ง€์ •

ํˆด์ฒด์ธ ํŒŒ์ผ: CMake๊ฐ€ ์ง€์›ํ•˜๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ๋“ค์„ ์‚ฌ์šฉํ•ด ๋นŒ๋“œ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋ฏธ๋ฆฌ ์ง€์ •๋œ ํŒŒ์ผ์„ ์˜๋ฏธํ•ฉ๋‹ˆ๋‹ค.

cmake --build . # ... ์ง€์ •๋œ ํˆด์„ ์‚ฌ์šฉํ•ด ๋นŒ๋“œ๋ฅผ ์ง„ํ–‰ํ•œ๋‹ค ...
cmake --build . --parallel          # ๋ณ‘๋ ฌ ๋นŒ๋“œ
cmake --build . --target install    # ๋นŒ๋“œ์— ์„ฑ๊ณตํ•˜๋ฉด ์„ค์น˜๊นŒ์ง€ ์ง„ํ–‰ํ•œ๋‹ค
cmake --build . --config debug      # Debug๋กœ ๋นŒ๋“œ
  • Android NDK์—์„œ๋Š” ์—ฌ๋Ÿฌ ์•„ํ‚คํ…์ฒ˜๋กœ์˜ ํฌ๋กœ์Šค ์ปดํŒŒ์ผ์— ํ•„์š”ํ•œ ์„ค์ •๋“ค์ด ์ž‘์„ฑ๋œ android.toolchain.cmake ํŒŒ์ผ์ด ํ•จ๊ป˜ ์ œ๊ณต๋˜๋ฉฐ, CMake๋ฅผ ์‚ฌ์šฉํ•œ ๋นŒ๋“œ๋ฅผ ์ˆ˜ํ–‰์‹œ์— Gradle์— ์˜ํ•ด์„œ ์ž๋™์œผ๋กœ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
  • iphone์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” https://github.com/leetal/ios-cmake ๋ฅผ ์‚ฌ์šฉํ•ด XCode ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹ค๋ฅด๊ฒŒ๋Š” https://github.com/Microsoft/vcpkg ์™€ ๊ฐ™์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํƒ์ƒ‰์— ํŠนํ™”๋œ ํˆด์ฒด์ธ ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
# ... Vcpkg์—์„œ ์ œ๊ณตํ•˜๋Š” cmake ํˆด์ฒด์ธ์˜ ๊ฒฝ๋กœ๋กœ ์ œ๊ณตํ•œ๋‹ค ...
cmake ../ -G "Visual Studio 15 2017 Win64" -DCMAKE_TOOLCHAIN_FILE="X:\Develop\vcpkg\scripts\buildsystems\vcpkg.cmake"

3. CMake ๊ธฐ์ดˆ ๋ฌธ๋ฒ• ์ •๋ฆฌ

3.1 ํ•„์ˆ˜์ ์ธ CMake: ์ตœ์ƒ๋‹จ CMakeLists.txt ํŒŒ์ผ

์ตœ์†Œ ๋ฒ„์ „ ๋ช…๊ธฐ

๋ชจ๋“  CMake ํŒŒ์ผ์˜ ์ตœ์ƒ๋‹จ์—๋Š” ์ตœ์†Œ ๋ฒ„์ „์ด ๋ช…์‹œ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

cmake_minimum_required(VERSION 3.10)

ํ”„๋กœ์ ํŠธ ์„ค์ •

์ตœ์ƒ์œ„ CMake ํŒŒ์ผ์€ ๋‹ค์Œ ๋‚ด์šฉ์„ ํฌํ•จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

project(MyProject VERSION 1.0
                  DESCRIPTION "Very nice project"
                  LANGUAGES CXX)
  • ์ŠคํŠธ๋ง์€ ““ ์ฒ˜๋ฆฌ
  • ๊ณต๋ฐฑ๋ฌธ์ž๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ€์ง€์ง€ ์•Š์Œ
  • LANGUAGES ๋Š” C CXX๊ฐ€ default์ด๋ฉฐ, ๊ทธ ์™ธ์—๋„ CUDA, OBJC, OBJCXX, Fortran ๋“ฑ๋“ฑ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

์„ค์ • ํŒŒ์ผ

configure_file(TutorialConfig.h.in TutorialConfig.h)

configure file์„ ์ถ”๊ฐ€ํ–ˆ๋‹ค๋ฉด ๋ฐ˜๋“œ์‹œ include ๊ฒฝ๋กœ๋ฅผ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

target_include_directories(${PROJECT_NAME}
  PUBLIC
    ${PROJECT_BINARY_DIR}/include
)
  • configure_file์— ๋Œ€ํ•œ ์„ธ๋ถ€์ ์ธ ๋‚ด์šฉ์€ [CMake] configure_file(): CMake ๋ณ€์ˆ˜๊ฐ’์„ ํŒŒ์ผ์— ๋ฐ˜์˜!์„ ์ฐธ๊ณ ํ•˜๋„๋ก ํ•ฉ์‹œ๋‹ค.

๋นŒ๋“œ ๊ด€๊ณ„ ์„ค์ • (์˜์กด์„ฑ)

ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ ์—ฌ๋Ÿฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋นŒ๋“œํ•œ๋‹ค๋ฉด, ๊ทธ๋ฆฌ๊ณ  ์„œ๋กœ ์˜์กด์„ฑ์ด ์žˆ๋‹ค๋ฉด ์ด๋ฅผ ์ œ์–ดํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ณผ์ •์€ ๋ณดํ†ต ํ•ด๋‹น sub-project๋“ค์„ ๋ชจ๋‘ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋Š” CMakeList์—์„œ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

์•„๋ž˜์™€ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ํ”„๋กœ์ ํŠธ๊ฐ€ ๊ตฌ์„ฑ๋˜์—ˆ๋‹ค๊ณ  ๊ฐ€์ •ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

$ tree ./multiple-library-project
./multiple-library-project
โ”œโ”€โ”€ CMakeLists.txt      # <--- Root CMakeList
โ”œโ”€โ”€ include
โ”‚   โ””โ”€โ”€ ... 
โ”œโ”€โ”€ module1
โ”‚   โ”œโ”€โ”€ CMakeLists.txt
โ”‚   โ””โ”€โ”€ ... 
โ”œโ”€โ”€ module2
โ”‚   โ”œโ”€โ”€ CMakeLists.txt
โ”‚   โ””โ”€โ”€ ... 
โ””โ”€โ”€ test
    โ”œโ”€โ”€ CMakeLists.txt
    โ””โ”€โ”€ ...

์ƒ๋‹จ์˜ CMakeLists.txt ํŒŒ์ผ์—์„œ ํ•˜์œ„ ํด๋”(module1, module2, test)๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

# multiple-library-project/CMakeLists.txt
add_subdirectory(module1)
add_subdirectory(module2)
add_subdirectory(test)

module2๊ฐ€ module1์˜ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ณ , test๋Š” ์ด ๋‘˜์˜ ๊ธฐ๋Šฅ์„ ๋ชจ๋‘ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ์ด๋Š” Root CMake์—์„œ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋ช…์‹œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

# dependency: from -> { to }
add_dependencies(module1 module2)            # `module1` requires `module2`
add_dependencies(test    module1 module2)    # `test` requires `module1` & `module2`

์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ CMake์—์„œ ํ”„๋กœ์ ํŠธ๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด, ๊ทธ ํ”„๋กœ์ ํŠธ๋Š” ์˜์กด์„ฑ์„ ๊ณ ๋ คํ•˜์—ฌ module1, module2, test ์ˆœ์„œ๋กœ ๋นŒ๋“œ๋ฅผ ์ง„ํ–‰ํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

3.2 ํƒ€๊ฒŸ(target) & ์†์„ฑ(property)

  • target์ด๋ž€? ํ”„๋กœ๊ทธ๋žจ์„ ๊ตฌ์„ฑํ•˜๋Š” ์š”์†Œ๋“ค(์‹คํ–‰ํŒŒ์ผ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋“ฑ)
  • property๋ž€? ๊ฐ ํƒ€๊ฒŸ์— ๋Œ€ํ•œ ์†์„ฑ(์ปดํŒŒ์ผ ์˜ต์…˜, ๋งํ‚นํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ, includeํ•  ํŒŒ์ผ์˜ ์œ„์น˜ ๋“ฑ)
    • ๋ชจ๋“  CMake ๋ช…๋ น์€ ๊ทธ๋ƒฅ ํƒ€๊ฒŸ์„ ์ •์˜ํ•˜๊ณ  (add_executable), ํ•ด๋‹น ํƒ€๊ฒŸ๋“ค์˜ ์†์„ฑ์„ ์ง€์ •ํ•˜๋Š” ๋ช…๋ น๋“ค (target_compile_options) ๋กœ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. 

ํƒ€๊ฒŸ(Target): ์‹คํ–‰ ํŒŒ์ผ ์ƒ์„ฑ

add_executable(one two.cpp three.h)
  • ์ดํ›„์— ๋‚˜์˜ค๋Š” .cpp ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ด ์‹คํ–‰ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ์‹คํ–‰ํŒŒ์ผ๋ช…, ์†Œ์Šค๋ช… ์ˆœ์œผ๋กœ ๊ธฐ์žฌํ•ฉ๋‹ˆ๋‹ค.
  • ์†Œ์Šค๋Š” ๋ณต์ˆ˜ ๊ฐœ๋ฅผ ๊ธฐ์žฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํ—ค๋”๋Š” ๋ฌด์‹œ๋˜์ง€๋งŒ, ํŠน์ • IDE๋Š” ํ—ค๋”๊ฐ€ ๋ช…์‹œ๋˜์–ด ์žˆ์–ด์•ผ ์ธ์‹ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ•„์š”์— ๋”ฐ๋ผ ๊ธฐ์žฌํ•ฉ๋‹ˆ๋‹ค.

ํƒ€๊ฒŸ(Target): ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ƒ์„ฑ

add_library(one STATIC two.cpp three.h)
  • add_executable๊ณผ ๊ฐ™์ด ๋งจ ์ฒ˜์Œ์—๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ช…์„ ๊ธฐ์žฌํ•˜๋ฉฐ, ์ดํ›„์— ๋‚˜์˜ค๋Š” .cpp ํŒŒ์ผ์„ ์‚ฌ์šฉํ•ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” STATIC, SHARED, MODULE์„ ํ†ตํ•ด ์„ ์–ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 
    • STATIC: ์ •์  ๋งํ‚น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (*.a, *.lib)
      • ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ํŒŒ์ผ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฝ”๋“œ๊ฐ€ ์ „๋ถ€ ๋“ค์–ด ์žˆ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.
    • SHARED: ๋™์  ๋งํ‚น ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ (*.so, *.dll)
      • ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰ ํŒŒ์ผ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ํฌํ•จ๋˜์–ด ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ๋ฉ”๋ชจ๋ฆฌ์— ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ๋”ฐ๋กœ ์˜ฌ๋ผ๊ฐ€๋Š”๋ฐ ์ด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค.
    • MODULE: ๋™์ ์œผ๋กœ ๋งํฌ๋˜์ง€๋Š” ์•Š์ง€๋งŒ, dlopen ๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜๋กœ ๋Ÿฐํƒ€์ž„ ์‹œ์— ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.
  • ์ฐธ๊ณ ๋กœ CMake ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ค๊ฒŒ ๋˜๋ฉด ์•ž์— lib์„ ๋ถ™์ธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํŒŒ์ผ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

+ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ณ„์นญ ์ƒ์„ฑ: ๊ด€๋ฆฌ ์šฉ์ด

add_library(project::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
  • ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๊ฐ€๊ธ‰์  ALIAS๋ฅผ ์ถ”๊ฐ€ํ•˜์—ฌ ์ƒ์šฉ *์จ๋“œํŒŒํ‹ฐ ์ œํ’ˆ๊ณผ ๊ฐ™์€ ํ˜•ํƒœ๋กœ ๊ด€๋ฆฌํ•ด์ฃผ์„ธ์š”. 
    *์จ๋“œํŒŒํ‹ฐ: ๋‹ค๋ฅธ ํšŒ์‚ฌ ์ œํ’ˆ์— ์ด์šฉ๋˜๋Š” ์†Œํ”„ํŠธ์›จ์–ด
์ฃผ์˜!!!: ์˜›๋‚  ๋ฒ„์ „์˜ CMake ์—์„œ๋Š” ์•ž์— *target_ ์ด ๋น ์ง„ include_directories, link_directories ์™€ ๊ฐ™์€ ๋ช…๋ น๋“ค์ด ์‚ฌ์šฉ๋˜์—ˆ๋Š”๋ฐ ์ด๋Š” ์ตœ์‹ ์˜ CMake ์—์„œ๋Š” ์‚ฌ์šฉ์ด ๊ถŒ์žฅ๋˜์ง€ ์•Š๋Š” ๋ช…๋ น๋“ค ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ์˜ Modern CMake ํŒจ๋Ÿฌ๋‹ค์ž„์€ ํƒ€๊ฒŸ๋“ค์„ ๊ธฐ์ค€์œผ๋กœ ๋Œ์•„๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ๊ผญ target_* ํ˜•ํƒœ์˜ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๋„๋ก ํ•ฉ์‹œ๋‹ค.

+ ์ผ๋ถ€ ํŒŒ์ผ๋กœ ์‹คํ–‰ํŒŒ์ผ ์ƒ์„ฑํ•˜๊ธฐ (target_sources)

  • add_executable๊ณผ add_library์˜ ํ•œ๊ณ„๋Š” ์†Œ์Šค ํŒŒ์ผ ๋ชฉ๋ก์„ ํ•œ๋ฒˆ์— ๊ฒฐ์ •ํ•ด์„œ ์ „๋‹ฌํ•ด์•ผ ํ•œ๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. 
  • ์ด๋Š” Target๋“ค์ด CMakeList ํŒŒ์ผ์˜ ๋๋ถ€๋ถ„์— ๋‚˜ํƒ€๋‚˜๊ฒŒ ๋งŒ๋“ค๋ฉฐ, 2.x ๋ฒ„์ „ CMake๋“ค์ด ์‚ฌ์šฉํ–ˆ๋˜ ๋ฐฉ๋ฒ•์ฒ˜๋Ÿผ List ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด ์†Œ์ŠคํŒŒ์ผ ๋ชฉ๋ก์„ ๋งŒ๋“ค์–ด์•ผ ํ•˜๋Š” ๋ถˆํŽธํ•จ์ด ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ, CMake 3.x์—์„œ๋Š” Target์— ์†Œ์ŠคํŒŒ์ผ์„ '์ถ”๊ฐ€'ํ•  ์ˆ˜ ์žˆ๋„๋ก target_sources๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
# preview ๊ฐ€ ๊ตฌํ˜„๋œ ์†Œ์ŠคํŒŒ์ผ์„ ์ถ”๊ฐ€ํ• ์ง€ ๊ฒฐ์ •ํ•˜๋Š” ๋ณ€์ˆ˜
set(USE_PREVIEW true)

# target: my_program
add_executable(my_program
    main.cpp
    feature1.cpp
)

target_sources(my_program
PRIVATE
    feature2.cpp
)
if(USE_PREVIEW)
    target_sources(my_program
    PRIVATE
        feature3_preview.cpp
    )
else()

+ ํŠน์ • ์œ„์น˜์˜ ํŒŒ์ผ ์ผ๊ด„ ์ถ”๊ฐ€: include srcs

file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS
  ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
)

add_library(shape STATIC ${SRC_FILES})
  • GLOB_RECURSE: ๋งŒ์ผ ํ•˜์œ„ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ํฌํ•จํ•˜๊ณ  ์‹ถ์ง€ ์•Š๋‹ค๋ฉด GLOB_RECURSE ๋Œ€์‹ ์— GLOB ์„ ์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.
  • SRC_FILES: ๋ช…๋ น ๋‚ด ํฌํ•จ๋œ ํŒŒ์ผ๋“ค์„ ๋ชจ๋‘ ๋ชจ์•„์„œ SRC_FILES ๋ผ๋Š” ๋ณ€์ˆ˜๋ฅผ ๊ตฌ์„ฑํ•˜๋ผ๋Š” ์˜๋ฏธ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
  • CONFIGURE_DEPENDS: ๋งŒ์•ฝ์— GLOB ์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ค๋Š” ํŒŒ์ผ ๋ชฉ๋ก์ด ์ด์ „๊ณผ ๋‹ค๋ฅผ ๊ฒฝ์šฐ (์˜ˆ๋ฅผ ๋“ค์–ด์„œ ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•˜๊ฑฐ๋‚˜ ์ง€์› ์„ ๋•Œ) CMake ๋ฅผ ๋‹ค์‹œ ์‹คํ–‰ํ•ด์„œ ๋นŒ๋“œ ํŒŒ์ผ์„ ์žฌ์ƒ์„ฑ ํ•˜๋ผ๋Š” ์˜๋ฏธ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
    • ๋งŒ์•ฝ์— ๋””๋ ‰ํ† ๋ฆฌ ์•ˆ์— ํŒŒ์ผ์ด ์ถ”๊ฐ€ ๋˜๋”๋ผ๋„, cmake .. ์„ ๋‹ค์‹œ ์‹คํ–‰ํ•  ํ•„์š” ์—†์ด ๊ทธ๋ƒฅ make ๋งŒ ์‹คํ–‰ํ•ด๋„ CMake ๊ฐ€ ๋‹ค์‹œ ์‹คํ–‰๋˜๋ฉด์„œ ๋นŒ๋“œ ํŒŒ์ผ์„ ์žฌ์ž‘์„ฑ ํ•ฉ๋‹ˆ๋‹ค. 
์ฐธ์กฐ!!: CMake ์—์„œ ๋ชจ๋“  ๋ณ€์ˆ˜๋“ค์€ ${๋ณ€์ˆ˜ ์ด๋ฆ„} ๊ณผ ๊ฐ™์€ ์‹์œผ๋กœ ์ฐธ์กฐํ•ฉ๋‹ˆ๋‹ค. 
make ์™€ ๋น„์Šทํ•œ๋ฐ, make ๋Š” ์†Œ๊ด„ํ˜ธ () ๋กœ ๊ฐ์‹ธ์ฃผ๋Š” ๋ฐ˜๋ฉด CMake ๋Š” ์ค‘๊ด„ํ˜ธ {} ๋กœ ๊ฐ์‹ธ์ค๋‹ˆ๋‹ค.
+ ${CMAKE_CURRENT_SOURCE_DIR}: CMakeLists.txt ๊ฐ€ ์œ„์น˜ํ•œ ๋””๋ ‰ํ† ๋ฆฌ, ์ฆ‰ ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์˜๋ฏธ ํ•ฉ๋‹ˆ๋‹ค.

์†์„ฑ(Property): compile options

target_compile_options(program PRIVATE -Wall -Werror)
  • -Wall : ๋ชจ๋“  ๊ฒฝ๊ณ ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.
  • -Werror : ๊ฒฝ๊ณ ๋Š” ์ปดํŒŒ์ผ ์˜ค๋ฅ˜๋กœ ๊ฐ„์ฃผํ•ฉ๋‹ˆ๋‹ค.

+ include(CheckCXXCompilerFlag)

์ปดํŒŒ์ผ๋Ÿฌ ์˜ต์…˜์„ ์ง€์ •ํ•ด์ฃผ๊ธฐ ์ „์—, ์ปดํŒŒ์ผ๋Ÿฌ๊ฐ€ ํ•ด๋‹น ์˜ต์…˜์„ ์ง€์›ํ•˜๋Š”์ง€ ๊ฒ€์‚ฌ๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๋„ ์žˆ์Šต๋‹ˆ๋‹ค. CMake์˜ ๊ธฐ๋ณธ ๋ชจ๋“ˆ๋“ค ์ค‘์—๋Š” ์ด๋ฅผ ์ง€์›ํ•˜๋Š” CheckCXXCompilerFlag๋ผ๋Š” ๋ชจ๋“ˆ์ด ์žˆ์œผ๋ฉฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค.

include(CheckCXXCompilerFlag)

check_cxx_compiler_flag(/std:c++latest  cxx_latest)
check_cxx_compiler_flag(-Wall           high_warning_level)
  • ์ถ”๊ฐ€์ ์ธ ์ปดํŒŒ์ผ ๊ด€๋ จ ๋‚ด์šฉ์€ [Github]CMake ํ• ๋•Œ ์ชผ์˜ค์˜ค๊ธˆ ๋„์›€์ด ๋˜๋Š” ๋ฌธ์„œ ๋ฅผ ์ฐธ๊ณ ํ•˜๋„๋ก ํ•ฉ์‹œ๋‹ค.

์†์„ฑ(Property):  include directories

target_include_directories(one PUBLIC include)

์ƒ๊ธฐ ๋ช…๋ น์–ด๋Š” ํƒ€๊ฒŸ์— ํฌํ•จํ•  ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค(๋Œ€์ฒด๋กœ ํ—ค๋”ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•œ๋‹ค).

  • PUBLIC: ๋ณธ ํƒ€๊ฒŸ์— ์˜์กดํ•˜๋Š” ํƒ€๊ฒŸ๋“ค๋„ ํ•ด๋‹น ๋””๋ ‰ํ† ๋ฆฌ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์˜์กด์„ฑ ์ „ํŒŒ).
  • PRAIVATE: ๋ณธ ํƒ€๊ฒŸ์—๋งŒ ํฌํ•จํ•ด์•ผ ํ•˜๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์—์„  ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

์†์„ฑ(Property): link library

target_link_libraries๋ฅผ ํ†ตํ•ด ํƒ€๊ฒŸ์— ์˜์กด๋˜์–ด ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋ช…์‹œํ•˜๋ฉฐ, ์ฃผ๋กœ ๋‚ด๋ถ€์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋‚˜ FetchContent๋ฅผ ํ†ตํ•ด ๋ฐ›์•„์˜จ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งํ‚นํ•  ๋•Œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

#FetchContent๋กœ ๋ฐ›์€ spdlog์™€ jsoncpp๋ฅผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋งํ‚น ์ž‘์—…(์˜์กด์„ฑ ์„ค์ •)
target_link_libraries(${PROJECT_NAME}
  PUBLIC
    spdlog::spdlog jsoncpp_static
  PRIVATE
    utf8proc
)

๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์—์„œ ์ƒ๊ธฐ์˜ ${PROJECT_NAME}์— ํ•ด๋‹นํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งํ‚นํ•œ ๊ฒฝ์šฐ... 

  • PUBLIC: ํ—ค๋”ํŒŒ์ผ์„ includeํ•˜๊ธฐ ์œ„ํ•œ ๊ฒฝ๋กœ์™€ ๋นŒ๋“œ ๊ฒฐ๊ณผ ์ƒ์„ฑ๋˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • PRAIVATE: ํ•ด๋‹น ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€ํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ๋‹ค๋ฅธ ํ”„๋กœ์ ํŠธ์—์„  ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
  • INTERFACE: ํ—ค๋” ํŒŒ์ผ์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๊ณ  ๋‚ด๋ถ€ ๊ตฌํ˜„์—์„œ๋Š” ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.
  • ๋”ฐ๋ผ์„œ...
    • ์˜์กด์„ฑ์ด ๊ณต์œ ๋˜์–ด์•ผ ํ•˜๊ฑฐ๋‚˜ ๊ธฐํƒ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ผ๋ฉด PUBLIC์œผ๋กœ ์„ ์–ธํ•˜๊ณ ,
    • ๋‚ด๋ถ€ ๊ตฌํ˜„์—๋งŒ ์‚ฌ์šฉ๋˜๊ณ  ๊ณต๊ฐœ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด PRIVATE์— ๋ฐฐ์น˜ํ•˜๋Š” ๊ฒƒ์ด ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  •  ์ถ”๊ฐ€๋กœ...
    • FetchContent๋ฅผ ์ด์šฉํ•˜์—ฌ ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•์€ ๋‹ค์Œ ๊ธ€์„ ์ฐธ์กฐํ•˜๋„๋ก ํ•ฉ์‹œ๋‹ค!
    • ์ฐธ๊ณ : [CMake] FetchContent: ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ž~

๊ฐ„๋‹จ ์˜ˆ์ œ

๋‹ค์Œ์€ ์ƒ๊ธฐ ์„ค๋ช…๋“ค์„ ํฌํ•จํ•˜๋Š” ์ตœ์†Œํ•œ์˜ CMake ์˜ˆ์ œ์ด๋ฉฐ, ๊ฒฐ๊ณผ๋กœ์„œ 'backlib'์ด๋ผ๋Š” ์ •์  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํŒŒ์ผ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

cmake_minimum_required(VERSION 3.22)
# ${PROJECT_NAME}: backlib
project(backlib VERSION 1.0
                  DESCRIPTION "Util Library"
                  LANGUAGES CXX C)

# CONFIGURE_DEPENDS: main build system check target to rerun the flagged GLOB commands at build time.
file(GLOB DEPS CONFIGURE_DEPENDS "src/*")
set(ALL_DEPS ${ALL_DEPS} ${DEPS})

# ${PROJECT_NAME}์™€ autocrypt::${PROJECT_NAME}๋ฅผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ์ถ”๊ฐ€
add_library(${PROJECT_NAME} STATIC ${ALL_DEPS})
# add_library(autocrypt::${PROJECT_NAME} ALIAS ${PROJECT_NAME})

target_include_directories(${PROJECT_NAME}
  PUBLIC
    include 
    ${PROJECT_BINARY_DIR}/include
)

#FetchContent๋กœ ๋ฐ›์€ spdlog์™€ jsoncpp๋ฅผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์— ๋งํ‚น ์ž‘์—…(์˜์กด์„ฑ ์„ค์ •)
target_link_libraries(${PROJECT_NAME}
  PUBLIC
    spdlog::spdlog jsoncpp_static
)

3.3 ๋ณ€์ˆ˜(Variables)์™€ ์บ์‹œ(Cache)

์ง€์—ญ๋ณ€์ˆ˜(Local Variables) ์„ค์ •

๋ณ€์ˆ˜๋Š” set์„ ์‚ฌ์šฉํ•ด์„œ ์ƒ์„ฑํ•˜๋ฉฐ ๋‹จ์ˆœํ•œ Boolean, ๋ฌธ์ž์—ด, ํŒŒ์ผ ๊ฒฝ๋กœ, ๋ฆฌ์ŠคํŠธ ๋“ฑ์„ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
๋˜ํ•œ, unset์„ ์‚ฌ์šฉํ•ด์„œ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

set(MY_VARIABLE "value")
set(MY_LIST "one" "two")
set(MY_LIST "one;two")
set(MY_BOOL ON)

option(MY_BOOL "message" OFF)

์ด๋Ÿฌํ•œ ๋ณ€์ˆ˜๋ฅผ message์™€ ${}๋ฅผ ์ด์šฉํ•˜๋ฉด ์ถœ๋ ฅํ•˜์—ฌ ๋ณ€์ˆ˜๊ฐ’์„ ๋ฌธ์ž์—ด๋กœ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

set(CMAKE_BUILD_TYPE Debug)

message(STATUS CMAKE_BUILD_TYPE)                     # -- CMAKE_BUILD_TYPE
message(STATUS ${CMAKE_BUILD_TYPE})                  # -- Debug
message(STATUS "Configuration: ${CMAKE_BUILD_TYPE}") # -- Configuration: Debug

+ message: ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ฉฐ ํ•ด๋‹น ๋ผ์ธ์— ์™”์„ ๋•Œ ํ•ด๋‹น ์ •๋ณด๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.

message([<mode>] "message text" ...)

 <mode> keyword: optional

  • NOTICE : <mode> ์ƒ๋žต์‹œ default <mode>๊ฐ’์ด๋ฉฐ, ์ค‘์š” ์ •๋ณด๋ฅผ ๋‚˜ํƒ€๋‚ด๋Š” ๋ฉ”์„ธ์ง€๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ์ถœ๋ ฅ
  • STATUS : ์ƒํƒœ๋ฉ”์„ธ์ง€ ์ถœ๋ ฅ ('--'์™€ ํ•จ๊ป˜ ๋ฉ”์„ธ์ง€๊ฐ€ ์ถœ๋ ฅ๋จ)
  • WARNING : ๊ฒฝ๊ณ  ๋ฉ”์„ธ์ง€
  • AUTHOR_WARNING : ์Šคํฌ๋ฆฝํŠธ ๊ฐœ๋ฐœ์ž์šฉ ๊ฒฝ๊ณ  ๋ฉ”์„ธ์ง€
  • SEND_ERROR : ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€, ์˜ค๋ฅ˜๊ฐ€ ๋‚˜๋„ ๊ณ„์† ์ง„ํ–‰ํ•˜์ง€๋งŒ ๊ฒฐ๊ณผ๋ฌผ(Makefile)์€ ์ƒ์„ฑํ•˜์ง€ ์•Š์Œ
  • FATAL_ERROR : ์˜ค๋ฅ˜ ๋ฉ”์„ธ์ง€, ๋นŒ๋“œ์ž‘์—…์„ ์ฆ‰์‹œ ์ค‘๋‹จ
    • ์ฃผ์˜!!! : Makefile ์‹คํ–‰ ์‹œ๊ฐ€ ์•„๋‹Œ cmake๋กœ Makefile์„ ์ƒ์„ฑํ•  ๋•Œ ์ถœ๋ ฅ๋˜๋Š” ๋ฉ”์„ธ์ง€์ž…๋‹ˆ๋‹ค.

์บ์‹œ(Cache) ์„ค์ •

์ปค๋งจ๋“œ ๋ผ์ธ์„ ํ†ตํ•œ ๋ณ€์ˆ˜ ์„ค์ •์€ Cache๋ฅผ ํ†ตํ•ด ์ง€์›๋ฉ๋‹ˆ๋‹ค.

set(MY_CACHE_VARIABLE "VALUE" CACHE STRING "Description")

+ ์บ์‹œ(Cache) ํ™•์ธ ๋ฐ ์„ค์ •

$ nano CMakeCaches.txt
$ ccmake ..
  • ccmake: MY_CACHE_VARIABLE๊ณผ ๊ฐ™์€ configuration ์„ค์ •๊ฐ’์„ ํ™•์ธ ๋ฐ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ.
  • ์ฐธ๊ณ : https://cmake.org/cmake/help/latest/manual/ccmake.1.html

ํ™˜๊ฒฝ๋ณ€์ˆ˜(Environment Variables) ์„ค์ •

# SET 
set(ENV{variable_name} value)
# GET 
$ENV{variable_name}

ํ”„๋กœํผํ‹ฐ(Properties) ์„ค์ •

CMake๊ฐ€ ์ •๋ณด๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์—๋Š” ๋ณ€์ˆ˜ ์™ธ์—๋„ ํ”„๋กœํผํ‹ฐ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœํผํ‹ฐ๋Š” ํƒ€๊ฒŸ ๋ณ„๋กœ ์ง€์ • ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

set_property(TARGET TargetName PROPERTY CXX_STANDARD 11)
set_target_properties(TargetName PROPERTIES CXX_STANDARD 11)

get_property(ResultVariable TARGET TargetName PROPERTY CXX_STANDARD)

3.4 CMake ํ”„๋กœ๊ทธ๋ž˜๋ฐ

CMake๋Š” ์ผ๋ถ€ ๊ฐ„๋‹จํ•œ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

if ๋ฌธ

if(variable)
    # If variable is `ON`, `YES`, `TRUE`, `Y`, or non zero number
else()
    # If variable is `0`, `OFF`, `NO`, `FALSE`, `N`, `IGNORE`, `NOTFOUND`, `""`, or ends in `-NOTFOUND`
endif()
# If variable does not expand to one of the above, CMake will expand it then try again

Generator-expressions

target_compile_options(MyTarget PRIVATE "$<$<CONFIG:Debug>:--my-flag>")

๋งคํฌ๋กœ(Macros) ๋ฐ ํ•จ์ˆ˜(Functions)

function(SIMPLE REQUIRED_ARG)
    message(STATUS "Simple arguments: ${REQUIRED_ARG}, followed by ${ARGV}")
    set(${REQUIRED_ARG} "From SIMPLE" PARENT_SCOPE)
endfunction()

simple(This)
message("Output: ${This}")
  • ํ•จ์ˆ˜(function)์™€ ๊ด€๋ จ๋œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ [CMake] function: ๋ฐ˜๋ณต๋˜๋Š” ์ž‘์—…์€ ํ•จ์ˆ˜ํ™”ํ•˜์ž!๋ฅผ ์ฐธ๊ณ ํ•ฉ์‹œ๋‹ค.

3.5 ์ฝ”๋“œ์™€ ์†Œํ†ตํ•˜๊ธฐ: CMakeLists ์ •์˜๋œ ๋ณ€์ˆ˜ ์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•˜๊ธฐ

CMake๋Š” configure_file ๋ช…๋ น์–ด๋ฅผ ํ†ตํ•ด cpp, hpp๋“ฑ ์ฝ”๋“œ๋ฅผ ์ง์ ‘ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๋Š” ์˜ˆ์‹œ๋Š” Version.h.in ์ž…๋‹ˆ๋‹ค.

Configure File ์„ค์ • ํŒŒ์ผ ์ƒ์„ฑ: Version.h.in

#pragma once

#define MY_VERSION_MAJOR @PROJECT_VERSION_MAJOR@
#define MY_VERSION_MINOR @PROJECT_VERSION_MINOR@
#define MY_VERSION_PATCH @PROJECT_VERSION_PATCH@
#define MY_VERSION_TWEAK @PROJECT_VERSION_TWEAK@
#define MY_VERSION "@PROJECT_VERSION@"

Configure File ์„ค์ • ํŒŒ์ผ ๋ช…์‹œ

configure_file (
    "${PROJECT_SOURCE_DIR}/include/My/Version.h.in"
    "${PROJECT_BINARY_DIR}/include/My/Version.h"
)

ํŒŒ์ผ์˜ ๋‚ด์šฉ์„ ์ฝ์–ด์˜ค๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

# Assuming the canonical version is listed in a single line
# This would be in several parts if picking up from MAJOR, MINOR, etc.
set(VERSION_REGEX "#define MY_VERSION[ \t]+\"(.+)\"")

# Read in the line containing the version
file(STRINGS "${CMAKE_CURRENT_SOURCE_DIR}/include/My/Version.hpp"
    VERSION_STRING REGEX ${VERSION_REGEX})

# Pick out just the version
string(REGEX REPLACE ${VERSION_REGEX} "\\1" VERSION_STRING "${VERSION_STRING}")

# Automatically getting PROJECT_VERSION_MAJOR, My_VERSION_MAJOR, etc.
project(My LANGUAGES CXX VERSION ${VERSION_STRING})

3.6 ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ ์‹คํ–‰์‹œํ‚ค๊ธฐ

๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•์€ 2๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

์„ค์ • ์‹œ๊ฐ„(configure time)์— ์™ธ๋ถ€ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•: execute_process

find_package(Git QUIET)

if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
    execute_process(COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
                    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
                    RESULT_VARIABLE GIT_SUBMOD_RESULT)
    if(NOT GIT_SUBMOD_RESULT EQUAL "0")
        message(FATAL_ERROR "git submodule update --init failed with ${GIT_SUBMOD_RESULT}, please checkout submodules")
    endif()
endif()

๋นŒ๋“œ ์‹œ๊ฐ„(build time)์— ์™ธ๋ถ€ ํ”„๋กœ๊ทธ๋žจ์„ ์‹คํ–‰์‹œํ‚ค๋Š” ๋ฐฉ๋ฒ•: add_custom_command...

find_package(PythonInterp REQUIRED)
add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/include/Generated.hpp"
    COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_CURRENT_SOURCE_DIR}/scripts/GenerateHeader.py" --argument
    DEPENDS some_target)

add_custom_target(generate_header ALL
    DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/include/Generated.hpp")

install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/Generated.hpp DESTINATION include)

3.7 ๋‹ค๋ฅธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๊ฐ€์ ธ์˜ค๊ธฐ: find_package, FetchContent

์„ค์ • ์‹œ๊ฐ„(configure time)์— ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•: FetchContent 

FetchContent_Declare(
  <name>
  <contentOptions>...
  [OVERRIDE_FIND_PACKAGE |
   FIND_PACKAGE_ARGS args...]
)
FetchContent_MakeAvilable(<name>)
  • `FetchContent_MakeAvailable` was introduced in CMake 3.14
  • FetchContent์— ๋Œ€ํ•œ ์ž์„ธํ•œ ์„ค๋ช…์€ [CMake] FetchContent: ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ž~ ๋ฅผ ์ฐธ๊ณ ํ•˜์‹œ๊ธฐ ๋ฐ”๋ž๋‹ˆ๋‹ค.

๋นŒ๋“œ ์‹œ๊ฐ„(build time)์— ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ๋ฐฉ๋ฒ•: ExternalProject_Add()

ExternalProject_Add(example
  ... # Download options, etc.
  BUILD_COMMAND ${CMAKE_COMMAND} -E echo "Starting $<CONFIG> build"
  COMMAND       ${CMAKE_COMMAND} --build <BINARY_DIR> --config $<CONFIG>
  COMMAND       ${CMAKE_COMMAND} -E echo "$<CONFIG> build complete"
)

3.8 CMake ๊ฐ„๋‹จ ์˜ˆ์ œ

๋‹ค์Œ์€ ์ƒ๊ธฐ ์„ค๋ช…๋“ค์„ ํฌํ•จํ•˜๋Š” CMake ๊ฐ„๋‹จํ•œ ์˜ˆ์ œ(์ฃผ์„ ํฌํ•จ) ์ž…๋‹ˆ๋‹ค.

# Almost all CMake files should start with this
# You should always specify a range with the newest
# and oldest tested versions of CMake. This will ensure
# you pick up the best policies.
cmake_minimum_required(VERSION 3.1...3.20)

# This is your project statement. You should always list languages;
# Listing the version is nice here since it sets lots of useful variables
project(
  ModernCMakeExample
  VERSION 1.0
  LANGUAGES CXX)

# If you set any CMAKE_ variables, that can go here.
# (But usually don't do this, except maybe for C++ standard)

# Find packages go here.

# You should usually split this into folders, but this is a simple example

# This is a "default" library, and will match the *** variable setting.
# Other common choices are STATIC, SHARED, and MODULE
# Including header files here helps IDEs but is not required.
# Output libname matches target name, with the usual extensions on your system
add_library(MyLibExample simple_lib.cpp simple_lib.hpp)

# Link each target with other targets or add options, etc.

# Adding something we can run - Output name matches target name
add_executable(MyExample simple_example.cpp)

# Make sure you link your targets with this command. It can also link libraries and
# even flags, so linking a target that does not exist will not give a configure-time error.
target_link_libraries(MyExample PRIVATE MyLibExample)

4. Do & Don't

๋‹ค์Œ ํ•ญ๋ชฉ๋“ค์€ An Introduction to Modern CMake: Do's and Don't, [CMake] Effective Modern CMake ์ •๋ฆฌ๋ฅผ ์ฐธ๊ณ ํ•˜์—ฌ ์ž‘์„ฑํ•˜์˜€์Šต๋‹ˆ๋‹ค. ํ•˜๊ธฐ ๋ชฉ๋ก๋งŒ์œผ๋กœ๋Š” ์ดํ•ด๊ฐ€ ์–ด๋ ค์šธ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ณด๋‹ค ์‹ฌ๋„์žˆ๋Š” ์ดํ•ด๋ฅผ ์›ํ•  ๊ฒฝ์šฐ ์›๋ฌธ์„ ์ฐธ์กฐํ•ด์ฃผ์„ธ์š”.

Do

  • CMake๋„ ์ฝ”๋“œ๋ผ๊ณ  ์ƒ๊ฐํ•˜๊ณ  ๊น”๋”ํ•˜๊ณ  ์ฝ์„ ์ˆ˜ ์žˆ๊ฒŒ ์œ ์ง€ํ•˜์‹œ์˜ค
  • target ๊ธฐ๋ฐ˜์œผ๋กœ ์ƒ๊ฐํ•˜์‹œ์˜ค
    • Your targets should represent concepts. Make an (IMPORTED) INTERFACE target for anything that should stay together and link to that.
  • interface๋ฅผ ๋‚ด๋ณด๋‚ด์‹œ์˜ค
  • Config.cmake ํŒŒ์ผ์„ ์ž‘์„ฑํ•˜์‹œ์˜ค
    • This is what a library author should do to support clients.
  • ALIAS๋ฅผ ์ž‘์„ฑํ•˜์‹œ์˜ค
    • Using add_subdirectory and find_package should provide the same targets and namespaces.
  • ๋งคํฌ๋กœ ๋Œ€์‹  ํŽ‘์…˜์„ ์‚ฌ์šฉํ•˜์‹œ์˜ค
  • ํ•จ์ˆ˜๋ช…์€ ์†Œ๋ฌธ์ž๋ฅผ ์‚ฌ์šฉํ•˜๊ณ , ๋ณ€์ˆ˜๋ช…์— ๋Œ€๋ฌธ์ž๋ฅผ ์‚ฌ์šฉํ•˜์‹œ์˜ค
  • cmake_policy๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  versions์˜ ๋ฒ”์œ„๋ฅผ ์„ค์ •ํ•˜์‹œ์˜ค.
    • Policies change for a reason. Only piecemeal set OLD policies if you have to.

Don't

  • ์ „์—ญ ํŽ‘์…˜์„ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์‹œ์˜ค: link_directories, include_libraries ๋“ฑ ์‚ฌ์šฉํ•˜์ง€ ๋งˆ์‹œ์˜ค.
  • ๋ถˆํ•„์š”ํ•œ PUBLIC ํ•œ์ •์ž ๋‚ด ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•˜์ง€ ๋งˆ์‹œ์˜ค
    • You should avoid forcing something on users that is not required (-Wall). Make these PRIVATE instead.
  • GLOB๋กœ ํŒŒ์ผ์„ ์„ ํƒํ•˜์ง€ ๋งˆ์‹œ์˜ค
    • Make or another tool will not know if you add files without rerunning CMake.
    • Note that CMake 3.12 adds a CONFIGURE_DEPENDS flag that makes this far better if you need to use it.
  • ํƒ€๊ฒŸ ์ž‘์„ฑ ์—†์ด LINKํ•˜์ง€ ๋งˆ์‹œ์˜ค
  • LINK์‹œ PUBLIC/PRIVATE๋ฅผ ์ƒ๋žตํ•˜์ง€ ๋งˆ์‹œ์˜ค

์ฐธ๊ณ 

  • [Blog] Effective Modern CMake: https://gist.github.com/mbinna/c61dbb39bca0e4fb7d1f73b0d66a4fd1
  • [Blog] An Introduction to Modern CMake: https://cliutils.gitlab.io/modern-cmake/
  • [Blog] C++ ํ”„๋กœ์ ํŠธ๋ฅผ ์œ„ํ•œ CMake ์‚ฌ์šฉ๋ฒ•: https://modoocode.com/332
  • ์ฐธ๊ณ ํ• ๋งŒํ•œ CMake ํ”„๋กœ์ ํŠธ
    • https://github.com/gabime/spdlog-
    • https://github.com/google/googletest
    • https://github.com/google/leveldb: target_sources ๋ถ€๋ถ„
    • https://github.com/google/benchmark 
    • https://github.com/open-source-parsers/jsoncpp
  • [Github]CMake ํ• ๋•Œ ์ชผ์˜ค์˜ค๊ธˆ ๋„์›€์ด ๋˜๋Š” ๋ฌธ์„œ:
    https://gist.github.com/luncliff/6e2d4eb7ca29a0afd5b592f72b80cb5c?permalink_comment_id=3037466 
๋ฐ˜์‘ํ˜•
์ €์ž‘์žํ‘œ์‹œ ๋น„์˜๋ฆฌ ๋ณ€๊ฒฝ๊ธˆ์ง€ (์ƒˆ์ฐฝ์—ด๋ฆผ)

'Study: DeveloperTools(DevTool) > DevTool: CMake' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

[CMake] FetchContent: ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ž~  (0) 2022.06.24
[CMake] Effective Modern CMake ์ •๋ฆฌ  (0) 2022.06.24
[CMake] CMake ์†Œ๊ฐœ ๋ฐ ํ•„์š”์„ฑ: Modern CMake 3.23+  (0) 2022.06.24
[CMake] Makefile ๋ฐ CMake์˜ ํ•„์š”์„ฑ ์ •๋ฆฌ  (2) 2022.06.24
[C++] C++ ๋นŒ๋“œ ์‹œ์Šคํ…œ(ํˆด)์—๋Š” ๋ญ๊ฐ€ ์žˆ์„๊นŒ?  (0) 2022.06.24
    'Study: DeveloperTools(DevTool)/DevTool: CMake' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€
    • [CMake] FetchContent: ์™ธ๋ถ€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ž~
    • [CMake] Effective Modern CMake ์ •๋ฆฌ
    • [CMake] CMake ์†Œ๊ฐœ ๋ฐ ํ•„์š”์„ฑ: Modern CMake 3.23+
    • [CMake] Makefile ๋ฐ CMake์˜ ํ•„์š”์„ฑ ์ •๋ฆฌ
    DrawingProcess
    DrawingProcess
    ๊ณผ์ •์„ ๊ทธ๋ฆฌ์ž!

    ํ‹ฐ์Šคํ† ๋ฆฌํˆด๋ฐ”