Bài 38.126 phút đọc
CMakeLists cơ bản và target
Sau bài này bạn sẽ làm được
- Viết CMakeLists tối thiểu build được
- Phân biệt add_executable và add_library
- Dùng target_link_libraries và target_include_directories
- Giải thích PUBLIC, PRIVATE, INTERFACE
Make là công cụ Unix. CMake không dựng gì cả: nó sinh ra tệp dựng cho nền tảng của bạn, Makefile trên Linux, project Visual Studio trên Windows, Xcode trên macOS. Bài này viết một CMakeLists.txt chạy được và giải thích tư duy target đằng sau nó.
#Vì sao CMake
| Make | CMake | |
|---|---|---|
| Học | Dễ hơn | Khó hơn |
| Đa nền tảng | Không, chủ yếu Unix | Có |
| Quản lý phụ thuộc | Thủ công | Tốt hơn |
| Tích hợp IDE | Kém | Tốt: VS, CLion, Xcode |
| Dự án nhỏ | Đủ dùng | Hơi thừa |
| Dự án lớn, thư viện | Khó | Tốt |
Bộ sinh (generator)
Chương trình dựng thật mà CMake tạo tệp cho:
Unix Makefiles, MinGW Makefiles, Ninja, Visual Studio, hoặc Xcode. Chọn bằng cờ -G. Cùng một CMakeLists.txt dựng được ở mọi nền tảng vì CMake sinh tệp phù hợp cho từng bộ.#CMakeLists tối thiểu
CMakeLists.txt
cmake_minimum_required(VERSION 3.16)
project(MyApp VERSION 1.0.0 LANGUAGES C)
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF) # dung -std=c17, khong phai -std=gnu17
add_executable(app src/main.c)
target_include_directories(app PRIVATE include)#Cấu hình rồi dựng
terminal
# Buoc 1: cau hinh. -S nguon, -B thu muc dung (out-of-source)
cmake -S . -B build -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release
-- The C compiler identification is GNU 8.1.0 -- Detecting C compiler ABI info - done -- Check for working C compiler: .../gcc.exe - skipped -- Detecting C compile features - done -- Configuring done (4.4s) -- Generating done (0.1s) -- Build files have been written to: .../build
# Buoc 2: dung. Goi bo sinh (o day la make) ho ban
cmake --build build
[ 50%] Building C object CMakeFiles/app.dir/src/main.c.obj [100%] Linking C executable app.exe [100%] Built target app
./build/app.exe
2+3=5 2*3=6
#Thư viện và liên kết
Thêm một thư viện tĩnh
cmake_minimum_required(VERSION 3.16)
project(MyApp VERSION 1.0.0 LANGUAGES C)
set(CMAKE_C_STANDARD 17)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
# ===== Thu vien =====
add_library(toan STATIC src/toan.c)
target_include_directories(toan PUBLIC include)
target_compile_options(toan PRIVATE -Wall -Wextra)
# ===== Chuong trinh chinh =====
add_executable(app src/main.c)
target_link_libraries(app PRIVATE toan)terminal
cmake --build build
[ 33%] Building C object CMakeFiles/toan.dir/src/toan.c.obj [ 33%] Linking C static library libtoan.a [ 33%] Built target toan [ 66%] Building C object CMakeFiles/app.dir/src/main.c.obj [ 66%] Linking C executable app.exe [100%] Built target app
#PUBLIC, PRIVATE, INTERFACE
Phạm vi lan truyền
Ba từ khoá quyết định một thuộc tính của thư viện có lan sang thứ liên kết với nó không.
PRIVATE: chỉ thư viện dùng. INTERFACE: chỉ người dùng thư viện dùng. PUBLIC: cả hai.Ba phạm vi, ba nghĩa
add_library(toan STATIC src/toan.c)
target_include_directories(toan
PUBLIC include # header CONG KHAI: toan dung, VA app dung
PRIVATE src # header RIENG: chi toan dung, app khong thay
)
target_compile_options(toan
PRIVATE -Wall -Wextra # canh bao khi dich toan, KHONG lan sang app
)
target_link_libraries(toan
PUBLIC m # neu toan.h dung <math.h>, app cung can -lm
PRIVATE pthread # neu chi toan.c dung pthread, app khong can
)Tự làm thử
- Viết một
CMakeLists.txttối thiểu và dựng một chương trình một tệp. - Cấu hình với
-B buildvà chứng minh không có tệp CMake nào rơi vào thư mục nguồn. - Tách mã thành một thư viện và liên kết chương trình với nó.
- Bỏ
CMAKE_C_EXTENSIONS OFFvà tìm cờ-stdmà CMake dùng trong tệp dựng. - Đặt một đường dẫn include là
PRIVATEmà lẽ raPUBLIC, và đọc lỗi liên kết. - Thêm
target_compile_optionsvớiPRIVATE -Wallvà xác nhận cảnh báo không lan sang chương trình.
Trình chấm điểm tự động sẽ được bổ sung ở giai đoạn sau. Hiện tại bạn tự chạy thử trên máy.
Tóm tắt
- CMake không dựng mà sinh tệp dựng cho nền tảng của bạn qua một bộ sinh; cùng
CMakeLists.txtchạy mọi nơi. - Khuôn mẫu bốn dòng đầu, và
CMAKE_C_EXTENSIONS OFFđể dùng chuẩn thuần. - Luôn dựng ngoài nguồn với
-B build, và dùngcmake --buildthay vì gọi bộ sinh trực tiếp. add_library,add_executable,target_link_librariestạo và nối các target; target mang theo cách dùng nó.PUBLIClan cả hai chiều,PRIVATEchỉ thư viện,INTERFACEchỉ người dùng; khi phân vân chọnPRIVATE.