(道歉:从 CMake 邮件列表中交叉发布)
我正在尝试了解 CMake 的正则表达式实现;我有一个包含 4 个文件夹和 2 个文本文件的文件夹,如下所示:
build/
projectA/
CMakeLists.txt
extrafiles/
README
temp/
一行 CMakeLists.txt 是:
set(CPACK_SOURCE_IGNORE_FILES "[^projectA]$")
在随后生成的我的源包中,build/
存在和 ,但不存在projectA/
2个文本文件。我正试图达到一个阶段,正则表达式将忽略文件夹中除,和之外的所有内容,但目前无法弄清楚我提供的正则表达式如何给出这些结果。extrafiles
temp/
projectA/
README
CMakeLists.txt
我想这归结为如何使用正则表达式匹配整个字符串。我意识到文档说Matches any character(s) not inside the brackets
我猜我哪里出错了......
进一步探索
在试图理解 CMake 的正则表达式实现时,我想我会从第一条原则开始,做一些简单的事情。
如果我做
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 projectA)
和
set(CPACK_SOURCE_IGNORE_FILES <name of my project>)
并将我的实际项目文件夹重命名projectA
为其实际名称,我最终得到一个空的压缩包!啊!我完全不知道 CMake 对我玩了什么奇怪的把戏,但我只想哭。
任何见解将不胜感激!
自包含示例
根据弗雷泽的要求,一个自包含的示例显示了我描述的 2 个“功能”。但是,我确实知道我正在以一种稍微不标准的方式运行 CMake,以便将所有与单个构建有关的事情放在一起,所以如果有任何证据以更标准的方式运行 CMake 可以消除这些问题,我会有兴趣看看他们。
第一步:创建文件
创建树:
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)
第二步:编译
在~/projectA
中,运行:
chris@chris:~/projectA$ cmake -H. -Bbuild
然后:
make -C build && make -C build package && make -C build package_source
这会在文件build
夹中生成 2 个 tarball。将它们移动到其他地方并解压缩它们会显示helloworld
在二进制 tarball 中(如预期的那样),以及源 tarball 中的所有内容~/projectA/projectA
,包括test.sh
哪些不会被编译(Fraser 似乎对此感到惊讶)
第 3 步:随机测试
修改CMakeLists.txt
以包含
set(CPACK_SOURCE_IGNORE_FILES "projectA")
并重新运行上面的 CMake / Make 命令会产生一个空的源 tarball,但使用与上面相同的二进制 tarball。我现在已经意识到,更改目录树以使顶级目录testproject
(与其子文件夹不同)不会导致空的源 tarball,并且只会删除中列出的文件CPACK_SOURCE_IGNORE_FILES