我在用科学Linux(SL)。我正在尝试编译一个使用一堆 C++ (.cpp) 文件的项目。
在该目录中user/project/Build
,我输入make
编译并链接所有.cpp 文件。然后我必须去user/run/
然后输入./run.sh values.txt
要使用 GDB 进行调试,我必须转到user/run
,然后键入gdb ../project/Build/bin/Project
并运行,我输入run -Project INPUT/inputfile.txt
。但是,我正在尝试使用 打印出变量的值p variablename
。
不过,我收到了消息s1 = <value optimized out>
。我在网上做了一些研究,似乎我需要在没有优化的情况下进行编译来-O0
解决这个问题。但我该在哪里输入呢?在里面CMakeLists
?如果是这样,哪个 CMakeLists?project/Build
或中的一个project/src/project
?
答案1
在调用时,通常使用 CMake 进行调试构建所需的全部内容是:
cmake -DCMAKE_BUILD_TYPE=Debug ..
这样做会添加-g
标志,可以通过以下方式确认:
make VERBOSE=1
其中显示了 GCC 构建命令,如下所述:https://stackoverflow.com/questions/5820303/how-do-i-force-make-gcc-to-show-me-the-commands
-O0
默认情况下不会添加到Debug
构建中,但-O0
它是默认-O
值,如下所述:https://stackoverflow.com/questions/1778538/how-many-gcc-optimization-levels-are-there等等man gcc
,所以通常并不重要。
如果您确实想显式控制调试的构建标志,您也可以使用
cmake -DCMAKE_BUILD_TYPE=Debug
-DCMAKE_C_FLAGS_DEBUG="-g -O0" \
-DCMAKE_CXX_FLAGS_DEBUG="-g -O0" \
..
CMAKE_C_FLAGS_DEBUG
和的默认值CMAKE_CXX_FLAGS_DEBUG
可以在以下位置找到:https://stackoverflow.com/questions/16851084/how-to-list-all-cmake-build-options-and-their-default-values和:
cmake -LAH .
这使:
// Flags used by the CXX compiler during DEBUG builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=-g
// Flags used by the C compiler during DEBUG builds.
CMAKE_C_FLAGS_DEBUG:STRING=-g
该命令还显示了其他感兴趣的值,这些值阐明了构建类型的默认行为:
// Flags used by the CXX compiler during all build types.
CMAKE_CXX_FLAGS:STRING=
// Flags used by the CXX compiler during DEBUG builds.
CMAKE_CXX_FLAGS_DEBUG:STRING=-g
// Flags used by the CXX compiler during MINSIZEREL builds.
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
// Flags used by the CXX compiler during RELEASE builds.
CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
// Flags used by the CXX compiler during RELWITHDEBINFO builds.
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
如果-DCMAKE_BUILD_TYPE=Debug
没有通过,CMAKE_BUILD_TYPE
则为空,并且不会添加任何额外的CMAKE_CXX_FLAGS_XXX
值,因此我们以不带-g
.
在 Ubuntu 22.10、CMake 3.24.2 上测试。
答案2
Chip 的答案很有帮助,但是由于该SET
行覆盖了默认值,导致我的可执行文件在没有调试信息的情况下构建。我需要对项目源目录中的 CMakeLists.txt 进行一些小的额外修改,以获得使用调试信息构建的可执行文件CMAKE_CXX_FLAGS_DEBUG
-g
和 -O0
优化(在 cmake 版本 2.8.12.2 上)。
我将以下内容添加到 CMakeLists.txt 以添加-O0
并保持-g
启用状态:
# Add -O0 to remove optimizations when using gcc
IF(CMAKE_COMPILER_IS_GNUCC)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0")
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
ENDIF(CMAKE_COMPILER_IS_GNUCC)
这会-O0
为 CMake 已用于调试的标志添加优化,并且仅在您碰巧使用跨平台项目时才包含在 GCC 构建中。
答案3
将其添加到 CMakeLists.txt(项目源目录中的那个;不要触及构建目录中的任何内容):
SET(CMAKE_CXX_FLAGS_DEBUG "-O0")
SET(CMAKE_C_FLAGS_DEBUG "-O0")
进而
$ cmake -DCMAKE_BUILD_TYPE=Debug
将工作。或者只需将其添加到 CMakeLists.txt:
SET(CMAKE_CXX_FLAGS "-O0")
SET(CMAKE_C_FLAGS "-O0")
答案4
我发现在一些测试中我CMAKE_C_FLAGS
默认包含一些优化选项(即-O2
)。在这种情况下,上述建议执行类似操作set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -O0")
不会"-O2 -g -O0"
禁用优化。
相反,我成功地使用一个简单的正则表达式"-O#"
在附加之前用空字符串替换"-O0"
。
我的正则表达式可能需要一些微调,但到目前为止它似乎工作得足够好:
option(OPTIMIZE "Allow compiler optimizations. Set to OFF to disable" ON)
if(NOT OPTIMIZE)
string(REGEX REPLACE "(\-O[011123456789])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REGEX REPLACE "(\-O[011123456789])" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O0")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O0")
endif()