Open wagcheg opened 1 week ago
Bot detected the issue body's language is not English, translate it automatically.
Title: GCC’s precompiled header does not work
v2.9.6+20241030
Linux 6.11.5-arch1-1
Recurrence: 1.xmake-v
Compile using precompiled headers
repair: Refer to CMake.
看不懂你要搞啥,
2.修改预编译头 增加#error 3.使用步骤1中的GCC编译命令编译 GCC不能通过编译
你改了预编译头加了 error ,不是当然会编译不过么,这不是正常现象么。。
参考CMake。 1.生成包含设置的预编译头文件的.h文件
为什么一定要参考 cmake 去生成?只要能实现预编译的目的不就行了,这又不是标准,目前仅仅 msvc 下,才会生成
gcc/clang 下不需要。
2.在.h相同的目录生成.h.gch文件
不考虑,这会污染源码目录,最不推荐的方式。所以的中间文件都应该隔离到 build 目录下。
Bot detected the issue body's language is not English, translate it automatically.
I don't understand what you are trying to do.
- Modify the precompiled header and add #error
- Use the GCC compilation command in step 1 to compile. GCC cannot be compiled.
If you changed the precompiled header and added error , of course it won't compile. Isn't this a normal phenomenon? .
Refer to CMake.
- Generate a .h file containing the set precompiled header file
Why must we refer to cmake to generate? As long as the purpose of precompilation can be achieved, it will be fine. This is not a standard. Currently, it is only generated under msvc.
Not required under gcc/clang.
- Generate .h.gch file in the same directory as .h
Regardless, this will pollute the source code directory, which is the least recommended way. Therefore, all intermediate files should be isolated to the build directory.
[pch]$ xmake -v && cmake -G Ninja && ninja -v checking for platform ... linux checking for architecture ... x86_64 checking for gcc ... /usr/bin/gcc checking for zig ... no checking for zig ... no checking for nim ... no checking for nim ... no checking for gcc ... /usr/bin/gcc checking for the c++ compiler (cxx) ... gcc checking for /usr/bin/gcc ... ok checking for flags (-fPIC) ... ok checking for flags (-Winvalid-pch) ... ok checking for flags (-H) ... ok [ 25%]: cache compiling.release PCH/pch.h /usr/bin/gcc -c -m64 -IPCH -IPCH1 -I build/.objs/pch/linux/x86_64/release/PCH/cxx -Winvalid-pch -H -x c++-header -o build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h.gch PCH/pch.h checking for flags (-MMD -MF) ... ok checking for flags (-fdiagnostics-color=always) ... ok . /usr/include/c++/14.2.1/iostream .. /usr/include/c++/14.2.1/bits/requires_hosted.h ... /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/c++config.h .... /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/os_defines.h ..... /usr/include/features.h ...... /usr/include/features-time64.h ....... /usr/include/bits/wordsize.h ....... /usr/include/bits/timesize.h ........ /usr/include/bits/wordsize.h ...... /usr/include/sys/cdefs.h ....... /usr/include/bits/wordsize.h ....... /usr/include/bits/long-double.h ...... /usr/include/gnu/stubs.h ....... /usr/include/gnu/stubs-64.h .... /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/cpu_defines.h .... /usr/include/c++/14.2.1/pstl/pstl_config.h [ 50%]: cache compiling.release main.cpp /usr/bin/gcc -c -m64 -IPCH -IPCH1 -include pch.h -I build/.objs/pch/linux/x86_64/release/PCH/cxx -Winvalid-pch -H -o build/.objs/pch/linux/x86_64/release/main.cpp.o main.cpp . /usr/include/stdc-predef.h . PCH/pch.h .. /usr/include/c++/14.2.1/iostream ... /usr/include/c++/14.2.1/bits/requires_hosted.h .... /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/c++config.h ..... /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/os_defines.h ...... /usr/include/features.h ....... /usr/include/features-time64.h ........ /usr/include/bits/wordsize.h ........ /usr/include/bits/timesize.h ......... /usr/include/bits/wordsize.h ....... /usr/include/sys/cdefs.h ........ /usr/include/bits/wordsize.h ........ /usr/include/bits/long-double.h ....... /usr/include/gnu/stubs.h ........ /usr/include/gnu/stubs-64.h checking for g++ ... /usr/bin/g++ checking for the linker (ld) ... g++ checking for /usr/bin/g++ ... ok checking for flags (-fPIC) ... ok [ 75%]: linking.release pch /usr/bin/g++ -o build/linux/x86_64/release/pch build/.objs/pch/linux/x86_64/release/main.cpp.o -m64 [100%]: build ok, spent 3.097s CMake Warning: No source or binary directory provided. Both will be assumed to be the same as the current working directory, but note that this warning will become a fatal error in future CMake releases.
CMake Warning (dev) in CMakeLists.txt: No project() command is present. The top-level CMakeLists.txt file must contain a literal, direct call to the project() command. Add a line of code such as
project(ProjectName)
near the top of the file, but after cmake_minimum_required().
CMake is pretending there is a "project(Project)" command on the first line. This warning is for project developers. Use -Wno-dev to suppress it.
CMake Warning (dev) in CMakeLists.txt: cmake_minimum_required() should be called prior to this top-level project() call. Please see the cmake-commands(7) manual for usage documentation of both commands. This warning is for project developers. Use -Wno-dev to suppress it.
-- The C compiler identification is GNU 14.2.1 -- The CXX compiler identification is GNU 14.2.1 -- Detecting C compiler ABI info -- Detecting C compiler ABI info - done -- Check for working C compiler: /usr/bin/cc - skipped -- Detecting C compile features -- Detecting C compile features - done -- Detecting CXX compiler ABI info -- Detecting CXX compiler ABI info - done -- Check for working CXX compiler: /usr/bin/c++ - skipped -- Detecting CXX compile features -- Detecting CXX compile features - done CMake Warning (dev) in CMakeLists.txt: No cmake_minimum_required command is present. A line of code such as
cmake_minimum_required(VERSION 3.30)
should be added at the top of the file. The version specified may be lower if you wish to support older CMake versions for this project. For more information run "cmake --help-policy CMP0000". This warning is for project developers. Use -Wno-dev to suppress it.
-- Configuring done (0.4s) -- Generating done (0.0s) -- Build files have been written to: /home/wc/WorkSpace/pch [1/3] /usr/bin/c++ -I/home/wc/WorkSpace/pch/PCH -I/home/wc/WorkSpace/pch/PCH1 -Winvalid-pch -H -Winvalid-pch -x c++-header -include /home/wc/WorkSpace/pch/CMakeFiles/pch.dir/cmake_pch.hxx -MD -MT CMakeFiles/pch.dir/cmake_pch.hxx.gch -MF CMakeFiles/pch.dir/cmake_pch.hxx.gch.d -o CMakeFiles/pch.dir/cmake_pch.hxx.gch -c /home/wc/WorkSpace/pch/CMakeFiles/pch.dir/cmake_pch.hxx.cxx 多个防止重包含可能对其有用: /home/wc/WorkSpace/pch/CMakeFiles/pch.dir/cmake_pch.hxx /usr/include/asm/errno.h /usr/include/bits/byteswap.h /usr/include/bits/locale.h /usr/include/bits/select.h /usr/include/bits/stdlib-float.h /usr/include/bits/time64.h /usr/include/bits/typesizes.h /usr/include/bits/uintn-identity.h /usr/include/bits/waitflags.h /usr/include/bits/waitstatus.h /usr/include/c++/14.2.1/clocale /usr/include/c++/14.2.1/cstdio /usr/include/c++/14.2.1/cstdlib /usr/include/c++/14.2.1/cwctype /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/ctype_base.h /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/ctype_inline.h /usr/include/features-time64.h /usr/include/gnu/stubs-64.h /usr/include/gnu/stubs.h /usr/include/linux/errno.h [2/3] /usr/bin/c++ -I/home/wc/WorkSpace/pch/PCH -I/home/wc/WorkSpace/pch/PCH1 -Winvalid-pch -H -Winvalid-pch -include /home/wc/WorkSpace/pch/CMakeFiles/pch.dir/cmake_pch.hxx -MD -MT CMakeFiles/pch.dir/main.o -MF CMakeFiles/pch.dir/main.o.d -o CMakeFiles/pch.dir/main.o -c /home/wc/WorkSpace/pch/main.cpp ! /home/wc/WorkSpace/pch/CMakeFiles/pch.dir/cmake_pch.hxx.gch . /home/wc/WorkSpace/pch/PCH/pch.h [3/3] : && /usr/bin/c++ -rdynamic CMakeFiles/pch.dir/main.o -o pch && :
https://gcc.gnu.org/onlinedocs/libstdc++/manual/using_headers.html -Winvalid-pch -H的用法可以在这里找到
另外请考虑使用common/stdafx.h和stdafx.h这样的情况 set_pcxxheader(“common/stdafx.h”)应该能使用common/stdafx.h对应的预编译头而不是存在于包含路径中的stdafx.h 这是我发现xmake的gch有问题的起因
Bot detected the issue body's language is not English, translate it automatically.
Also consider using common/stdafx.h and stdafx.h like this set_pcxxheader("common/stdafx.h") should be able to use the precompiled header corresponding to common/stdafx.h instead of stdafx.h that exists in the include path This is the reason why I found a problem with xmake's gch
还是不懂你在说啥,遇到的是什么问题
Bot detected the issue body's language is not English, translate it automatically.
I still don’t understand what you are talking about and what problem you are encountering.
首先GCC对于使用预编译头和强制包含头文件是一样的语法 大部分情况就算预编译头不生效也时能编译通过的 因此需要有个方法来确定预编译头是否生效
1.可以添加-H来检测预编译头是否被使用 https://gcc.gnu.org/onlinedocs/gcc/Preprocessor-Options.html Print the name of each header file used, in addition to other normal activities. Each name is indented to show how deep in the ‘#include’ stack it is. Precompiled header files are also printed, even if they are found to be invalid; an invalid precompiled header file is printed with ‘...x’ and a valid one with ‘...!’ .
1.1xmake的命令行 输出无gch文件 /usr/bin/gcc -c -m64 -IPCH -include pch.h -I build/.objs/pch/linux/x86_64/release/PCH/cxx -Winvalid-pch -H -o build/.objs/pch/linux/x86_64/release/main.cpp.o main.cpp . /usr/include/stdc-predef.h . PCH/pch.h .. /usr/include/c++/14.2.1/iostream ... /usr/include/c++/14.2.1/bits/requires_hosted.h .... /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/c++config.h ..... /usr/include/c++/14.2.1/x86_64-pc-linux-gnu/bits/os_defines.h ...... /usr/include/features.h ....... /usr/include/features-time64.h ........ /usr/include/bits/wordsize.h ........ /usr/include/bits/timesize.h ......... /usr/include/bits/wordsize.h ....... /usr/include/sys/cdefs.h ........ /usr/include/bits/wordsize.h ........ /usr/include/bits/long-double.h ....... /usr/include/gnu/stubs.h ........ /usr/include/gnu/stubs-64.h
1.2将gch所在目录提到最前 输出里包含gch但是编译错误(原因不明 gcc 14.2.1 20240910)
/usr/bin/gcc -c -m64 -I build/.objs/pch/linux/x86_64/release/PCH/cxx -IPCH -include pch.h -Winvalid-pch -H -o build/.objs/pch/linux/x86_64/release/main.cpp.o main.cpp
! build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h.gch
main.cpp:1:10: 致命错误:build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h:没有那个文件或目录
1 | #include "pch.h"
| ^~~
编译中断。
1.3一个正常的命令行(尽管没有build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h也能识别到gch) /usr/bin/gcc -c -m64 -IPCH -include build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h -Winvalid-pch -H -o build/.objs/pch/linux/x86_64/release/main.cpp.o main.cpp ! ./build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h.gch
2.在不被当成预编译头后 命令行实际意义为强制包含文件 -include包含的是文件名而不是完整路径 存在被搜索路径干扰的问题
3.gch不生效后内存占用增多 内存不足触发swap 大多数gcc进程卡在d状态 cpu跑不满
最小可复现工程 tree -a . ├── main.cpp ├── PCH │ └── pch.h └── xmake.lua
cat main.cpp
int main() { return 0; }
cat xmake.lua target("pch") add_files("*.cpp") add_includedirs("PCH") set_pcxxheader("PCH/pch.h") add_cxxflags("-Winvalid-pch") add_cxxflags("-H")
cat PCH/pch.h
你这表述的也太琐碎了,抓不到重点,看了半天才看明白咋回事。。。还不如直接说 pch 没生效,然后给个完整复现 demo 不就完事了么。。
这里主要有几个问题导致:
xmake f --ccache=n
或者 set_policy("build.ccache", false)
禁用这两处理了,pch 就可以生效了。
至于你说的
-include
完整路径,这个不是关键,同样会被 -IPCH 干扰,而且绝对路径这边不考虑至于 ccache 那个问题
-H
不会输出任何东西Bot detected the issue body's language is not English, translate it automatically.
Your expression is too trivial and misses the point. It took me a long time to understand what was going on. . . It would be better to just say that pch does not take effect, and then give a complete reproduction demo and be done with it. .
There are several main problems here:
xmake f --ccache=n
or set_policy("build.ccache", false)
After these two steps are taken care of, pch can take effect.
As for what you said
-include
full path, this is not critical, it will also be interfered by -IPCH, and the absolute path is not considered hereAs for the ccache issue
-H
will not output anything.把gch换个名字能解决 [wc@wc pch]$ mv build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h.gch build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.hxx.gch [wc@wc pch]$ /usr/bin/gcc -c -m64 -I build/.objs/pch/linux/x86_64/release/PCH/cxx -include pch.hxx -IPCH -Winvalid-pch -H -o build/.objs/pch/linux/x86_64/release/main.cpp.o main.cpp ! build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.hxx.gch
Bot detected the issue body's language is not English, translate it automatically.
5896 will cause compilation errors. The command line called is the same as the 1.2 I added the second time.
Changing the name of gch can solve the problem [wc@wc pch]$ mv build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h.gch build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.hxx .gch [wc@wc pch]$ /usr/bin/gcc -c -m64 -I build/.objs/pch/linux/x86_64/release/PCH/cxx -include pch.hxx -IPCH -Winvalid-pch -H -o build/.objs/pch/linux/x86_64/release/main.cpp.o main.cpp ! build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.hxx.gch
我这里可以,没啥问题
ruki@f276d0cf2cba:/tmp/test$ tree .
.
|-- PCH
| `-- pch.h
|-- main.cpp
`-- xmake.lua
1 directory, 3 files
ruki@f276d0cf2cba:/tmp/test$ xmake f -c --ccache=n
checking for platform ... linux
checking for architecture ... x86_64
ruki@f276d0cf2cba:/tmp/test$ xmake -rv
checking for gcc ... /usr/bin/gcc
checking for the c++ compiler (cxx) ... gcc
checking for /usr/bin/gcc ... ok
checking for flags (-fPIC) ... ok
checking for flags (-fvisibility-inlines-hidden) ... ok
checking for flags (-O3) ... ok
checking for flags (-Winvalid-pch) ... ok
checking for flags (-H) ... ok
checking for flags (-DNDEBUG) ... ok
[ 25%]: compiling.release PCH/pch.h
/usr/bin/gcc -c -m64 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -I build/.objs/pch/linux/x86_64/release/PCH/cxx -IPCH -Winvalid-pch -H -DNDEBUG -x c++-header -o build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h.gch PCH/pch.h
checking for flags (-MMD -MF) ... ok
checking for flags (-fdiagnostics-color=always) ... ok
PCH/pch.h:2:9: warning: #pragma once in main file
2 | #pragma once
| ^~~~
[ 50%]: compiling.release main.cpp
/usr/bin/gcc -c -m64 -fvisibility=hidden -fvisibility-inlines-hidden -O3 -I build/.objs/pch/linux/x86_64/release/PCH/cxx -include pch.h -IPCH -Winvalid-pch -H -DNDEBUG -o build/.objs/pch/linux/x86_64/release/main.cpp.o main.cpp
! build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h.gch. <--------
checking for g++ ... /usr/bin/g++
checking for the linker (ld) ... g++
checking for /usr/bin/g++ ... ok
checking for flags (-fPIC) ... ok
[ 75%]: linking.release pch
/usr/bin/g++ -o build/linux/x86_64/release/pch build/.objs/pch/linux/x86_64/release/main.cpp.o -m64 -s
[100%]: build ok, spent 0.74s
ruki@f276d0cf2cba:/tmp/test$ cat ./xmake.lua
add_rules("mode.debug", "mode.release")
target("pch")
add_files("*.cpp")
add_includedirs("PCH")
set_pcxxheader("PCH/pch.h")
add_cxxflags("-Winvalid-pch")
add_cxxflags("-H")
你的main.cpp里是不是没有#include "pch.h"
Bot detected the issue body's language is not English, translate it automatically.
Is there no #include "pch.h" in your main.cpp?
你的main.cpp里是不是没有#include "pch.h"
之前被我改成了 #include "PCH/pch.h"
,改回去后,是有这个问题,但按理 gcc 应该能找到才对,search dir 已经靠前了,既然 pch.hxx 可以,按理 pch.h 应该也可以。。gcc的行为很怪。
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/11"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/11/include-fixed"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/11/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
build/.objs/pch/linux/x86_64/release/PCH/cxx
/usr/include/c++/11
/usr/include/x86_64-linux-gnu/c++/11
/usr/include/c++/11/backward
/usr/lib/gcc/x86_64-linux-gnu/11/include
/usr/local/include
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
GNU C++17 (Ubuntu 11.4.0-1ubuntu1~22.04) version 11.4.0 (x86_64-linux-gnu)
compiled by GNU C version 11.4.0, GMP version 6.2.1, MPFR version 4.1.0, MPC version 1.2.1, isl version isl-0.24-GMP
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: d591828bb4d392ae8b7b160e5bb0b95f
! build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h.gch
main.cpp:1:10: fatal error: build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h: No such file or directory
1 | #include "pch.h"
其实 gcc 已经找到 pch.h.gch 了。。看来改了 .gch 做隔离,还是得塞个 pch.h 到 gch 对应目录下才行。。否则行为不可靠,蛋疼。还是 clang 靠谱。
Bot detected the issue body's language is not English, translate it automatically.
Is there no #include "pch.h" in your main.cpp?
I changed it to #include "PCH/pch.h"
before. After changing it back, I still have this problem, but it stands to reason that gcc should be able to find it. The search dir is already at the front. Since pch.hxx can be found, it stands to reason. pch.h should also work. . gcc behaves strangely.
再试下。https://github.com/xmake-io/xmake/pull/5902 但还是得先禁用下 ccache
再试下上面的 patch,gcc 下 ccache 也支持了,加了个 -fpch-preprocess
flag, https://musescore.org/en/node/182331
而 clang 下,本身就通过 -include-pch 在预处理阶段展开了,所以原本就是支持 ccache 的,但是在开启 ccache 下,每个预处理文件,都提前全部展开了,相比 no ccache + pch 反而会慢不少,这个暂时不管了,等后面有更好的方案再优化
ruki@f276d0cf2cba:/tmp/test$ rm -rf build/; xmake f -c; xmake -r
checking for platform ... linux
checking for architecture ... x86_64
[ 25%]: cache compiling.release PCH/pch.h
PCH/pch.h:2:9: warning: #pragma once in main file
2 | #pragma once
| ^~~~
[ 50%]: cache compiling.release main.cpp
! build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h.gch
. build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h
Multiple include guards may be useful for:
build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h
. /usr/include/stdc-predef.h
<command-line>
. build/.objs/pch/linux/x86_64/release/PCH/cxx/pch.h
[ 75%]: linking.release pch
[100%]: build ok, spent 0.789s
Xmake 版本
v2.9.6+20241030
操作系统版本和架构
Linux 6.11.5-arch1-1
描述问题
复现: 1.xmake -v 2.修改预编译头 增加#error 3.使用步骤1中的GCC编译命令编译 GCC不能通过编译
期待的结果
使用预编译头编译通过
工程配置
pch.zip
附加信息和错误日志
修复: 参考CMake。 1.生成包含设置的预编译头文件的.h文件 2.在.h相同的目录生成.h.gch文件 3.只需要增加编译选项-include 生成.h文件的完整路径