You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在CMake中实现shell反引号(`)命令替换以适配png++编译?

使用CMake构建png++项目的问题解决

我正在使用png++库,该库要求通过以下Shell命令编译:

g++ -c example.cpp `libpng-config --cflags`
g++ -o example example.o `libpng-config --ldflags`

这种方式可以正常工作,但我用CLion开发,希望用CMake规范构建(不想直接运行Shell脚本)。试了两种CMakeLists写法都失败,猜测问题出在反引号(`)上,不清楚它的具体含义。

我尝试的两种CMakeLists写法

写法一

cmake_minimum_required(VERSION 3.27)
project(image_proc)

set(CMAKE_CXX_STANDARD 17)

add_executable(image_proc src/main.cpp src/core.h)
add_compile_options(`libpng-config --cflags`)
add_link_options(`libpng-config --ldflags`)

写法二

cmake_minimum_required(VERSION 3.27)
project(image_proc)

set(CMAKE_CXX_STANDARD 17)

SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} `libpng-config --cflags`")
SET(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} `libpng-config --ldflags`")

add_executable(image_proc src/main.cpp src/core.h)

错误输出

====================[ Build | image_proc | Debug ]==============================
/home/saprykin/.local/share/JetBrains/Toolbox/apps/clion-nova/bin/cmake/linux/x64/bin/cmake --build /home/saprykin/image_proc/cmake-build-debug --target image_proc -j 3
[1/1] Linking CXX executable image_proc
FAILED: image_proc 
: && /usr/bin/c++ -g  CMakeFiles/image_proc.dir/src/main.cpp.o -o image_proc   && :
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::info_base::info_base(png::io_base&, png_struct_def*)':
/usr/local/include/png++/info_base.hpp:55: undefined reference to `png_create_info_struct'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::info::write() const':
/usr/local/include/png++/info.hpp:126: undefined reference to `png_set_PLTE'
/usr/bin/ld: /usr/local/include/png++/info.hpp:133: undefined reference to `png_set_tRNS'
/usr/bin/ld: /usr/local/include/png++/info.hpp:147: undefined reference to `png_set_gAMA'
/usr/bin/ld: /usr/local/include/png++/info.hpp:157: undefined reference to `png_write_info'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::info::sync_ihdr() const':
/usr/local/include/png++/info.hpp:172: undefined reference to `png_set_IHDR'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::end_info::destroy()':
/usr/local/include/png++/end_info.hpp:56: undefined reference to `png_destroy_info_struct'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::end_info::write() const':
/usr/local/include/png++/end_info.hpp:66: undefined reference to `png_write_end'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::io_base::set_swap() const':
/usr/local/include/png++/io_base.hpp:315: undefined reference to `png_set_swap'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::io_base::set_interlace_handling() const':
/usr/local/include/png++/io_base.hpp:379: undefined reference to `png_set_interlace_handling'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::io_base::raise_error()':
/usr/local/include/png++/io_base.hpp:449: undefined reference to `png_set_longjmp_fn'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::io_base::raise_error(png_struct_def*, char const*)':
/usr/local/include/png++/io_base.hpp:454: undefined reference to `png_get_error_ptr'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::writer<std::basic_ofstream<char, std::char_traits<char> > >::writer(std::basic_ofstream<char, std::char_traits<char> >&)':
/usr/local/include/png++/writer.hpp:78: undefined reference to `png_create_write_struct'
/usr/bin/ld: /usr/local/include/png++/writer.hpp:80: undefined reference to `png_set_write_fn'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::writer<std::basic_ofstream<char, std::char_traits<char> > >::~writer()':
/usr/local/include/png++/writer.hpp:86: undefined reference to `png_destroy_write_struct'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::writer<std::basic_ofstream<char, std::char_traits<char> > >::write_info() const':
/usr/local/include/png++/writer.hpp:106: undefined reference to `png_set_longjmp_fn'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::writer<std::basic_ofstream<char, std::char_traits<char> > >::write_row(unsigned char*)':
/usr/local/include/png++/writer.hpp:118: undefined reference to `png_set_longjmp_fn'
/usr/bin/ld: /usr/local/include/png++/writer.hpp:122: undefined reference to `png_write_row'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::writer<std::basic_ofstream<char, std::char_traits<char> > >::write_end_info() const':
/usr/local/include/png++/writer.hpp:130: undefined reference to `png_set_longjmp_fn'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::writer<std::basic_ofstream<char, std::char_traits<char> > >::write_data(png_struct_def*, unsigned char*, unsigned long)':
/usr/local/include/png++/writer.hpp:140: undefined reference to `png_get_error_ptr'
/usr/bin/ld: /usr/local/include/png++/writer.hpp:143: undefined reference to `png_get_io_ptr'
/usr/bin/ld: CMakeFiles/image_proc.dir/src/main.cpp.o: in function `png::writer<std::basic_ofstream<char, std::char_traits<char> > >::flush_data(png_struct_def*)':
/usr/local/include/png++/writer.hpp:169: undefined reference to `png_get_error_ptr'
/usr/bin/ld: /usr/local/include/png++/writer.hpp:172: undefined reference to `png_get_io_ptr'
collect2: error: ld returned 1 exit status
ninja: build stopped: subcommand failed.

问题原因及解决方法

反引号的含义

在Shell环境中,反引号`的作用是命令替换:执行反引号内的命令,把命令的输出结果直接替换到当前位置。比如libpng-config --cflags会输出编译png++需要的头文件路径等参数,libpng-config --ldflags会输出链接时需要的库路径和库名。

你的CMake写法错误原因

CMake不识别Shell的反引号语法,直接写add_compile_options(libpng-config --cflags)会把整个字符串libpng-config --cflags当成编译选项,而不是执行该命令获取实际参数,导致编译和链接时没有正确引入libpng的依赖,所以出现大量未定义引用错误。

正确的CMakeLists.txt写法

方法一:使用execute_process获取参数

用CMake的execute_process命令执行libpng-config,获取输出参数后再应用到项目:

cmake_minimum_required(VERSION 3.27)
project(image_proc)

set(CMAKE_CXX_STANDARD 17)

# 获取libpng的编译参数
execute_process(
    COMMAND libpng-config --cflags
    OUTPUT_VARIABLE LIBPNG_CFLAGS
    OUTPUT_STRIP_TRAILING_WHITESPACE
)

# 获取libpng的链接参数
execute_process(
    COMMAND libpng-config --ldflags
    OUTPUT_VARIABLE LIBPNG_LDFLAGS
    OUTPUT_STRIP_TRAILING_WHITESPACE
)

add_executable(image_proc src/main.cpp src/core.h)

# 将参数应用到目标
target_compile_options(image_proc PRIVATE ${LIBPNG_CFLAGS})
target_link_options(image_proc PRIVATE ${LIBPNG_LDFLAGS})

方法二:使用pkg_check_modules(更规范)

借助CMake的pkg_check_modules模块,通过pkg-config工具查找libpng的依赖,这种方式更符合现代CMake的用法:

cmake_minimum_required(VERSION 3.27)
project(image_proc)

set(CMAKE_CXX_STANDARD 17)

# 查找pkg-config模块
find_package(PkgConfig REQUIRED)
# 通过pkg-config查找libpng
pkg_check_modules(LIBPNG REQUIRED libpng)

add_executable(image_proc src/main.cpp src/core.h)

# 链接libpng的依赖库
target_link_libraries(image_proc PRIVATE ${LIBPNG_LIBRARIES})
# 添加libpng的头文件路径
target_include_directories(image_proc PRIVATE ${LIBPNG_INCLUDE_DIRS})
# 添加libpng的编译选项
target_compile_options(image_proc PRIVATE ${LIBPNG_CFLAGS_OTHER})

两种写法都能正确获取libpng的编译和链接参数,解决链接时的未定义引用问题。

内容的提问来源于stack exchange,提问作者maridj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 23:54:54