(TL; DR在底部)
我有一个c ++项目,我可以使用
成功编译mkdir build && cd build
cmake ..
make
但是,因为我不希望我的云同步程序同步这个,所以我将此文件夹命名为build
,而不是_#build
。这导致make输出:
/bin/sh: -c: line 0: unexpected EOF while looking for matching `"'
/bin/sh: -c: line 1: syntax error: unexpected end of file make: ***
[Makefile:190: cmake_check_build_system] Error 1
在尝试使用构建文件夹的不同名称之后 - 例如`~build~似乎有用 - 我注意到当dirname包含#标记符号时,cmake的输出相差一行。
- 检测CXX编译功能 - 失败
没有标签,它表示"已完成"而不是"失败"。
对于这个特定情况,我只是告诉我的同步工具也忽略名为" build"的目录。并且只是使用了dirname" build",但我仍然想知道如果我想在名称中保留主题标签,我将如何解决这个问题。这是我的问题:如何在名称中包含#
的目录中成功运行make?
请注意,这发生在cygwin上,我不确定这是否也会发生在本机bash shell上。
首次修改
根据Patrick Kelly的建议,我尝试将Makefile中路径中的所有出现从_#build
替换为_\#build
。我是手动完成的,并确保在使用sed
时没有其他事件发生。
当我尝试运行make
时,这不起作用,所以我试图在任何子文件夹中的任何文件中替换_#build
的每个出现 - 我认为不会出现任何问题。路径。只是为了确保没有任何改变。所以我做的是:
$ grep --null -l '_#build' -r . | xargs -0 sed -i 's/_#build/_\\#build/g'
我真的不明白为什么我必须逃避反斜杠,我认为单引号没有评估它。但无论如何,这也没有用。此命令的简短说明:grep列出所有子文件夹(-l
)中找到的所有文件名(-r
),并用nullcharacteres(--null
)分隔它们,以便xargs将sed应用于所有这些文件。 sed命令本身替换文件中的所有出现。
现在的问题:
make
Call Stack (most recent call first):
/usr/share/cmake-3.6.2/Modules/CMakeSystemSpecificInformation.cmake:36 (include)
CMakeLists.txt:5 (PROJECT)
-- Configuring incomplete, errors occurred!
See also "/cygdrive/c/Users/myUser/Documents/temp/_#build/CMakeFiles/CMakeOutput.log".
See also "/cygdrive/c/Users/myUser/Documents/temp/_#build/CMakeFiles/CMakeError.log".
make: *** [Makefile:190: cmake_check_build_system] Error 1
CMakeError.log包含"运行构建命令"并且对于"检测CXX [-std = c ++ 14]编译器功能......"以下(不粘贴整件事)。 检测到CXX [-std = c ++ 14]编译器功能无法使用以下输出进行编译:
Change Dir: /cygdrive/c/Users/myUser/Documents/temp/_\#build/CMakeFiles/CMakeTmp
Run Build Command:"/usr/bin/make.exe" "cmTC_1dcec/fast"
/usr/bin/make -f CMakeFiles/cmTC_1dcec.dir/build.make CMakeFiles/cmTC_1dcec.dir/build
make[1]: Entering directory '/cygdrive/c/Users/myUser/Documents/temp/_\#build/CMakeFiles/CMakeTmp'
make[1]: *** No rule to make target '/cygdrive/c/Users/myUser/Documents/temp/_', needed by 'CMakeFiles/cmTC_1dcec.dir/feature_tests.cxx.o'. Stop.
显然,我在太多地方插入了反斜杠,是吧?
简单的解决方案:我不需要在Makefile中更改所有出现的内容。我需要更换的内容:
CMAKE_BINARY_DIR = "/cygdrive/c/Users/myUser/Documents/temp/_\#build"
我必须离开的原因是:
all: cmake_check_build_system
$(CMAKE_COMMAND) -E cmake_progress_start "/cygdrive/c/Users/myUser/Documents/temp/t/_#build/CMakeFiles" "/cygdrive/c/Users/myUser/Documents/temp/t/_#build/CMakeFiles/progress.marks"
$(MAKE) -f CMakeFiles/Makefile2 all
$(CMAKE_COMMAND) -E cmake_progress_start "/cygdrive/c/Users/Eric/Documents/temp/t/_#build/CMakeFiles" 0
此外,无需更改Makefile以外的任何其他文件。
TL; DR
仅将
CMAKE_BINARY_DIR
更改为CMAKE_BINARY_DIR = "/cygdrive/c/Users/myUser/Documents/temp/_\#build"
因为我需要替换的路径是Makefile中的第一次出现,所以下面的bash命令为我自动化了它。
sed -i 's/_#build/_\\#build/' Makefile
答案 0 :(得分:1)
问题在于make
使用#符号进行评论。当cmake
创建Makefile时,生成的其中一行将为您设置构建目录。像这样:
CMAKE_BINARY_DIR = "/home/Patrick/TEMP/_#build"
但由于#符号用于注释,make
不使用shell执行的所有相同转义规则,因此忽略该行的build"
部分。这将创建一个非终止字符串。没有CMake机制可以让您自动修复此问题。用户无法覆盖CMakeLists.txt
文件中CMAKE_BINARY_DIR的定义。这是cmake
生成和管理的特殊变量。因此,实现此功能的唯一方法是在运行Makefile
后手动编辑cmake
,并在#符号前添加转义字符:
CMAKE_BINARY_DIR = "/home/Patrick/TEMP/_\#build"
如果您愿意在cmake
命令后手动编辑,则可以使其正常工作。或者,如果您真的非常,那么您可以编写自己的shell脚本,以便为您更改Makefile
,并在cmake
之后运行命令。类似的东西:
mkdir _#build && cd _#build
cmake ..
fix_makefile.sh
make