- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
(抱歉:从 CMake 邮件列表交叉发布)
我正在尝试了解 CMake 的正则表达式实现;我有一个包含 4 个文件夹和 2 个文本文件的文件夹,如下所示:
build/
projectA/
CMakeLists.txt
extrafiles/
README
temp/
CMakeLists.txt 的一行是:
set(CPACK_SOURCE_IGNORE_FILES "[^projectA]$")
在随后生成的源包中,存在 build/
、projectA/
和 extrafiles
,但 temp/
而 2 个文本文件则不是。我正在尝试进入正则表达式将忽略文件夹中除 projectA/
、README
和 CMakeLists.txt
之外的所有内容的阶段,但目前无法弄清楚我的正则表达式如何提供的是给出这些结果。
我想这归结为如何使用正则表达式匹配整个字符串。我意识到文档说匹配不在括号内的任何字符
,这就是我猜错的地方......
进一步探索
在尝试理解 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
重命名为其实际名称,我最终得到一个空 tarball!啊!我完全不知道 CMake 对我玩什么奇怪的把戏,但我只想哭。
任何见解都将不胜感激!
独立示例
As requested作者:Fraser,这是一个独立的示例,显示了我所描述的 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
中,运行:
chris@chris:~/projectA$ cmake -H. -Bbuild
然后:
make -C build && make -C build package && make -C build package_source
这会在 build
文件夹中生成 2 个 tarball。将它们移至其他位置并解压它们,会在二进制 tarball 中显示 helloworld
(如预期),以及来自 ~/projectA/projectA
的所有内容源 tarball,包括 test.sh
,它不会被编译(Fraser 似乎对此感到惊讶)
第 3 步:随机测试
修改 CMakeLists.txt
以包含
set(CPACK_SOURCE_IGNORE_FILES "projectA")
并重新运行上面的 CMake/Make 命令会产生一个空的源 tarball,但具有与上面相同的二进制 tarball。我现在意识到,更改目录树以使顶级目录为 testproject
(因此与其子文件夹不同)不会导致空的源 tarball,并且仅删除 CPACK_SOURCE_IGNORE_FILES
最佳答案
我认为您无法实现使用 [请参阅编辑末尾的更新答案。]CPACK_SOURCE_IGNORE_FILES
之后的目标(虽然我不确定)。正如您正确指出的那样,CMake 的正则表达式处理允许排除字符组,但我认为它不允许否定整个模式。
话虽如此,我想您可以在 install
中列出您希望排除的所有文件夹。命令。不像排除“projectA”之外的所有内容那样强大,但语法仍然如下:
install(DIRECTORY .
DESTINATION the_install_subdir
REGEX "build|extrafiles|temp+" EXCLUDE)
关于空的 tarball,我想你可能有 <name of my project>
既作为项目的根目录又作为子目录?因此,在您的示例中,如果您将项目命名为“projectA”,那么您将拥有“projectA/build”、“projectA/projectA”等。
如果是这样,正则表达式将在完整路径上运行,因此项目中的所有文件都将包含 projectA/
在他们的路径内。
至于哭……好吧,我只能建议你控制住自己,振作起来! :-)
<小时/>编辑:为了回应评论,这里有一个使用 install
的快速示例。实现目标的命令:
install(DIRECTORY projectA
DESTINATION the_install_subdir)
install(FILES CMakeLists.txt README DESTINATION the_install_subdir)
<小时/>
进一步编辑:
好吧,你的例子很有帮助 - 我确实误解了你在做什么。我没有意识到你实际上正在制作两个不同的目标(“package”和“package_source”)。我原以为您正在通过执行类似的操作来创建二进制包
cpack -G DEB
并且您正在通过执行以下操作创建另一个包
cpack -G TGZ
它们都构建了二进制包。我的错误——我应该更加注意。抱歉!
至于您的具体问题:
问题1
It seems to me that installing files / directories that aren't compiled but are at the same level as the folder containing all the compiled files (i.e. bin), and then ignoring the bin folder using CPACK_SOURCE_IGNORE_FILES results in an empty tarball - is this correct?
我认为这意味着:“执行 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
,那么正则表达式“build”将匹配项目中的每个文件,因为每个文件都包含“test_builds”;导致一个空的 tarball。
我认为这是每次生成空 tarball 时问题的症结所在。无论正则表达式试图实现什么目的,它实际上最终都会匹配并排除所有文件。
问题2
It also seems that files in the
CMAKE_SOURCE_DIR
which aren't 'installed' don't end up in the binary tarball but do end up in the source tarball
是的,“package_source”确实是二进制包的不同目标。默认情况下,它包含 ${CMAKE_SOURCE_DIR}
中的所有 文件。 ,而“package”目标仅包含通过 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}")
希望这现在对您有用。再次抱歉误导了您。
关于cmake - CPack : Ignoring files using regex,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17935748/
我为几个操作系统版本创建软件包,包括 RHEL7 和 RHEL8(或者几乎同样是 CentOS7 和 8)。 可以安装为 .el7 构建的包。在 .el8 上。但它通常不起作用(例如由于 undefi
我有一个 CMake由一个根组成的项目 CMakeLists和多个子CMakeLists (每个项目一个)。 我正在尝试使用 CPack为这些项目之一 (APP_client) 生成 .deb 文件。
我有一个 CMake 项目来构建多个共享库和工具,其中大部分位于子目录下: add_directory(libFirst) add_directory(libSecond) add_directory
我有一个使用 CMake 构建的相当复杂的项目。该项目使用 CPack 生成 .deb 包。当我刚刚用 make 构建项目时(即不构建 .deb)一个干净的构建大约需要 2 分钟。但是,当我使用 ma
我希望 cpack 仅采用某些组件。但他同时使用 run 和 deb 组件。我查看了很多资料来源。包括这个cpack component level install 。但我不明白我做错了什么。请告诉我
我使用 cpack (CMake 3.0.2) 从我的源构建 RPM。我在构建预安装目标时出错,它说: CPack Error: Problem running install command: "
对于附加到 CMake wiki 的示例 CMakeLists.txt。我还在下面添加了实际的 make 命令来创建基于组件的 TGZ。我很困惑,在文档中没有看到任何帮助。 CMakeLists.tx
我在使用 CPack 和 CMake 创建两个 debian 软件包时遇到了问题。我已经完成了 here 中的示例我确实设法创建了两个不同的 debian 包,但我希望它们每个都有自己的依赖项。生成的
EDIT =================== apr-1 是 apache 可移植运行时,我自己下载并编译以创建共享库(因此它不是由 cmake 制作的)。在目标系统上运行 CPack 后,我需要
我正在一个发行版中构建两个包: 运行时共享库包 开发库包 问题是在其中任何一个中包含正确的符号链接(symbolic link)。目前我使用: set_target_properties(myli
我正在使用 CMake 2.8.11.2、CPack 和 NSIS 编写安装程序。我到了需要调用包含的子安装程序(如 MSVCR)的地步。这是我的 CMakeLists.txt 的样子: set(CP
我正在使用 CPack WIX 生成器来创建安装程序。安装程序需要在目标系统上的 %ALLUSERSPROFILE%\foo\文件夹中安装一个文件。 我找不到在安装树 (C:\Program File
我想重命名 CPack (v2.8.7) 生成的安装程序文件,以包含在构建时从版本控制系统获取的版本号。看来这不能通过设置 CPACK_* 变量来完成,因为这发生在“cmake”时间。 我想要做的是运
因此,有多种方法可以在 CMake 处复制文件(和目录)。运行时(file(COPY ...)、configure_file(...) 和 add_custom_command() 都可以工作*),但
语境 我有一个使用 CMake 3.17 构建的托管 C++/CLR 库,并使用 CPack 打包到 NuGet 包中。生成的 nupkg 文件无法导入 C# 项目,因为包管理器发出以下错误:“[sn
我想使用 cmake 和 cpack 在 Windows 上为某些程序创建安装程序。我希望能够选择要安装的程序,并且所选程序应作为快捷方式显示在开始菜单中。这是一个简单的尝试。为每个程序完成一个组件但
我真的很难让 CPack 以我想象的方式运行。我在下面有一个小示例设置,在将它应用到更大的项目之前,我一直在努力工作。本质上,我正在尝试使用 fixup_bundle 来收集所有依赖项并将它们复制到打
看下面这个相当简单的 CMake 文件: cmake_minimum_required(VERSION 3.7) add_library(libdice SHARED lib.cpp) set_tar
我目前正在开发一个 cmake 项目,该项目使用通过 find_package 函数导入的外部库。我的问题围绕着 cpack 以及我应该如何将找到的包添加到 cpack 输出中。例如,如果我使用这个
我需要将库中的所有 header 定位到 /usr/include ,而不是 /usr/include/mylibname 。请注意,我想更改标题的位置。我想将我的 .so 文件保留在 /usr/li
我是一名优秀的程序员,十分优秀!