2013-07-29 2 views
4
을 사용하여 무시 파일

(사과 : CMake 메일 링리스트에서 교차 게시)CPack : 정규식

내가 CMake의 정규식 구현 라운드 내 머리를 얻으려고; CMakeLists.txt의

build/ 
projectA/ 
CMakeLists.txt 
extrafiles/ 
README 
temp/ 

한 줄은 다음과 같습니다 :

다음 이후에 생성되는 내 소스 패키지에서
set(CPACK_SOURCE_IGNORE_FILES "[^projectA]$") 

, build/, projectA/ 다음과 같이 내가 4 개 폴더와이 개 텍스트 파일이 들어있는 폴더가 extrafiles은 있지만, temp/이고 2 개의 텍스트 파일은 없습니다. 정규 표현식이 projectA/, READMECMakeLists.txt을 제외하고 폴더의 모든 내용을 무시하는 단계에 도달하려고하지만 현재 제공되는 정규식이 이러한 결과를 제공하는 방법을 생각해 낼 수 없습니다.

제가 궁금해하는 점은 정규식을 사용하여 전체 문자열을 일치시키는 방법입니다. 내가 CMake의 정규식 구현을 이해하려고 노력에서

또한 탐사

... 워드 프로세서 내가 내가 잘못가는 것 같아 곳이다 Matches any character(s) not inside the brackets 말을 실현, 내가 첫 번째 원칙에서 시작 거라고 생각 쉬운 일을해라. (예상대로)

내가

set(CPACK_SOURCE_IGNORE_FILES projectA) 

을 할 경우 폴더 projectA 내 소스 패키지에 표시되지 않습니다 그러나, 내가 할 경우

set(CPACK_SOURCE_IGNORE_FILES ^projectA$) 

또는

set(CPACK_SOURCE_IGNORE_FILES ^/projectA/$) 

projectA 가 나타나지 않습니다. ^ (줄의 시작)과 $ (줄의 끝)에 대해 무엇을 알지 못합니다.

은 더욱

으로 아마 분명, projectA 실제로 내 프로젝트의 이름이 아닙니다,하지만 물리적으로 projectA 내 프로젝트 폴더의 이름을 바꿀 때 모든 위 마찬가지입니다. 그러나, 나는

set(CPACK_SOURCE_IGNORE_FILES <name of my project>) 

set(CPACK_SOURCE_IGNORE_FILES projectA) 

교체하고 실제 이름 projectA에서 내 실제 프로젝트 폴더의 이름을 바꿀 때, 나는 타르와 끝까지! 아! 나는 절대적으로 을 가지고 있지 않다. 아이디어 CMake가 나에게 놀고있는 이상한 속임수가 무엇인지 생각하지만 나는 단지 울고 싶다.

어떤 통찰력이라도 대단히 감사하겠습니다!프레이저에 의해

아파트형 예

As requested는, 자기는 내가 기술 한 '기능'의 2를 보여주는 예제가 포함되어 있습니다. 그러나 나는 CMake를 약간 비표준 방식으로 실행하여 모든 것을 개별 빌드와 함께 유지한다는 것을 알고있다. 그래서 CMake를 좀 더 표준적인 방법으로 실행하면 이러한 문제를 해결할 수있다. 그들을 보러 관심이 있어요.

1 단계 :

cd ~ 
mkdir 
cd projectA 
mkdir projectA  

하는 C 파일을 만들고 ~/projectA/projectA/helloworld.c로 저장 :

#include <stdio.h> 
#include <stdlib.h> 

int main(void) { 
    printf("!!!Hello World!!!\n"); /* prints !!!Hello World!!! */ 
    printf("!!!Hello CMake!!!\n"); /* prints !!!Hello CMake!!! */ 
    return 0; 
} 

필요가 없습니다 파일을 생성 생성 파일

트리 만들기 컴파일하여 다음과 같이 저장하십시오 : ~/projectA/test.sh :

#A non compiled program 
echo "Hello world!" 

~/projectA/CMakeLists.txt 만들 :

cmake_minimum_required (VERSION 2.6) 
project (HelloWorld) 

set(CMAKE_INSTALL_PREFIX "$ENV{HOME}/projectAinstall") 

add_executable(helloworld projectA/helloworld.c) 
install(TARGETS helloworld DESTINATION .) 

include(InstallRequiredSystemLibraries) 
set(CPACK_GENERATOR "TGZ") 
set(CPACK_SOURCE_GENERATOR "TGZ") 

include(CPack) 

2 단계 : ~/projectA에서

를 컴파일, 실행 후

[email protected]:~/projectA$ cmake -H. -Bbuild 

:

make -C build && make -C build package && make -C build package_source 

이 경우 build 폴더에 두 개의 타르볼이 생성됩니다. 이러한 다른 곳으로 이동하고 압축을 해제하는 것은 (예상대로) 바이너리 타르볼에서 helloworld, 그리고 (프레이저가에 대해 놀랄 듯) 컴파일되지 않습니다 test.sh 포함 소스 타르볼의 ~/projectA/projectA에서 모든 보여줍니다

3 단계 : 위의 CMake/확인 명령을

set(CPACK_SOURCE_IGNORE_FILES "projectA") 

를 포함 CMakeLists.txt을 수정하고 다시 실행 무작위 시험

빈 소스 tarball이되지만 위와 동일한 바이너리 tarball이 있습니다. 지금 실현하는 최상위 디렉토리 (하위 폴더 그래서 다른과) testproject빈 소스 타르볼하지 결과를 않습니다, 단지 CPACK_SOURCE_IGNORE_FILES

답변

2
에 나열된 파일을 제거 않습니다되도록 디렉토리 트리를 변경

CPACK_SOURCE_IGNORE_FILES (내가 확실하지 않지만)을 사용한 후에 달성 할 수 있다고 생각하지 않습니다. 당신이 올바르게 지적했듯이, CMake의 정규 표현식 처리는 문자 그룹을 제외시킬 수 있지만 전체 패턴을 부정 할 수는 없다고 생각합니다. [편집 마지막에 업데이트 된 답변보기]

즉, 내 생각에 install 명령에서 제외 할 모든 폴더를 나열 할 수 있습니다."PROJECTA"를 제외한 모든 제외만큼 강력하지만, 여전히 여기 구문의 안 : 빈 타르에 관한

install(DIRECTORY . 
     DESTINATION the_install_subdir 
     REGEX "build|extrafiles|temp+" EXCLUDE) 

, 나는 당신이 어쩌면 프로젝트의 루트 디렉토리로와 하위 디렉터리로 <name of my project> 모두가 상상? 예를 들어 프로젝트 "projectA"를 호출하면 "projectA/build", "projectA/projectA"등이 나타납니다.

그렇다면 정규식이 전체 경로에서 작동하고 따라서 프로젝트 내의 모든 파일에는 경로 내에 projectA/이 포함됩니다.

울음 소리에 관해서는 ... 음, 나는 단지 당신에게 그립을 가져서 함께 할 것을 조언 할 수 있습니다! :-)


편집 :

install(DIRECTORY projectA 
     DESTINATION the_install_subdir) 
install(FILES CMakeLists.txt README DESTINATION the_install_subdir) 

또한 편집 : 코멘트에 대응가 여기에 목표를 달성하기 위해 install 명령을 사용하는 간단한 예입니다

좋아요, 당신의 사례가 많이 도움이됩니다. 저는 정말로 당신이하고있는 일에 대해 오해했습니다. 나는 실제로 당신이 2 개의 다른 목표 ("package"와 "package_source")를 만들고 있다고 생각하지 않았다. 난 당신이

cpack -G DEB 

같은 작업을 수행하여 바이너리 패키지를 작성하고 당신이 바이너리 패키지를 빌드 모두

cpack -G TGZ 

를 수행하여 다른 패키지를 만들고 있다고 생각했다. 나의 실수 - 나는 더 많은 관심을 기울여야했다. 죄송합니다! 특정 질문에 대해서는


:

질문 1

그것은 나에게 보인다 포함 된 폴더와 같은 수준에 컴파일되지만되지 않은 파일/디렉토리를 설치 모든 컴파일 된 파일 (예 : bin)을 복사 한 다음 CPACK_SOURCE_IGNORE_FILES를 사용하여 bin 폴더를 무시하면 빈 tarball이됩니다.

나는 이것을 의미하기 위해 : "set(CPACK_SOURCE_IGNORE_FILES "${CMAKE_BINARY_DIR}")을하면 빈 tarball이 생성됩니까?" 대답은 아마도 그렇지 않습니다.

CPACK_SOURCE_IGNORE_FILES은 정규 표현식이므로 결과 정규 표현식 이 프로젝트의 모든 파일과 일치 할 수 있으며이 경우에는 빈 tarball이 발생합니다. 그러나 나는 그것이 매우있을 법하지 않다고 상상한다.

${CMAKE_BINARY_DIR} 변수를 통해 bin 디렉토리에 대한 전체 경로를 사용하는 대신 폴더 이름을 지정하면 빈 tarball이 발생할 확률이 훨씬 높아집니다. bin 디렉토리에 "build"라고하고 set(CPACK_SOURCE_IGNORE_FILES "build")을 가지고 있다고 가정 해보십시오. 프로젝트가 ~/test_builds/projectA에 살았다면 "test_builds"가 들어 있기 때문에 "build"정규식은 프로젝트의 모든 파일과 일치합니다. 결과적으로 빈 tarball이 생성됩니다.

빈 타르볼을 생성 할 때마다 이것이 문제의 핵심이라고 생각합니다. 정규식이 무엇을하려 든간에 실제로 모든 파일을 일치시키고 제외시킵니다.


질문 또한 '설치'되지 않은 CMAKE_SOURCE_DIR에서 파일이 바이너리 타르볼에서 생을 마감하지 않지만 소스에서 생을 마감 할 것 같다 2

tarball

예, "package_source"는 실제로 바이너리 패키지의 다른 대상입니다. 기본적으로 모두 파일이 ${CMAKE_SOURCE_DIR} 인 반면, "패키지"대상은 install 명령을 통해 추가 된 항목 만 포함합니다. 뿐만 아니라이 .c, .CC, .CXX 등


원래 질문

-이 소스 트리에있는 모든 파일을 의미하기 때문에 여기에서, 용어 "소스 파일은"아마 약간 잘못된 것입니다

결국 원래의 목표를 달성하는 데 합리적으로 안전한 방법이 있다고 생각합니다. file(GLOB ...)을 사용하여 루트에있는 모든 파일/폴더의 비 재귀 목록을 생성 한 다음 원본 패키지에 보관하려는 파일/폴더를 제거하는 경우 나머지 목록을 CPACK_SOURCE_IGNORE_FILES :

의 정규식 값으로 사용할 수 있어야합니다.
file(GLOB SourceIgnoreFiles "${CMAKE_SOURCE_DIR}/*") 
set(SourceKeepFiles "${CMAKE_SOURCE_DIR}/projectA" 
        "${CMAKE_SOURCE_DIR}/CMakeLists.txt" 
        "${CMAKE_SOURCE_DIR}/README") 
list(REMOVE_ITEM SourceIgnoreFiles ${SourceKeepFiles}) 
# Escape any '.' characters 
string(REPLACE "." "\\\\." SourceIgnoreFiles "${SourceIgnoreFiles}") 
set(CPACK_SOURCE_IGNORE_FILES "${SourceIgnoreFiles}") 


이 기능을 사용해보세요. misdirections에 대해 다시 미안.

+0

3 코멘트! : 모든 설치 명령이 참조하는 디렉토리를 무시하면 CPack은 자동으로 다른 모든 것을 무시하므로 (따라서 빈 tarball을 작성하는) 경우입니까? 나는'set (CPACK_SOURCE_IGNORE FILES ...) '대신에'INSTALL (DIRECTORY ...)'명령으로 파일을 나열하는 장점을 알 수 있을지 모르겠다. 모든 것을 제외시키는 진정한 이유는 제 동료 중 한 명이 자신의 dev 폴더에있는 가짜 파일을 가지고있는 사람들이 실수로 소스 패키지에서 끝날 것이라는 점을 염려하고 있었기 때문에 나는 이것을 막고 싶었습니다. – ChrisW

+0

!) 예 - 그렇게 생각합니다. 2) 나는 CMakeLists.txt에 이미 하나 이상의'install' 호출이 있다고 상상 했었습니다. 그것은 항상 CPack을 사용한 방법입니다. 나는'include (CPack)'을 포함하고'install' 호출이 없다면 어떻게 될지 확신하지 못합니다. 나는이 경우 빈 타르볼을 기대한다고 생각한다. 3) 나는 나의 해결책이 "제외하는 모든 것"방법만큼 강력하지 않다는 데 동의하지만, 이것이 당신이 묻는 것과 가장 가까운 것이라고 생각했습니다. 필자가 선호하는 기술 (가장 안전한 것)은 사물을 제외하려고하지 않고'install' 호출을 통해 모든 것을 * 명시 적으로 나열하는 것입니다. – Fraser

+0

흠, 나는 나 자신을 매우 분명하게 생각하지 않는다! 나는 * 많은'install' 호출을 (당신의 예제에 따라) 가지고있다. 필자는 컴파일되지 않았지만 컴파일 된 모든 파일 (예 : bin)을 포함하는 폴더와 동일한 레벨에있는 파일/디렉토리를 설치 한 다음 'CPACK_SOURCE_IGNORE_FILES'를 사용하여 bin 폴더를 무시하면 빈 tarball이됩니다. 이게 맞습니까? 또한 'CMAKE_SOURCE_DIR' 파일은'설치되지 않았습니다 '는 바이너리 tarball로 끝나지 않지만 소스 타볼에서는 * do * 끝납니다. 사용하지 않는 별도의'CPACK_IGNORE_FILES'가 있습니다 – ChrisW