C++ Visual Studio生成的静态库是否可以去除符号?
我将把这些问题分为三个部分:C++ Visual Studio生成的静态库是否可以去除符号?,c++,visual-studio-2008,static-libraries,symbols,C++,Visual Studio 2008,Static Libraries,Symbols,我将把这些问题分为三个部分: 我想制作一个静态库并去掉它的符号。(已不包括调试信息) 类似于linux中的strip命令。能做到吗 windows环境中是否有与linux中的nm工具等效的工具 使用VS2008创建静态库时。是否可以定义一个脚本,将生成的一些.obj文件排除在构建和静态库之外? 它可以是动态的吗?我的意思是,我将在脚本中定义编译模式,这将导致特定的对象文件被排除在构建之外 不,您认为静态库的用户在不知道他们使用的符号在哪里定义的情况下如何链接到它 是的,试试这个工具 嗯,是的。您
它可以是动态的吗?我的意思是,我将在脚本中定义编译模式,这将导致特定的对象文件被排除在构建之外
/REMOVE:foo
运行LIB
实用程序这就是说,我认为您正在做一些不值得做的事情,或者可以做得比删除库成员简单得多。如果您认为不应该看到任何东西,请尝试使用“static”关键字声明它。这告诉编译器它只能被当前模块访问。我一直在VS2010生成的.obj文件中查找某些(但不是所有)静态函数的名称。有趣的是,它们在我的Release.obj文件中可见,但在Debug.obj文件中不可见。我只是使用cygwin字符串来执行搜索:
$ strings myObjectFile.obj | grep myStaticFunctionName
我跟踪到“整个程序优化=是”设置(“/GL”)。当我将其切换为“否”时,函数名不再出现
更新:作为后续测试,我在vim中打开了“cleaned”myObjectFile.obj,仍然可以找到它们(使用:set encoding=utf-8或:set encoding=latin1)。我不知道为什么字符串没有匹配。哦,好吧。在某些情况下,除了少数“导出”的公共符号外,可以方便地去掉所有符号,但这并不切实可行 静态库只不过是.obj文件的集合。内部依赖关系还没有被解决,直到链接时间才会被解决 例如,如果您的.lib由foo.obj和bar.obj组成,并且foo.obj中有一个对bar.obj中定义的函数的调用,那么该符号在链接时必须可用,即使库外没有任何东西可以看到它 因此,不能去除符号(文件范围静态符号可能除外)。即使是受保护或私有(在C++意义上)的类方法也会存在于符号表中,因为可见性的实现是编译时问题,而不是链接时问题 相反,动态库是一个已经链接的独立二进制文件。已解析从foo.obj到bar.obj的引用。因此,除了必须导出的符号(甚至可以重命名这些符号或用序数替换这些符号)之外,DLL可以去掉符号
如果您的DLL公开了一个简单的C API,那么您就万事大吉了。但是如果你想公开C++类,你可能最终会输出它的所有方法,甚至是受保护的和私有的方法(因为在外部应用程序中的内联可能导致对私有方法的直接调用)。没有符号的库与只写内存一样有用。这只做了一半的工作。该库仍然包含符号,但它们可以删除:在linux上,通过
strip-x…
,在Windows上,我不知道如何删除,这就是问题所在!实际上,我刚刚编译了一个简单的文件,声明了两个函数,一个是静态的,一个不是,静态函数不出现在.lib文件中(用十六进制编辑器验证)。这似乎符合OP的要求。我找不到从最终库中删除单个符号的方法,另一个答案中提到的/remove选项似乎只从输出库中删除整个.obj文件。@Jimbo,如果您只是声明(并定义)静态函数,它不会出现在编译文件中。不过,如果你真的使用它,它会被包括在内。我对否决票很好奇。有人愿意发表评论,以便我能改进我的答案吗?你答案中的第一句话就是我们也在努力实现的目标。到目前为止,选项似乎是1)将所有不需要的符号声明为静态,2)将不需要的符号放在未命名的命名空间中,3)将不需要的符号重命名为一些垃圾(如果混淆是您的目标)。前两个选项应该与unity build结合使用,以确保不再需要私有跨对象Symbil。