Windows10 MSYS2下C程序链接自编译LibRaw Beta时出现未定义引用错误
问题背景
在Windows10 MSYS2环境下,使用CLion和Mingw64的gcc/clang编译C程序,尝试链接C库LibRaw。原本通过MSYS2 Pacman安装的旧版LibRaw可正常运行,但为支持新相机,从源码编译LibRaw Beta版本并将libraw.a和头文件放入Mingw64的lib、include目录后,编译原有C代码和CMake配置时出现大量__cxa开头的未定义引用错误。尝试用g/clang++编译、添加-lsupc++,以及直接链接旧版MSVC编译的libraw.lib,后者运行时直接崩溃,需解决编译错误的原因及修复方法。
简化后的C程序代码
#include <stdio.h> #include <tiffio.h> #include <libraw.h> int main(void); int main(void) { const char* libtiffVersion; const char* librawVersion; libtiffVersion = TIFFGetVersion(); if(libtiffVersion) printf("%s\n", libtiffVersion); else printf("libtiff not found!\n"); librawVersion = libraw_version(); if(librawVersion) printf("%s\n", librawVersion); else printf("libraw not found!\n"); return 0; }
原CMake配置
cmake_minimum_required(VERSION 3.23) project(MyProject C) set(CMAKE_C_STANDARD 90) find_library(LIBRAW libraw) find_library(LIBTIFF libtiff) add_executable(MyProject main.c) target_link_libraries(MyProject ${LIBTIFF} ${LIBRAW})
CMake生成的链接命令
cmd.exe /C "cd . && C:\msys64\mingw64\bin\gcc.exe -g CMakeFiles/MyProject.dir/main.c.obj -o MyProject.exe -Wl,--out-implib,libMyProject.dll.a -Wl,--major-image-version,0,--minor-image-version,0 C:/msys64/mingw64/lib/libtiff.dll.a C:/msys64/mingw64/lib/libraw.a -lkernel32 -luser32 -lgdi32 -lwinspool -lshell32 -lole32 -loleaut32 -luuid -lcomdlg32 -ladvapi32 && cd ."
尝试过的旧版MSVC库CMake配置
cmake_minimum_required(VERSION 3.23) project(MyProject C) set(CMAKE_C_STANDARD 90) find_library(LIBTIFF libtiff) add_executable(MyProject main.c) target_link_libraries(MyProject ${LIBTIFF} ${PROJECT_SOURCE_DIR}/libraw.lib)
错误原因分析
__cxa未定义引用问题:LibRaw是C编写的库,编译生成的libraw.a依赖C标准库。使用gcc(C编译器)链接时,不会自动链接C标准库(如libstdc++.a),导致__cxa_guard_acquire、__cxa_pure_virtual等C标准库符号缺失。- MSVC库与MinGW不兼容:MSVC编译的
libraw.lib采用MSVC的C++ ABI和运行时库,与MinGW的GCC/Clang工具链完全不兼容,直接链接会引发运行时崩溃,属于跨工具链的二进制不兼容问题。
解决方法
方法1:修改CMake配置,用C++编译器链接C程序
将项目改为C项目,或强制用C编译器链接,确保自动引入C++标准库:
cmake_minimum_required(VERSION 3.23) project(MyProject CXX) set(CMAKE_CXX_STANDARD 11) find_library(LIBRAW libraw) find_library(LIBTIFF libtiff) add_executable(MyProject main.c) target_link_libraries(MyProject ${LIBTIFF} ${LIBRAW})
方法2:保持C项目,手动链接C++标准库
若需继续用C编译器编译,需在链接阶段手动添加C++标准库和异常处理库:
cmake_minimum_required(VERSION 3.23) project(MyProject C) set(CMAKE_C_STANDARD 90) find_library(LIBRAW libraw) find_library(LIBTIFF libtiff) find_library(LIBCXX libstdc++) find_library(SUPCXX supc++) add_executable(MyProject main.c) target_link_libraries(MyProject ${LIBTIFF} ${LIBRAW} ${LIBCXX} ${SUPCXX})
方法3:重新编译LibRaw,确保生成MinGW兼容的库
编译LibRaw Beta时,必须使用MSYS2 Mingw64的工具链(gcc/g++),步骤如下:
- 打开MSYS2 Mingw64终端,进入LibRaw源码目录
- 执行配置命令:
(./configure --prefix=/mingw64 --disable-shared--disable-shared生成静态库libraw.a,如需动态库可去掉该参数) - 编译安装:
生成的库会自动放入Mingw64的make -j$(nproc) make installlib和include目录,确保与当前工具链兼容。
内容的提问来源于stack exchange,提问作者calandracas
相关产品推荐
相关产品推荐

