我有一个共享库项目,它由4个静态库(.a)和一个object(.o)文件构成.我正在尝试添加-fvisibility=hidden选项以将输出中的符号限制为仅使用__attribute__在源中标记的符号.
我已经-fvisibility=hidden为.so项目的编译选项(包括.o文件)和项目添加了选项.a.
目标文件中的符号将按照预期从最终中删除.so.但是,.a项目中的符号仍然在最终.so文件中.将-fvisibility=hidden选项添加到.solink命令无效.
我究竟做错了什么?
我的目的是从.so除了接口函数之外的所有符号中删除库.
编辑:我实际上使用版本地图来解决这个问题.但是,随着外部符号的更改,它需要继续维护版本脚本.接受的答案有更好的主意.
我正按照此处提供的说明为iPhone编写可重复使用的静态库.
我想minizip在内部使用我的库,但不想将它暴露给用户.
用户应该可以自己包含minizip,可能是不同的版本,并且不会导致与我的"内部"迷你剪辑版本发生冲突.
这可能吗?
编辑:
我已经尝试-fvisibility=hidden为minizip文件添加额外的编译器标志并将函数更改为__private_extern__和__attribute__((visibility("hidden"))),但它似乎仍然生成定义的外部符号:
00000918 T _unzOpen
0000058e T _unzOpen2
00001d06 T _unzOpenCurrentFile
00001d6b T _unzOpenCurrentFile2
...
Run Code Online (Sandbox Code Playgroud)
编辑#2:
显然,标记有这些注释的符号仅由链接器设为私有,这在Xcode构建源时不会发生,因为它添加了-c参数("编译或汇编源文件,但不链接.")
以下是其他帖子的引文:
我正在一个iOS项目中工作,该项目包括由另一家公司创建的静态库.该库包含旧版AFNeworking,我没有任何源文件.
现在我需要使用更新的(并且更少的bug)版本的afneworking,但我不能在项目中两次包括相同的类(当然)因为所有"重复的符号"
我的问题是我正在准备一个iOS框架,我想在将来避免这种情况.我不是在谈论AFNetworking,而是其他非常流行的iOS框架.另外,我在原始框架代码中应用了一些自定义更改.
避免"重复符号"和"类X在Y和Z中实现的一种方法.将使用其中一个",我想到的是在原始框架类中添加一些前缀,但是这是正确的解?
更新1:
我试图应用约翰的解决方案,但没有快乐.我创建了一个简化的项目(这里是repo的链接),它有两个类FrameworkClass,它只存在于框架目标中,而SharedClass存在于框架和应用程序目标中,所以也许你可以看看我是否在做某事错误.应用程序启动后,我仍然得到:
objc[96426]: Class SharedClass is implemented in both .../TestFramework.framework/TestFramework and .../SymbolsVisibilityTest.app/SymbolsVisibilityTest. One of the two will be used. Which one is undefined
更新2:
这是我的输出nm基于提供的示例项目的框架输出:
0000000000007e14 t -[FrameworkClass doFramework]
0000000000007e68 t -[SharedClass doShared]
U _NSLog
U _NSStringFromSelector
00000000000081f0 s _OBJC_CLASS_$_FrameworkClass
U _OBJC_CLASS_$_NSObject
0000000000008240 s _OBJC_CLASS_$_SharedClass
00000000000081c8 s _OBJC_METACLASS_$_FrameworkClass
U _OBJC_METACLASS_$_NSObject
0000000000008218 s _OBJC_METACLASS_$_SharedClass
0000000000007fb0 s _TestFrameworkVersionNumber
0000000000007f70 s _TestFrameworkVersionString
U ___CFConstantStringClassReference
U __objc_empty_cache …Run Code Online (Sandbox Code Playgroud) objective-c static-libraries objective-c-runtime ios ios-frameworks
我想隐藏与最后一个用户无关的符号名称,并在我的共享库或静态库中仅显示可见的API.我有一个简单的代码:
int f_b1(){
return 21 ;
}
int f_b3(){
return f_b1() ;
}
Run Code Online (Sandbox Code Playgroud)
我应用了此处所述的所有方法,例如使用__attribute__ ((visibility ("hidden")))和static数据但未获得成功结果.我的操作系统是Ubuntu和x86_64 GNU/Linux处理器.在使用gcc编译时我们是否使用特殊选项?我用nm命令列出了库的模块和功能.在我上面的例子中,我只想制作可见的f_b3功能.当我使用attribute hidden宏编译器时不会给出任何错误但该函数仍然存在于nm命令输出的列表中.
我正在编写一个使用Objective-C的小型动态库,并将C链接功能公开给Unity(这是一个本机插件)。
即使我的编译器设置将“默认情况下隐藏的符号”设置为“ 是”,并且我正在使用__attribute__((visibility("default")))要公开的函数声明,即使static符号(函数和全局变量)也出现在输出库中。
我已经重新创建了一个测试Xcode项目,该项目最初包含一个C文件。
file.h:
#pragma once
extern __attribute__((visibility("default"))) void not_hidden();
Run Code Online (Sandbox Code Playgroud)
file.c:
#include "file.h"
#include <stdio.h>
static void hidden()
{
printf("I'm hidden\n");
}
void not_hidden()
{
printf("I'm not hidden\n");
hidden();
}
Run Code Online (Sandbox Code Playgroud)
和这工作如广告:
$ nm libHiddenSymbolTest.dylib
0000000000000f40 T _not_hidden
U _printf
U dyld_stub_binder
Run Code Online (Sandbox Code Playgroud)
但是,一旦我添加了具有类似功能的Objective-C文件(not_hidden2(),等),所有的static符号都会被公开:
$ nm libHiddenSymbolTest.dylib
U _CFStringGetCStringPtr
U _NSLog
00000000000054d0 s _OBJC_METACLASS_$___ARCLite__
U __Block_copy
U __DefaultRuneLocale
0000000000005710 b __ZGVZL18add_image_hook_ARCPK11mach_headerlE7patches
0000000000005830 b __ZGVZL22add_image_hook_swiftV1PK11mach_headerlE7patches
0000000000005640 b …Run Code Online (Sandbox Code Playgroud) 我有一个很大的iOS项目,它包含几个(大约20-30个)静态库,它们链接在一起成为最终的可执行文件.一些组件是独立于平台的(纯C++),一些是特定于iOS的(Obj-C/Obj-C++).C++模板被密集使用,因此每个目标文件都包含许多带有模糊链接的符号.问题是这些符号仅在最终可执行文件的链接期间合并,但在创建静态库时不合并.每个库包含大量重复的符号(6-60个克隆).所以应用程序的最终链接需要几分钟.在调试和做一些小的改动时,这变得非常烦人.
有没有办法为每个库执行符号与模糊链接的合并?
我知道,这是在使用动态库时自动完成的.通过一些黑客攻击(http://sumgroup.wikispaces.com/iPhone_Dynamic_Library),可以为iOS构建动态库.有没有办法静态链接dylib(将它们链接到一个可执行文件)?
当然,能够调试生成的应用程序是必须的.