如何将反引号(`)中的参数传递给cmake

bmvo0sr5  于 5个月前  发布在  其他
关注(0)|答案(1)|浏览(52)

我使用png++ lib,它需要通过编译

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

字符串
它工作得很好,但我使用clion,所以我想运行它与CMake(我知道,我可以只运行shell,但它不是好看的选项)。我不知道如何做到这一点。我已经尝试了2种方法,但都没有工作。我的猜测,在反引号(`)的问题。真的,我真的不明白他们的意思
我试过这些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.

ljsrvy3e

ljsrvy3e1#

“反引号中的参数”还不是参数。它们是command substitutions,由shell生成。只有在替换之后,它们才成为参数。
因为你写的是CMake代码,而不是shell代码,所以你必须用CMake表达的方式来做这些替换。但是,理想情况下,你不应该手工做任何事情。CMake应该为你处理它-这就是它存在的原因!
由于libpng-config为您提供了流行的libpng库的配置信息,可能CMake已经有了libPNG的查找模块?它确实:

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)
find_package(PNG REQUIRED)

# When building an executable - link PRIVATE-ly
add_executable(my_executable ...)
target_link_libraries(my_executable PRIVATE PNG::PNG)

# When building a library, link PUBLIC-ly
add_library(my_library ...)
target_link_libraries(my_library PUBLIC PNG::PNG)

字符串
命令find_package(FOO [...])表示“搜索FindFOO模块,将参数传递给它,并执行其中的代码”。该代码应该找到“FOO”包。这里,“PNG”是“libpng”的缩写。* 约定是libFoo的查找模块将被称为FindFOOFindFoo *。

  • 您希望使用更高的最低CMake版本声明。我显示的版本是使用我演示的功能所需的最低版本,仅此而已。*
  • 由于您正在构建可执行文件,因此只需要与add_executable相关的部分。add_library部分是构建库时如何执行的示例。*

这有跨平台工作的好处,而libpng-config是Unix的东西。
FindPNG模块(通过find_package命令访问)设置一个IMPORTED库目标。该目标包含目标属性,以及使用库所需的包含路径、链接库和编译选项。
PNG::PNG是由FindPNG模块创建的目标,该目标具有使用库所需的所有信息。
使用find_package的另一个好处是,有一些常用的方法可以将提示传递给Find模块,所以如果有人使用您的项目在非标准位置中有libpng,他们可以通过命令行或该高速缓存或json配置文件中的CMAKE变量轻松地将库的位置传递给FindPNG。例如,后两种方法通常由IDE使用。
尽管不推荐使用,并且会被认为是一种黑客行为,但当然可以手动执行命令替换。让我们显式地调用libpng-config,就像shell一样:

cmake_minimum_required(VERSION 3.18 FATAL_ERROR)

execute_process(
    COMMAND libpng-config --cflags 
    ECHO_OUTPUT_VARIABLE LIBPNG_CFLAGS
)
execute_process(
    COMMAND libpng-config --ldflags 
    ECHO_OUTPUT_VARIABLE LIBPNG_LDFLAGS
)

add_executable(my_executable ...)
target_compile_options(my_executable PRIVATE ${LIBPNG_CFLAGS})
target_link_options(my_executable PRIVATE ${LIBPNG_LDFLAGS})


正如您所看到的,通过find_package使用FindPNG模块要容易得多。
为什么FindPNG在这里工作?因为我的库需要这个模块?
FindPNG在这里工作,因为它是一个查找模块,用于查找PNG库(libpng)。有许多这样的查找模块,用于各种常见的库,它们消除了向项目添加流行依赖项的繁重工作。
由于您的项目需要libpng,因此可以使用FindPNG模块。
请参阅:

反引号(或者$( ... ))表示shell command substitution。整个反引号“短语”被替换为命令的输出。
bash(或大多数Unix shell)看到它的方式如下:
1.输入命令行:
g++ -c example.cpplibpng-config --cflags``,或:
g++ -c example.cpp $(libpng-config --cflags)
1.命令替换是必要的. pixx 1 m21n1x并将其输出替换到命令行中。
1.现在命令行看起来像(例如):g++ -c example.cpp -I/usr/include/libpng16
1.由于没有更多的替换要执行,g++进程是用给定的命令行派生的。

相关问题