xmake-io / xmake

🔥 A cross-platform build utility based on Lua
https://xmake.io
Apache License 2.0
10.02k stars 781 forks source link

debug模式编译时,最后把obj链接成可执行程序时参数漏掉了-g -O0 #2509

Open heheda123123 opened 2 years ago

heheda123123 commented 2 years ago

Xmake 版本

2.6.8

操作系统版本和架构

Windows 11

描述问题

xmake create一个新项目 xmake.lua中添加依赖

add_rules("mode.debug", "mode.release")
add_requires("spdlog")

target("test_spd")
    set_kind("binary")
    add_files("src/*.cpp")
    add_packages("spdlog")

配置 mingw x86_64 debug mingw 执行构建命令 xmake build -v -D

PS C:\Users\Administrator\temp\test_spd\test_spd> xmake build -v -D
[ 25%]: ccache compiling.debug src\main.cpp
C:\msys64\mingw64\bin\x86_64-w64-mingw32-g++ -c -m64 -g -O0 -isystem C:\Users\Administrator\AppData\Local\.xmake\packages\s\spdlog\v1.10.0\951a3e64909845aea6e64baf5b2b3038\include -o c:\Users\Administrator\temp\test_spd\test_spd\build\.objs\test_spd\mingw\x86_64\debug\src\main.cpp.obj src\main.cpp
[ 50%]: linking.debug test_spd.exe
C:\msys64\mingw64\bin\x86_64-w64-mingw32-g++ -o c:\Users\Administrator\temp\test_spd\test_spd\build\mingw\x86_64\debug\test_spd.exe c:\Users\Administrator\temp\test_spd\test_spd\build\.objs\test_spd\mingw\x86_64\debug\src\main.cpp.obj -m64

build cache stats:
cache directory: c:\Users\Administrator\temp\test_spd\test_spd\build\.build_cache
cache hit rate: 100%
cache hit: 1
cache miss: 0
new cached files: 0
remote cache hit: 0
remote new cached files: 0
preprocess failed: 0
compile fallback count: 0

[100%]: build ok!

可以看到在把obj最后合成exe的时候,编译参数没带-g -O0。导致最后编译出来的程序用gdb调试的时候存在问题

期待的结果

对于debug模式,在把obj链接成可执行程序的时候也带上-O0 -g (另外除了mingw,其他的也可以看看是否存在类似的情况

工程配置

No response

附加信息和错误日志

No response

waruqi commented 2 years ago

应该只需要加上 -g 就行了,跟 -O0 无关。。而且仅仅 windows 上需要。

主要是 windows 上 debug symbols 需要 linker 带上,因为生成 pdb 符号需要同时传递到 linker,之前只对 clang 加了, gcc 没加 https://github.com/xmake-io/xmake/commit/671cabb77b5421fae4fabecdfe9d0df4adf0ddb8

刚更新了下,你再试试 dev 分支

xmake update -s dev

waruqi commented 2 years ago

如果 ok 了,我就关了,有问题再开

heheda123123 commented 2 years ago

只加-g不行,

PS C:\Users\Administrator\temp\learn_xmkae\learn_xmkae> xmake clean
PS C:\Users\Administrator\temp\learn_xmkae\learn_xmkae> xmake build -v -D
[ 25%]: ccache compiling.debug src\main.cpp
C:\msys64\mingw64\bin\x86_64-w64-mingw32-g++ -c -m64 -g -O0 -isystem C:\Users\Administrator\AppData\Local\.xmake\packages\s\spdlog\v1.10.0\951a3e64909845aea6e64baf5b2b3038\include -o c:\Users\Administrator\temp\learn_xmkae\learn_xmkae\build\.objs\learn_xmkae\mingw\x86_64\debug\src\main.cpp.obj src\main.cpp
[ 50%]: linking.debug learn_xmkae.exe
C:\msys64\mingw64\bin\x86_64-w64-mingw32-g++ -o c:\Users\Administrator\temp\learn_xmkae\learn_xmkae\build\mingw\x86_64\debug\learn_xmkae.exe c:\Users\Administrator\temp\learn_xmkae\learn_xmkae\build\.objs\learn_xmkae\mingw\x86_64\debug\src\main.cpp.obj -m64 -g

build cache stats:
cache directory: c:\Users\Administrator\temp\learn_xmkae\learn_xmkae\build\.build_cache
cache hit rate: 100%
cache hit: 1
cache miss: 0
new cached files: 0
remote cache hit: 0
remote new cached files: 0
preprocess failed: 0
compile fallback count: 0

[100%]: build ok!

调试的话明显看到有些代码还是跳过了

(gdb) b main
Breakpoint 1 at 0x140001790: file src\main.cpp, line 8.
(gdb) run
Starting program: C:\Users\Administrator\temp\learn_xmkae\learn_xmkae\build\mingw\x86_64\debug\learn_xmkae.exe
[New Thread 18256.0x3eac]
[New Thread 18256.0x42c4]
[New Thread 18256.0x6124]

Thread 1 hit Breakpoint 1, main () at src\main.cpp:8
8           cout << a;
(gdb) n
10          spdlog::error("Some error message with arg: {}", 1);
(gdb)
12          spdlog::warn("Easy padding in numbers like {:08d}", 12);
(gdb)
heheda14            spdlog::info("Support for floats {:03.2f}", 1.23456);
(gdb)
[2022-06-30 10:31:14.890] [info] Welcome to spdlog!
16          spdlog::info("{:<30}", "left aligned");
(gdb)
[2022-06-30 10:31:16.207] [error] Some error message with arg: 1
20
(gdb) quit
heheda123123 commented 2 years ago

前面以为可以了是我忘记改配置,用的msvc的工具链,mingw只加-g还是不行。 不过另外一个话题,在windows上用mingw,如果只是-g,gdb调试程序都找不到main 。挺玄学的。

waruqi commented 2 years ago

那要等后面几天才能看看了,理论上 -O0 只是编译选项,不应该对 linker 生效。。你可以先找下相关资料

heheda123123 commented 2 years ago

看了下gcc的文档,链接时确实可以单独优化,还额外包含很多链接时的优化选项,比如合并不同编译单元的常量之类的。

https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

官方给的例子

gcc -c -O2 -flto foo.c
gcc -c -O2 -flto bar.c
gcc -o myprog -flto -O2 foo.o bar.o
waruqi commented 2 years ago

看了下gcc的文档,链接时确实可以单独优化,还额外包含很多链接时的优化选项,比如合并不同编译单元的常量之类的。

https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html

官方给的例子

gcc -c -O2 -flto foo.c
gcc -c -O2 -flto bar.c
gcc -o myprog -flto -O2 foo.o bar.o

那是 lto 用的,专门给 链接时优化的,目前看文档,也就是 开启了 lto 时候,才要求同步优化编译flags 到 linker

To use the link-time optimizer, -flto and optimization options should be specified at compile time and during the final link. It is recommended that you compile all the files participating in the same link with the same options and also specify those options at link time. For example:

其他非 lto 情况下,并没明确说明,你这也没开 lto 。。

因为开了 lto,生成的 .obj 文件里面都是字节码,并没有完整编译,要在 link 阶段再去吧字节码编译到 binary 。。所以需要依赖 -Ox

heheda123123 commented 2 years ago

image 不管怎么说,文档里的意思就是在链接的时候确实是存在优化的。至于上面说那个-flto的例子无关紧要吧,我只是想说明在编译时确实是存在优化的可能。

waruqi commented 2 years ago

因为开了 lto,生成的 .obj 文件里面都是字节码,并没有完整编译,要在 link 阶段再去吧字节码编译到 binary 。。所以需要依赖 -Ox

机制不同,我刚说了,只有 lto 时候,link 阶段会走编译逻辑。。

因为开了 lto,生成的 .obj 文件里面都是字节码,并没有完整编译,要在 link 阶段再去吧字节码编译到 binary 。。所以需要依赖 -Ox

waruqi commented 2 years ago

至于上面说那个-flto的例子无关紧要吧,我只是想说明在编译时确实是存在优化的可能。

但是,不能确定 非 lto 情况下, -Ox 会影响 link。。如果没有明确文档化,也不好乱加 flags 的。。先得找到官方文档,或者相关代码位置

heheda123123 commented 2 years ago

有点难,刚刚对比了下程序的hex,区别主要在于后面的附加数据 image 这块之前也看过,貌似是mingw编译出来的程序特有的,其他平台或者编译器都不会这样干。估计看gcc的文档是找不到的。mingw也没完善的文档可以看

heheda123123 commented 2 years ago

不过同样的工具链用cmake试了下没问题,他倒是没用 -O0,他用的编译参数可以参考下

PS C:\Users\Administrator\temp\learn_cmake> cmake --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=C:\msys64\mingw64\bin\gcc.exe -DCMAKE_CXX_COMPILER:FILEPATH=C:\msys64\mingw64\bin\g++.exe -Sc:/Users/Administrator/temp/learn_cmake -Bc:/Users/Administrator/temp/learn_cmake/build -G Ninja -DCMAKE_VERBOSE_MAKEFILE:BOOL=ON
Not searching for unused variables given on the command line.
-- Configuring done
-- Generating done
-- Build files have been written to: C:/Users/Administrator/temp/learn_cmake/build
PS C:\Users\Administrator\temp\learn_cmake> cmake --build c:/Users/Administrator/temp/learn_cmake/build --config Debug --target all
[1/2] C:\msys64\mingw64\bin\g++.exe  -IC:/tools/vcpkg/installed/x64-mingw-static/include -g -MD -MT CMakeFiles/heheda.dir/main.cpp.obj -MF CMakeFiles\heheda.dir\main.cpp.obj.d -o CMakeFiles/heheda.dir/main.cpp.obj -c C:/Users/Administrator/temp/learn_cmake/main.cpp
[2/2] cmd.exe /C "cd . && C:\msys64\mingw64\bin\g++.exe -g  CMakeFiles/heheda.dir/main.cpp.obj -o heheda.exe -Wl,--out-implib,libheheda.dll.a -Wl,--major-image-version,0,--minor-image-version,0 -LC:/tools/vcpkg/installed/x64-mingw-static/lib -lfmt  -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."
PS C:\Users\Administrator\temp\learn_cmake> start .
waruqi commented 2 years ago

他也就用了个 -g 。。没用 -O0,所以我感觉跟 -O0 还是没啥关系 ,你可以 xmake -v 跟它比下,然后完全照搬挨个测试呗。。

waruqi commented 2 years ago

找搞编译器相关的人确认了下,-O 除了在 lto ,其他时候是不影响 link 的。而且 cmake 也没用到 -O 。。应该还是其他地方的关系。。你可以对比下两者的 .obj 。。比如吧 cmake 生成的 obj 。。拿过来 -g link 后,看看是否 ok

waruqi commented 1 year ago

我试了下,xmake run -d 直接在 msys2 下加载 gdb 断点调试,没发现有跳行问题,你可以先命令行走 gdb 试试。确认下是 否 vscode 下才有问题