Table of Contents
Windows, macOS 및 Linux에서 안정적으로 컴파일하고 실행하는 C 응용 프로그램을 구축하면 휴대용 소스 코드보다 더 많은 것이 요구됩니다. 각 플랫폼의 기본 툴링에 적응하는 빌드 시스템. CMake, 오픈 소스 빌드 시스템 생성기, 간단한 구성 파일에서 프로젝트를 정의하여이 문제를 해결하고 플랫폼 별 빌드 파일 (Makefiles, Visual Studio 솔루션 파일, Xcode 프로젝트 등)을 생성하는 것입니다. 이 문서는 철저한, 실용적인 가이드를 제공하여 CMakefiles, Visual Studio 솔루션 파일, Xcode 프로젝트, 기타 모두의 기본 설계와 같은 모든 작업을 수행 할 수 있습니다.
CMake는 무엇입니까?
CMake는 메타 빌드 시스템입니다: 코드를 직접 컴파일하지 않지만 다른 빌드 시스템에 입력 파일을 생성하지 않습니다. 도메인 별 언어를 사용하여 ] 파일에 프로젝트를 설명합니다. CMake는 다음이 파일을 읽고 대상 플랫폼에 적합한 빌드 지침을 출력합니다.
CMake의 주요 특성은 다음과 같습니다 :
- Platform-agnostic 문법: 유닉스, Windows 및 macOS에서 동일한 ] 작품.
- 다중 발전기: 닌자, Visual Studio, Xcode 등 지원
- Out-of-source builds: 소스 코드에서 별도의 artifacts를 구축한다.
- Extensibility: Modules, function, 그리고 매크로는 재사용 가능한 빌드 논리를 허용한다.
- 패키지 발견: 라이브러리 및 헤더를 설치합니다.
- CI/CD:는 자동화된 파이프라인에서 원활하게 작동합니다.
CMake는 LLVM, MySQL, KDE 데스크톱 환경으로 변화하는 프로젝트로 C 및 C++ 생태계의 크로스 플랫폼 개발을 위한 데 facto 표준이 되었습니다.
Cross-Platform C 개발용 CMake를 활용한 장점
CMake 채택은 간단한 휴대성보다 몇 가지 구체적인 이점을 제공합니다.
- 단일 소스의 진실: 을 작성하면 logic을 작성하고 모든 플랫폼에 대한 파일을 생성하고, eliminating fragile shell 스크립트 또는 플랫폼 별 Makefiles.
- IDE 통합: 팀은 Visual Studio, CLion, Xcode, VS Code에서 작동하여 동일한 ]를 공유할 수 있습니다.
- Modular 프로젝트 구조: ]]를 사용하여 큰 프로젝트를 관리 가능한 구성 요소로 분할합니다.
- Conditional logic: 플랫폼 별 플래그, 소스 파일, 또는 라이브러리를 전체 구성을 복제하지 않고 필요한 경우만 적용.
- 자동 의존성 처리: ] 과 세번째 파티 라이브러리를 사용하여 단순화.
- 테스트 및 포장:] CTest와 CPack은 단단히 통합되어 테스트 추가 및 설치 프로그램을 만들 수 있습니다.
- Build performance: 닌자 발생기 CCache와 결합된 시간의 재구성을 극적으로 감소시킵니다.
- Active 커뮤니티: Thorough official documentation] 및 모듈 및 튜토리얼의 분산 생태계.
시작: C Project에 CMake 설정
이 섹션은 설치에서 컴파일된 실행을 3개의 주요 플랫폼으로 실행할 수 있는 완전한 워크플로를 통해 진행됩니다.
1. CMake 설치
cmake.org에서 최신 바이너리를 다운로드하거나 시스템의 패키지 관리자를 사용합니다.
- ]Linux (Debian/Ubuntu): ]
- macOS (홈 Brew): ]]
- Windows: 설치 프로그램을 실행하고 “시스템 PATH에 CMake 추가”를 선택한다.
로 설치를 검증합니다. 버전 3.10 이상은 여기에 논의 된 기능에 대해 권장됩니다.
2. Minimal CMakeLists.txt를 작성합니다.
프로젝트 루트에서 라는 파일 생성. 아래는 단일 소스 C 프로젝트의 최소 예입니다:
cmake_minimum_required(VERSION 3.10)
project(HelloWorld C)
add_executable(hello main.c)
공급 능력:
- 은 최소 CMake 버전을 설정합니다. 또한, 행동을 개선하는 정책 업데이트도 가능합니다.
- 프로젝트 이름과 언어를 정의합니다. ]를 지정하면 C++ 컴파일러에 대한 스캔에서 CMake를 방지합니다.
- ]] 는 CMake에게 ] 에서 내장되어야한다.
약간 더 현실적인 예제는 컴파일러 플래그와 헤더만 의존성을 추가합니다.
cmake_minimum_required(VERSION 3.15)
project(Calculator C)
set(CMAKE_C_STANDARD 11)
set(CMAKE_C_STANDARD_REQUIRED ON)
add_executable(calc main.c parser.c)
target_include_directories(calc PRIVATE include)
] ]를 ] 대상에 대한 컴파일러의 헤더 검색 경로에 추가합니다.
3. 빌드 파일 생성
빌드 디렉토리를 만들고 CMake를 실행하십시오.
mkdir build
cd build
cmake ..
Linux/macOS에서 기본적으로 Makefile을 생성합니다. Visual Studio를 설치한 Windows에서 ]파일을 생성합니다. 다른 발전기를 요청하려면 ]를 사용하십시오.
세대 후, 설정 시간에 옵션을 통과 할 수 있습니다:
cmake .. -DCMAKE_BUILD_TYPE=Release -DMY_FEATURE=ON
이 변수는 에 저장되며, 이후 실행에 재사용됩니다.
4. 프로젝트 구축
파일을 생성하면 컴파일:
- Make/Ninja: ] (모든 플랫폼과 발전기에서 작품)
- Visual Studio: ]
- Xcode:
명령은 크로스 플랫폼이며 플랫폼 별 인발을 방지합니다. ]를 사용하여 빌드 속도를 높입니다.
Real-World 프로젝트의 고급 CMake 기술
CMake는 기본을 넘어 더 큰 더 복잡한 빌드를 간소화하는 기능을 제공합니다. 마스터링은 시간을 절약하고 오류를 줄일 수 있습니다.
find package와 의존성을 관리
명령은 라이브러리 파일들을 위한 라이브러리 및 설정 변수를 설치합니다. 현대 CMake는 를 사용하여 권장됩니다 대상] 깨끗한 의존성 전파에 대한:
find_package(SDL2 REQUIRED)
target_link_libraries(my_app PRIVATE SDL2::SDL2)
가져오기 대상은 자동으로 디렉터리, 컴파일 정의 및 링크 플래그를 포함 합니다. 라이브러리가 CMake 구성 파일을 제공하지 않는 경우, Find 모듈이 필요할 수 있습니다. cmake-developer에서 자신의 커뮤니티에 여러분의 의견을 작성하십시오.
시스템 전체 설치없이 의존성, 다운로드 및 구성 시간에 소스 코드를 통합 :
include(FetchContent)
FetchContent_Declare(
zlib
GIT_REPOSITORY https://github.com/madler/zlib.git
GIT_TAG v1.3
)
FetchContent_MakeAvailable(zlib)
target_link_libraries(my_app PRIVATE zlib)
이 접근법은 특정 버전의 피싱에 의해 재현 가능한 빌드를 보장합니다.
CTest로 테스트 추가
CMake는 CTest를 통해 테스트를 통합합니다. 그것을 사용 하 고 테스트 정의 :
enable_testing()
add_executable(test_parser test_parser.c)
target_link_libraries(test_parser PRIVATE parser_lib)
add_test(NAME ParserTest COMMAND test_parser)
테스트 실행:
ctest --output-on-failure
CTest는 테스트 정착물, 상표, 타임아웃 및 평행한 실행을 지원합니다. 더 포괄적인 테스트를 위해, ]cmocka를 사용하여 라이브러리를 연결하고 ]를 사용하여 단위 테스트 기구와 결합하는 것을 고려하십시오.
크로스 컴파일
CMake는 toolchain 파일]을 통해 크로스 컴파일을 단순화합니다. 도구 체인 파일은 컴파일러, sysroot 및 대상 아키텍처를 설정합니다. 와 같은 파일을 작성하십시오.
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR arm)
set(CMAKE_C_COMPILER arm-linux-gnueabihf-gcc)
set(CMAKE_SYSROOT /path/to/sysroot)
그런 다음 도구 체인 CMake를 호출 :
cmake -DCMAKE_TOOLCHAIN_FILE=arm-cross.cmake ..
CMake는 지정된 크로스 컴파일러를 자동으로 사용하고 라이브러리에 대한 sysroot를 검색합니다. 이 기술은 임베디드 시스템, 모바일 플랫폼 및 빌드 머신이 대상 기계와 다릅니다있는 시나리오에 사용됩니다. 공식 Cross가 CMake] 가이드와 호환됩니다.
설치 및 포장
] 를 사용하여 프로젝트가 배포되는 방법을 정의 할 명령을 실행합니다.
install(TARGETS my_app DESTINATION bin)
install(FILES config.ini DESTINATION etc)
CPack은 설치자를 생성합니다 : DEB, RPM, NSIS, DMG 등 의 끝에 추가 :
include(CPack)
Debian 패키지를 생성하기 위해 를 실행하십시오. CPack은 모든 설치 규칙을 상속하고 ]과 같은 변수를 통해 사용자 정의 할 수 있습니다.
일반적인 Pitfalls 및 모범 사례
경험 많은 개발자가 snags를 공격합니다. 자주 묻는 질문과 그를 피하는 방법:
Pitfall: 하드 코딩 경로
절대 경로는 ]를 사용하지 않습니다. ]과 ]] 소스 트리에 관계 없이 사용하세요. 실행 시간 파일 위치에 대해서는 를 사용하여 경로 또는 설치 디렉토리에 의존합니다.
Pitfall: 발전기 표현을 무시
생성기 표현 () 빌드 시간에 평가, 시간을 구성하지. 그들은 구성 설정 설정에 필수적입니다:
target_compile_definitions(my_app PRIVATE
$<$<CONFIG:Debug>:_DEBUG>
)
디버그 빌드에만 를 추가합니다. ]를 사용하지 않도록 멀티 구성 생성기 (Visual Studio, Xcode)가 설정되지 않기 때문에 를 구성 시간에.
Pitfall: 글로벌 명령을 극복
, , ]]은 모든 대상에 영향을 미칩니다. ], ], ]와 같은 대상별 명령을 더 잘 캡슐화합니다.
Pitfall: 찾기에 대한 Proper 범위 사용하지 package
] 을 적절하게 설정한다. 현대 CMake를 사용하면 를 선호하고 그 목표를 연결한다. 을 사용하지 않고 수동으로 연결 디렉토리를 설정한다.
관련 기사
CMake는 관리 가능한 반복 가능한 프로세스로 멀티 플랫폼 C 개발의 도전을 변환합니다. 빌드 지침의 단일 세트를 작성함으로써, 당신은 기본 성능, IDE 지원 및 모든 주요 운영 체제에서 강력한 의존성 관리를 얻을 수 있습니다. 간단한 로 시작하고 점차적으로 고급 기능을 채택하여 프로젝트가 성장함에 따라 프로젝트가 성장합니다. CMake 학습 투자는 빌드, 테스트, 또는 단일 코드없이 다른 코드를 구축 할 때마다 다시 지불합니다.