CMake编译gtkmm4报错:error adding symbols: DSO missing from command line
解决gtkmm-4.0 CMake构建时链接错误的问题
问题场景
在Ubuntu 22.10环境下将gtkmm-4的命令行编译转为CMake构建时,出现链接错误,但直接用g++命令编译完全正常。
CMake配置与构建的错误输出
raphy@raohy:~/gtkmm-prj$ cmake -B build -- The CXX compiler identification is GNU 12.3.0 -- 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 -- Found PkgConfig: /usr/bin/pkg-config (found version "1.8.1") -- Checking for module 'gtkmm-4.0' -- Found gtkmm-4.0, version 4.10.0 -- Checking for module 'giomm-2.68' -- Found giomm-2.68, version 2.76.0 -- Configuring done (0.4s) -- Generating done (0.0s) -- Build files have been written to: /home/raphy/gtkmm-prj/build raphy@raohy:~/gtkmm-prj$ cmake --build build [ 50%] Building CXX object CMakeFiles/basic.dir/src/basic.cc.o [100%] Linking CXX executable basic /usr/bin/ld: CMakeFiles/basic.dir/src/basic.cc.o: undefined reference to symbol '_ZN4Glib7ustringD1Ev' /usr/bin/ld: /lib/x86_64-linux-gnu/libglibmm-2.68.so.1: error adding symbols: DSO missing from command line collect2: error: ld returned 1 exit status gmake[2]: *** [CMakeFiles/basic.dir/build.make:97: basic] Error 1 gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/basic.dir/all] Error 2 gmake: *** [Makefile:91: all] Error 2
正常工作的命令行编译命令
raphy@raohy:~/gtkmm-prj$ g++ src/basic.cc -o basic `pkg-config --cflags --libs gtkmm-4.0` raphy@raohy:~/gtkmm-prj$ ./basic
原CMakeLists.txt内容
cmake_minimum_required(VERSION 3.24) project(tutorial01 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) find_package(PkgConfig REQUIRED) pkg_check_modules(gtkmm-4.0 REQUIRED IMPORTED_TARGET gtkmm-4.0) pkg_check_modules(giomm-2.68 REQUIRED IMPORTED_TARGET giomm-2.68) add_executable(basic src/basic.cc) target_compile_options(basic PUBLIC ${gtkmm-4.0_CFLAGS_OTHER} ${giomm-2.68}) target_include_directories(basic PUBLIC ${gtkmm-4.0_INCLUDE_DIRS} ${giomm-2.68_INCLUDE_DIRS}) target_link_libraries(basic PUBLIC gtkmm-4.0 giomm-2.68 )
问题分析
- 链接目标使用错误:使用
pkg_check_modules时添加了IMPORTED_TARGET参数,意味着要通过PkgConfig::<模块名>的形式引用目标,但原代码直接用模块名链接,导致CMake没有正确引入所有依赖的链接库(比如glibmm)。 - 编译选项参数错误:
target_compile_options里的${giomm-2.68}是错误的,应该是${giomm-2.68_CFLAGS_OTHER}。 - 冗余依赖指定:gtkmm-4.0本身已经依赖giomm,通过pkg-config会自动处理依赖链,不需要单独指定giomm-2.68的检查。
修改后的CMakeLists.txt
cmake_minimum_required(VERSION 3.24) project(tutorial01 LANGUAGES CXX) set(CMAKE_CXX_STANDARD 17) find_package(PkgConfig REQUIRED) # 只需要检查gtkmm-4.0,其依赖会自动被处理 pkg_check_modules(gtkmm-4.0 REQUIRED IMPORTED_TARGET gtkmm-4.0) add_executable(basic src/basic.cc) # 使用PkgConfig::前缀的目标,自动包含编译选项、头文件和链接库 target_link_libraries(basic PUBLIC PkgConfig::gtkmm-4.0 )
说明
- 使用
PkgConfig::gtkmm-4.0目标后,CMake会自动从pkg-config获取并应用所有必要的编译标志、头文件路径和链接库,无需手动设置target_compile_options和target_include_directories。 - 去掉了对giomm-2.68的单独检查,因为gtkmm-4.0的pkg-config文件已经包含了该依赖,CMake会自动递归处理所有间接依赖。
内容的提问来源于stack exchange,提问作者Raphael10
相关产品推荐
相关产品推荐

