Clang生成动态库的关键是:Linux用-fPIC -shared生成.so,macOS用-fPIC -dynamiclib生成.dylib,Windows应使用clang-cl配合MSVC linker生成.dll;必须加-fPIC,否则链接报错。

Clang 生成动态库的关键是用 -shared(Linux/macOS)或 -dynamiclib(macOS)选项,并确保编译阶段加 -fPIC;Windows 上不推荐直接用 Clang 生成 DLL,应走 MSVC + clang-cl 工具链。
Linux 下用 clang 生成 .so 文件必须加 -fPIC
位置无关代码(PIC)是动态库运行的基础。没加 -fPIC 编译目标文件,链接时会报错:relocation R_X86_64_32 against `xxx' can not be used when making a shared object。
- 正确流程分两步:先编译为 PIC 目标文件,再链接成共享库
clang -fPIC -c func.c -o func.oclang -shared func.o -o libfunc.so- 如果源文件里有 C++ 代码,统一用
clang++,避免 ABI 不一致 - 头文件路径用
-I/path/to/headers,否则#include会失败
macOS 下必须用 -dynamiclib,不是 -shared
macOS 的动态库后缀是 .dylib,且链接器不认 -shared —— 用错会提示:unknown argument: '-shared'。
Clang 22.1.3 Windows 64 位历史版本安装包,适合旧项目兼容、LLVM/Clang 工具链回退、编译行为对比、链接问题复现和 C/C++ 构建环境维护。
- 命令格式:
clang -dynamiclib -o libMyLib.dylib src/MyLib.c -Iinclude - 如果涉及 Objective-C 或 ARC,要加
-fobjc-arc和-isysroot指向 SDK - 导出符号默认隐藏,需在函数声明前加
__attribute__((visibility("default"))),否则调用方找不到符号 - 注意:Xcode 默认禁用隐式导出,不加 visibility 属性,
nm -g libMyLib.dylib看不到你的函数
链接时找不到 -lxxx:-L 和 -l 顺序与路径都得对
编译可执行程序时用 -lfunc 找 libfunc.so,但链接器默认只查系统路径(如 /usr/lib),不会自动搜当前目录。
- 必须显式加
-L.(当前目录)或-L/path/to/libs - 顺序不能错:
clang++ main.o -L. -lfunc -o main,-L必须在-l前面 - 运行时报
libfunc.so: cannot open shared object file?说明运行时路径没设 —— 要么把.so放进/usr/local/lib并运行sudo ldconfig(Linux),要么临时加LD_LIBRARY_PATH=. - macOS 对应的是
DYLD_LIBRARY_PATH=.,但 SIP 启用时该环境变量会被忽略,更稳妥的是用install_name_tool修改库的 install name
Windows 上别硬刚 clang -shared
Clang 自身不提供 Windows DLL 链接器支持;直接跑 clang -shared 会失败或生成不可用的二进制。
- 正确做法是用
clang-cl+ MSVC linker:clang-cl /c /EHsc func.cpp→link /DLL func.obj /OUT:func.dll - 若用 CMake,必须指定工具集:
-T ClangCL -A x64,否则add_library(... SHARED)可能静默失败 - Windows 导出符号要用
__declspec(dllexport),头文件里配合宏做 import/export 切换 - 不要依赖
libfunc.dll.a这类导入库自动生成 —— Clang for Windows 不稳定产出它,手动写.def文件更可靠
最易被忽略的一点:动态库的 ABI 兼容性完全取决于编译器版本、标准库选择(libc++ vs libstdc++)、C++11 ABI 开关(_GLIBCXX_USE_CXX11_ABI)—— 即使命令全对,混用不同配置生成的 .so 和主程序,也会在运行时崩在 undefined symbol 或段错误上。

















