使用CMake链接libswscale失败:x86_64架构下sws_getContext符号未定义
链接libswscale时
sws_getContext符号未定义的解决方案 核心排查方向及解决步骤:
1. 修复C++与C库的符号兼容问题
FFmpeg全量库基于C语言实现,在C代码中直接引入其头文件时,编译器会对符号进行C风格的名字修饰,导致无法匹配库中的原生C符号。
修改video_writer.cpp中FFmpeg头文件的引入方式,用extern "C"包裹:
extern "C" { #include <libswscale/swscale.h> #include <libavcodec/avcodec.h> #include <libavutil/pixfmt.h> }
2. 调整链接顺序与依赖关系
链接器按从左到右的顺序解析符号,被依赖的库需要放在依赖它的库之后。尝试调整CMake中pkg-config的模块顺序,让libswscale优先被处理:
pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET libswscale libavcodec libavutil )
3. 确认库架构与编译目标匹配
执行以下命令检查FFmpeg库的架构,确保与报错显示的x86_64一致:
lipo -info /usr/local/Cellar/ffmpeg/5.1.2/lib/libswscale.dylib
4. 验证pkg-config输出正确性
在终端运行以下命令,确认pkg-config返回的链接参数完整无遗漏:
pkg-config --libs --cflags libswscale libavcodec libavutil
将输出与CMake实际传递给链接器的参数对比,排查是否缺少必要的编译/链接选项。
原问题相关信息:
报错信息:
Undefined symbols for architecture x86_64: "sws_getContext(int, int, AVPixelFormat, int, int, AVPixelFormat, int, SwsFilter*, SwsFilter*, double const*)", referenced from: VideoWriter::writeFrame(std::__1::vector<char, std::__1::allocator<char> >) in video_writer.cpp.o
调用代码:
struct SwsContext *sws_ctx = sws_getContext( avCodecContext->width, avCodecContext->height, AV_PIX_FMT_RGBA, avCodecContext->width, avCodecContext->height, AV_PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL);
链接命令片段:
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ld" -demangle -lto_library /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/libLTO.dylib -no_deduplicate -dynamic -arch x86_64 -platform_version macos 10.15.0 11.1 -syslibroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.1.sdk -o bin/main -search_paths_first -headerpad_max_install_names CMakeFiles/main.dir/src/main.cpp.o CMakeFiles/main.dir/src/window.cpp.o CMakeFiles/main.dir/src/video_writer.cpp.o -rpath /usr/local/lib /usr/local/lib/libGLEW.2.2.0.dylib /usr/local/lib/libboost_program_options-mt.dylib -framework OpenGL /usr/local/Cellar/sdl2_image/2.6.2/lib/libSDL2_image.dylib /usr/local/lib/libSDL2.dylib /usr/local/Cellar/ffmpeg/5.1.2/lib/libavcodec.dylib /usr/local/Cellar/ffmpeg/5.1.2/lib/libswscale.dylib /usr/local/Cellar/ffmpeg/5.1.2/lib/libavutil.dylib -lc++ -lSystem /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/12.0.0/lib/darwin/libclang_rt.osx.a -F/Library/Developer/CommandLineTools/SDKs/MacOSX10.15.sdk/System/Library/Frameworks
CMake配置:
cmake_minimum_required(VERSION 3.19.2) project(FragTool VERSION 1.0) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/") # --- c++ build settings --- # set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weffc++ -O0") set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) set(CMAKE_BUILD_TYPE Debug) # --- dependencies --- # find_package(GLEW REQUIRED) find_package(Boost 1.79.0 COMPONENTS program_options REQUIRED) find_package(PkgConfig REQUIRED) pkg_check_modules(LIBAV REQUIRED IMPORTED_TARGET libavcodec libswscale libavutil ) pkg_check_modules(LIBSDL2 REQUIRED IMPORTED_TARGET sdl2 sdl2_image ) set(EXECUTABLE main) add_executable(${EXECUTABLE} src/main.cpp) target_sources(${EXECUTABLE} PRIVATE ${CMAKE_SOURCE_DIR}/src/window.cpp ${CMAKE_SOURCE_DIR}/src/video_writer.cpp ) target_include_directories(${EXECUTABLE} PRIVATE ${CMAKE_SOURCE_DIR}/src) target_include_directories(${EXECUTABLE} PRIVATE ${GLEW_INCLUDE_DIRS}) target_link_libraries(${EXECUTABLE} PRIVATE GLEW::glew) target_link_libraries(${EXECUTABLE} PRIVATE ${Boost_LIBRARIES}) target_link_libraries(${EXECUTABLE} PRIVATE PkgConfig::LIBSDL2) target_link_libraries(${EXECUTABLE} PRIVATE PkgConfig::LIBAV)
内容的提问来源于stack exchange,提问作者J. Johnson
相关产品推荐
相关产品推荐

