Clang 中 __MODULE__ 使用

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Clang 中 __MODULE__ 使用相关的知识,希望对你有一定的参考价值。

参考技术A 最近在做一个在打 log 的宏中待上每个模块的名字的任务,一个应用拆分下来有 20-30 个 framework, 不可能让每一个打log 的地方都手动改一下,加上自己打 log 的前缀, 打算重写掉之前打log 这个宏在预处理阶段就让每个打log的调用带上所属模块的名称,所以需要在预编译期间获得每个模块的名称,如果在 runtime 期间拿到,可以直接读info.plist 里面的值(如果这个模块进了主工程,读出来的值都会是一样的值),所以只能在预编译期间拿这个值。
最后在 Clang 找到了 __MODULE__ 这个在 Clang 中像 __FILE__ 一样的预定义的宏,但是有区别的是, __MODULE__ 不像 __FILE__ 一样,它不是字符串,我们最终需要把 __MODULE__ 转成一个字符串。

__MODULE__ 被定义的前提是 Xcode 的 build setting 里面 define module 要打开

如果是通过 CocoaPods 引入的源码,需要在 podspec 文件里面加入
s.pod_target_xcconfig = 'DEFINES_MODULE' => 'YES'

最后结果:

gcc 标准预定义的宏
Clang 预定义
Define module CocoaPods

使用可见性属性(没有 __declspec(dllexport))时,Clang 可以生成导入库吗?

【中文标题】使用可见性属性(没有 __declspec(dllexport))时,Clang 可以生成导入库吗?【英文标题】:Can Clang generate an import library when using the visibility attribute (without __declspec(dllexport))? 【发布时间】:2019-11-17 23:24:34 【问题描述】:

使用 Microsoft 编译器时,要从库中导出类或函数,您可以使用类似于以下内容的代码:

class __declspec(dllexport) Foo ;

使用 Clang(和 GCC),您可以使用可见性属性来确保符号可见:

class __attribute__((visibility(default))) Foo ;

或者依赖于编译时设置的可见性。

当我在 Windows 上使用 Clang 编译时,如果一个类可见(即使具有显式属性),则不会导出该函数(不创建导入库)。

是否可以让 Clang 生成导入库而不使用 Clang 大部分但不完全支持的 Microsoft 扩展 __declspec(dllexport)

【问题讨论】:

您能否详细说明“Clang 主要但不完全支持的__declspec(dllexport)”,它不支持哪个方面? @mstorsjo 针对 LLVM 项目的__declspec(dllexport) 记录了几个错误;这是我最近提交的一个示例 - bugs.llvm.org/show_bug.cgi?id=44016 很公平,这种情况似乎确实偏离了 MSVC 的行为。 我很确定是 LLVM 端口激发了微软创建自己的分支。他们研究了一段时间,因为异常处理是更难破解的问题。它在 VS2017 左右变得稳定,并包含在 VS 安装程序中。 @HansPassant Microsoft fork 了什么? 【参考方案1】:

澄清一些事情;生成导入库的不是编译器 (Clang) 本身,而是链接器,而目标文件格式在此过程中起着重要作用。

调整通过__attribute__((visibility(default))) 导出的符号(当使用__attribute__((visibility(hidden))) 将其他符号标记为隐藏时,或使用-fvisibility=hidden 之类的设置默认值时,在构建ELF 目标文件时,GCC 和Clang 都适用。COFF 不'没有类似的每个符号可见性标志。

当使用 MS link.exe 或 LLVM 的 lld-link(模仿 link.exe 的行为)链接 DLL 时,只有标有 __declspec(dllexport) 或在传递给链接器的 def 文件中列出的符号是已导出。

在 MinGW 生态系统中(带来更多类似 unix 的行为),如果没有符号,默认是导出所有全局符号(使用一些逻辑来避免导出属于 mingw 基础库本身的东西)被明确选择导出。

如果使用 lld-link 而不是 MS link.exe 链接(如果直接调用链接器,则通过调用 lld-link 而不是链接,或者如果通过 clang-cl 前端调用链接器,则添加 -fuse-ld=lld),您可以通过添加特定于 lld 的选项 -lldmingw 来选择启用此行为,这会在 lld 中启用许多特定于 MinGW 的行为。

【讨论】:

谢谢。我希望 Clang 能够自动将符号标记为已导出,如果它们是可见的(基于属性或默认值),这将允许链接器生成导入库。【参考方案2】:

添加到@mstorsjo 的答案,这是一个将 def 文件传递​​给 clang 的示例。

clang -shared structs.c -o structs.dll -Wl"/DEF:structs.def"

我为此苦苦挣扎了一天,希望对某人有所帮助 (explaination)

【讨论】:

以上是关于Clang 中 __MODULE__ 使用的主要内容,如果未能解决你的问题,请参考以下文章

clang __asm__在case statment中使用标签,得到错误:指令操作数无效。

__m256 未知类型(clang 5.1/i5 CPU)?

使用可见性属性(没有 __declspec(dllexport))时,Clang 可以生成导入库吗?

错误:未知类型名称 '__darwin_wctype_t' typedef __darwin_wctype_t wctype_t 在 MacOS 上使用 Clang 编译

未定义符号 RealmSwift:“_OBJC_CLASS_$_RLMNotificationToken”,clang 错误

强制函数在Clang / LLVM中内联