问题描述
我尝试在CMakeLists.txt文件中使用-rdynamic
选项,如下所示:
cmake_minimum_required(VERSION 3.5)
project(Tmuduo CXX)
...
set(CMAKE_CXX_STANDARD 11)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads required)
if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
add_compile_options(-Wthread-safety )
endif()
add_compile_options(
# -DVALGRIND
-Wall
-Wno-unused-parameter
-Woverloaded-virtual
-Wpointer-arith
-Wwrite-strings
-O3
-rdynamic
)
...
当我使用cmake .. -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER=clang
和make VERBOSE=1
时,收到如下消息:
正如您所看到的,-rdynamic
编译选项确实出现在clang ++命令中,并且编译器还抱怨该参数未使用。但是当我使用下面的命令时,发生了一些奇怪的事情。
clang++ -I/home/phoenix/MyProject/Tmuduo -g -Wthread-safety -Wall -Wno-unused-parameter -Woverloaded-virtual -Wpointer-arith -Wwrite-strings -rdynamic -std=gnu++11 test/Exception_test.cc base/Exception.cc base/CurrentThread.cc -o exception_test -O3
一切顺利。这次,-rdynamic
选项有效。那实在使我感到困惑。谁能告诉我这是怎么回事?为什么cmake失败时clang ++命令可以工作?
解决方法
因为-rdynamic
是链接器选项,所以如果在将源文件编译为对象*.o
时使用它,则它什么都不做,因此这里没有链接阶段。
将所有*.o
和库链接到最终可执行文件时,便会实际使用它。
来自man gcc
(但clang使用相同的语言):
-rdynamic
Pass the flag -export-dynamic to the ELF linker,on targets that support it.
This instructs the linker to add all symbols,not only used ones,to the
dynamic symbol table. This option is needed for some uses of "dlopen" or to
allow obtaining backtraces from within a program.