CMake?를 사용하여 폴더의 모든 파일을 대상에 자동으로 추가 하시겠습니까?


163

Visual C ++, XCode 및 makefile의 별도 빌드 관리 시스템에서 크로스 플랫폼 프로젝트를 CMake로 전환하는 것을 고려하고 있습니다.

필요한 한 가지 필수 기능은 디렉토리의 모든 파일을 대상에 자동으로 추가하는 것입니다. 이것은 make로하기 쉽지만 Visual C ++ 및 XCode로는 쉽게 수행 할 수 없습니다 (잘못된 경우 수정하십시오). CMake에서 직접 할 수 있습니까? 어떻게?


Btw. Visual Studio에는 최소한 C # 프로젝트에는 프로젝트 탐색기에 모든 파일 표시라는 도구 모음 단추가 있습니다. 프로젝트에 논리적으로 포함 된 파일이 없으면 프로젝트의 모든 하위 디렉토리가 표시되고 회색으로 표시됩니다. 컨텍스트 메뉴를 통해 이러한 디렉토리를 포함시킬 수 있습니다. 여기에는 모든 소스 파일이 재귀 적으로 포함됩니다.)
yeoman

답변:


228

것이 가능하다. 예 file(GLOB:

cmake_minimum_required(VERSION 2.8)

file(GLOB helloworld_SRC
    "*.h"
    "*.cpp"
)

add_executable(helloworld ${helloworld_SRC})

참고이이 요구하는 매뉴얼 을 다시 실행하는 cmake생성 된 빌드 시스템이 다시 생성 CMake를 요청할 때 알 수 없기 때문에 소스 파일이 추가되거나 제거되면, 그리고 빌드 시간을 증가시킬 모든 빌드에 그 일을.


11
cmake를 수동으로 다시 실행하는 대안은 make를 실행하기 전에 CMakeLists.txt 파일을 터치하는 것입니다.
Seamus Connor


8
""GLOB를 사용하여 소스 트리에서 소스 파일 목록을 수집하지 않는 것이 좋습니다. 소스를 추가하거나 제거 할 때 CMakeLists.txt 파일이 변경되지 않으면 생성 된 빌드 시스템이 CMake의 재생성 시점을 알 수 없습니다. " 이것은 더 이상 Hand1Cloud 약 연결 CMAKE3.7의 문서에 recommeneded하지 않습니다
트리플

4
그렇다면 GLOB의 대안은 무엇입니까?
Shayne

13
v3.1 이후의 더 좋은 방법은 다음과 같습니다. target_sources () crascit.com/2016/01/31/…
Sheen

34

Kleist의 대답은 확실히 작동하지만 중요한주의 사항이 있습니다.

Makefile수동으로 작성할 때 SRCS모든 .cpp.h파일 을 선택하는 함수를 사용하여 변수를 생성 할 수 있습니다. 소스 파일이 나중에 추가되면 재실행에 make포함됩니다.

그러나 CMake (와 같은 명령 사용 file(GLOB ...))는 명시 적으로 파일 목록을 생성하여 자동 생성 된 파일 목록에 배치합니다 Makefile. 새 소스 파일이 있으면을 다시 Makefile실행 하여 파일을 다시 생성해야합니다 cmake.

편집 : Makefile을 제거 할 필요가 없습니다.


4
cmake를 단순히 재실행 할 수 없어 오래된 Makefile을 제거 / 수정해야합니까?
Ethan

25
이것은 답변이 아니며 @Kleist의 답변에 대한 의견입니다.
Neowizard

3
@Neowizard는 Stackoverflow 용어가 아닙니다.
kara deniz

1
이 의견은 훌륭하지만 "표준"입니다. asker는 이미 cmake를 사용하고 있으므로 make가 "더 똑똑"할 수 있다고 제안하는 것이 도움이되지 않습니다.
frankliuao

새 소스 파일을 추가 한 다음 cmake를 다시 실행하지 않고 빌드하는 방법이 있습니까?
artin

6

확장 에 대한 @Kleist 대답 :

CMake 3.12부터 추가 옵션 CONFIGURE_DEPENDS 가 명령 및에서 지원 됩니다 . 이 옵션을 사용하면 디렉토리에 소스 파일을 추가 / 삭제 한 후 CMake 를 수동으로 다시 실행할 필요없습니다 . 다음 프로젝트 빌드시 CMake가 자동으로 다시 실행됩니다.file(GLOB)file(GLOB_RECURSE)

그러나 CONFIGURE_DEPENDS 옵션 은 빌드가 요청 될 때마다 해당 디렉토리가 다시 검사됨을 의미하므로 빌드 프로세스는 CONFIGURE_DEPENDS 가없는 것보다 더 많은 시간을 소비 합니다.

CONFIGURE_DEPENDS 옵션을 사용할 수 있어도 CMake 설명서 는 소스를 사용 하거나 수집하는 것을 권장하지 않습니다 .file(GLOB)file(GLOB_RECURSE)


"CMake 문서는 여전히 소스 사용 file(GLOB)또는 file(GLOB_RECURSE)수집을 권장하지 않습니다. "그렇다면 무엇을 권장합니까? 다른 것을 사용하여 소스를 수집하거나 모든 단일 소스 파일을 수동으로 나열합니까?
토마스

1
@Thomas : 모든 소스 파일을 수동으로 나열하는 것이 좋습니다. 이 답변 은 권장 사항에 대한 훌륭한 설명을 제공합니다.
Tsyvarev

-2

따라서 powershell을 사용하여 소스 파일 목록을 만드십시오. 이 스크립트를 한번보세요

param (
    [Parameter(Mandatory=$True)]
    [string]$root 
)

if (-not (Test-Path  -Path $root)) {    
throw "Error directory does not exist"
}

#get the full path of the root
$rootDir = get-item -Path $root
$fp=$rootDir.FullName;


$files = Get-ChildItem -Path $root -Recurse -File | 
         Where-Object { ".cpp",".cxx",".cc",".h" -contains $_.Extension} | 
         Foreach {$_.FullName.replace("${fp}\","").replace("\","/")}

$CMakeExpr = "set(SOURCES "

foreach($file in $files){

    $CMakeExpr+= """$file"" " ;
}
$CMakeExpr+=")"
return $CMakeExpr;

이 구조의 폴더가 있다고 가정하십시오.

C:\Workspace\A
--a.cpp
C:\Workspace\B 
--b.cpp

이제이 파일을 "generateSourceList.ps1"로 저장하고 스크립트를 다음과 같이 실행하십시오.

~>./generateSourceList.ps1 -root "C:\Workspace" > out.txt

out.txt 파일에는

set(SOURCE "A/a.cpp" "B/b.cpp")

질문은 크로스 플랫폼으로 태그되었습니다-powershell은 크로스 플랫폼이 아닙니다.
reichhart

@reichhart PowerShell은 너무 리눅스 및 맥에서 작동
아무도

알아. 그러나 powershell에는 태그가 없으며 "CMake"는 이미 크로스 플랫폼입니다. "Powershell"은 추가 종속성이며 Windows 이외의 다른 OS에서는 거의 사용되지 않습니다. Powershell을 사용하는 사람보다 Linux에서 더 많은 C # 개발자를 찾을 수 있습니다. 그리고 가장 중요한 사실은 "CMake에서 직접 할 수 있습니까?"라는 질문입니다.
reichhart
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.