2010-01-21 4 views
42

디렉토리 아래에있는 모든 .c 파일을 찾고 모든 파일을 SRC 파일에 추가하여 cmake에서 컴파일하려고합니다. 어떻게 CMakeList.txt에서 이것을 할 수 있습니까?Cmake 빌드 시스템의 모든 * .c 파일을 찾는 방법

일반 메이크 위해 나는

SPECIFIED_SRC_FILE = $(foreach d,$(SPECIFIED_SRC_DIRS),$(wildcard $(addprefix $(d)/*,*.c))) 

을 만들 수 있지만 CMakeList.txt이 같은 작업을 수행하는 방법을 가져올 수 없습니다.

+1

"glob로 모든 소스 파일 수집"은 ** CMake에서 권장하지 않음 ** : 소스 트리에서 소스 파일 목록을 수집하는 데'GLOB '을 사용하지 않는 것이 좋습니다. 소스가 추가되거나 제거 될 때'CMakeLists.txt' 파일이 변경되지 않으면 생성 된 빌드 시스템은 언제 CMake가 재생성을 요청할 지 알 수 없습니다. * - [documentation] (https://cmake.org/cmake/help/) v3.7/command/file.html) –

+0

@FranklinYu에는 수동으로 모든 파일 이름을 쓰지 않아도되는 대안이 있습니까? –

+1

@Ciro 모든 파일 이름을 쓰는 것을 피하려면 OP에서 언급 한 'foreach'가 최선의 방법이라고 생각합니다. 그러나 CMake 팀은 수동으로 모든 파일 이름을 쓰는 것을 권장합니다 *. –

답변

39

이 시도 :

AUX_SOURCE_DIRECTORY

이 디렉토리에있는 모든 소스 파일을 찾을 수 있습니다.

AUX_SOURCE_DIRECTORY(dir VARIABLE) 

은 지정된 디렉토리 의 모든 소스 파일의 이름을 수집하고 제공하는 변수의 목록을 저장합니다. 이 명령은 명시 적 템플릿 인스턴스화를 사용하는 프로젝트에서 을 사용하도록되어 있습니다. 템플릿 인스턴스화 파일은 템플릿 " "하위 디렉토리에 저장하고 모든 인스턴스화를 수동으로 나열하지 않으려면이 명령을 사용하여 자동으로 수집 할 수 있습니다.

소스 파일 목록을 라이브러리 또는 실행 가능 타겟에 쓰지 않으려면이 명령을 사용하는 것이 좋습니다. 이것이 작동하는 것처럼 보이지만 CMake가 새로운 소스 파일이 추가되었을 때를 알고있는 빌드 시스템을 생성하는 방법은 없습니다. 일반적으로 생성 된 빌드 시스템 은 CMake를 다시 실행해야 할 때를 알고 있습니다. 왜냐하면 CMakeLists.txt 파일이 새 소스를 추가하도록 으로 수정 되었기 때문입니다. 이 파일을 수정하지 않고 소스가 디렉토리에 추가되면 수동으로 CMake를 다시 실행하여 새 파일을 통합하는 빌드 시스템을 생성해야합니다. 예상대로 CMake가 와일드 카드를 사용하여 전체 포인트의 종류 인 (새 파일이 추가 될 때 결정하기 위해 수 없습니다로

+11

"이 명령을 사용하여 유혹을 피하려고합니다."로 시작하는 마지막 부분을 읽으십시오. – SaoPauloooo

+1

@SaoPauloooo는 다음과 같이 쓰여졌습니다. "Cmake가 새로운 빌드가 언제 생성되는지를 알 수있는 빌드 시스템을 생성 할 방법이 없습니다 소스 파일이 추가되었습니다. " 이 명령은 OP 질문에 대한 가장 가까운 답변입니다. 나를 위해 좋네. – whitequark

0

, @whitequark가 설명 된대로 AUX_SOURCE_DIRECTORY을 사용할 수 있습니다,하지만 정말 작동하지 않습니다).

+2

AUX_SOURCE_DIRECTORY는 현재 잘 수행됩니다. 정말 고맙습니다. AUX_SOURCE_DIRECTORY ($ {PROJECT_INC_DIR} 제어/src에 CTR_SOURCES) ADD_EXECUTABLE ($ {EXE_NAME} $ {CTR_SOURCES}) –

41

어때?

FILE(GLOB MyCSources *.c) 
ADD_EXECUTABLE(MyExecutable ${MyCSources}) 
+0

이 잘 작동하지만에주의를 (CMake 새로운 파일이 추가 될 때 모르는 것) 피 않습니다 다른 두 가지 대답은? – kylewm

+1

아니요, 그렇지 않습니다. 새 파일이 추가되면 CMake를 다시 실행해야합니다. –

+8

(내 요구에 잘 맞았어요 ... 소스 파일을 추가 할 때마다 CMakeList를 편집하는 것보다 쉽습니다) – kylewm

1

네, 두 가지 옵션이 있습니다. 폴더 구조가 이와 비슷한 것으로 가정합시다.

├── autopilot 
      │   ├── _AutoPilot.cpp 
      │   ├── _AutoPilot.h 
      │   └── action 
      │    ├── ActionBase.cpp 
      │    ├── ActionBase.h 
      │    ├── APcopter 
      │    │   ├── APcopter_avoid.cpp 
      │    │   ├── APcopter_avoid.h 

당신이 CMakeLists.txt에게 하위 디렉토리의 각 하나를 추가해야 AUX_SOURCE_DIRECTORY를 사용하는 경우. 그런 다음 모든 하위 디렉토리를 포함하고 링크해야합니다. 이것은 상당히 어려운 작업입니다. 그래서 당신은 GLOB 할 수 있고 일을 아주 쉽게 할 수 있습니다. 이것이 어떻게 이루어 졌는지입니다.

:

ADD_LIBRARY (autopilot ${autopilot}) 
    TARGET_LINK_LIBRARIES (autopilot) 

이 소스 코드 위에 사용하여 실행 파일을 만들려면 명령입니다 : 당신이 소스 코드 위에 사용하여 라이브러리를 만들려면

file(GLOB autopilot_sources ./*.cpp ./*/*.cpp ./*/*/*.cpp ./*/*/*/*.cpp ./*.c ./*/*.c ./*/*/*.c ./*/*/*/*.c) 
    SET(autopilot ${autopilot_sources}) 

이 명령입니다

ADD_EXECUTABLE(autopilot ${autopilot}) 
0

GLOB_RECURSE 재귀 예

그것은 기본적으로 *는 하위 디렉토리로 이동합니다 :

cmake_minimum_required(VERSION 3.0) 
file(GLOB_RECURSE SOURCES RELATIVE ${CMAKE_SOURCE_DIR} "src/*.c") 
add_executable(main ${SOURCES}) 

을하고 다음 우리의 소스는 예를 들어 위치 할 수있다 :

src/main.c 
src/d/a.c 
src/d/a.h 

그리고 main.c#include "d/a.h"를 사용하고 a.c#include "a.h"를 사용합니다. 이 build/ 아래에 위치 CMake 자체에 의해 생성 .c 파일을 선택할 수 있습니다으로 CMake의 최상위에 GLOB_RECURSE를 사용

은 (즉, 대신 "src/*.c""*.c"는) 가능성이 나쁜 생각입니다.

실행 가능한 예 on GitHub.

관련 문제