我有一堆项目都可以共享一个"常见"的静态类库.
令我困惑的是,如果我从这些类中创建一个静态库并在我的项目中链接它,我仍然需要在我的主项目中的静态库中的类的标题.
那么静态库有什么好处呢?
像Adobe这样的公司如何处理这个?
直到前一段时间,我认为.a静态库只是.o目标文件的集合,只是归档它们而不是以不同的方式处理它们.但是链接到.o对象并链接到包含此.o对象的.a静态库显然是不一样的.我不明白为什么......
我们来考虑以下源代码文件:
// main.cpp
#include <iostream>
int main(int argc, char* argv[]) {
std::cout << "main" << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
// object.hpp
#include <iostream>
struct Object
{
Object() { std::cout << "Object constructor called" << std::endl; }
~Object() { std::cout << "Object destructor called" << std::endl; }
};
Run Code Online (Sandbox Code Playgroud)
// object.cpp
#include "object.hpp"
static Object gObject;
Run Code Online (Sandbox Code Playgroud)
让我们编译并链接并运行以下代码:
g++ -Wall object.cpp main.cpp -o main1
./main1
> Object constructor called
> main
> Object destructor called
Run Code Online (Sandbox Code Playgroud)
构造函数是全局gObject对象的析构函数.
现在让我们从代码中创建一个静态库,并在另一个程序中使用(链接)它:
g++ …Run Code Online (Sandbox Code Playgroud) 我有一个C++项目,由于其目录结构被设置为静态库A,它链接到共享库B,它链接到可执行文件C.(这是使用CMake的一个跨平台的项目,所以在Windows上我们得到的A.lib,B.dll和C.exe,和在Linux上我们得到的libA.a,libB.so和C).图书馆A有一个初始化函数(A_init在定义A/initA.cpp),即从库调用B的初始化函数(B_init,定义于B/initB.cpp),从C主要调用.因此,当链接时B,A_init(和所有符号中定义的initA.cpp)被链接到B(这是我们期望的行为).
问题在于,A库还定义了一个动态加载的函数(Af,在A/Afort.f其中定义)(即LoadLibrary/ GetProcAddress在Windows上和dlopen/ dlsym在Linux上).由于没有Af来自库的引用B,A/Afort.o因此不包括符号B.在Windows上,我们可以通过使用pragma人工创建引用:
#pragma comment (linker, "/export:_Af")
Run Code Online (Sandbox Code Playgroud)
由于这是一个pragma,它只适用于Windows(使用Visual Studio 2008).为了让它在Linux上运行,我们尝试将以下内容添加到A/initA.cpp:
extern void Af(void);
static void (*Af_fp)(void) = …Run Code Online (Sandbox Code Playgroud) 将静态库与可执行文件链接时,通常会丢弃未引用的符号.在我的例子中,一些未使用的对象用于将它们各自的类注册到工厂中,如果丢弃了对象,则该注册失败.
在我们使用gcc的Unix下,我可以将标志--whole-archive传递给链接器ld(参见下面的ld文档摘录),这使得ld不会丢弃任何对象.Visual C++有这样的东西吗?
--whole归档
对于
`--whole-archive'选项后命令行中提到的每个归档
,请在链接中包含归档中的每个目标文件,而不是在归档中搜索所需的
目标文件.这通常用于将存档文件转换
为共享库,从而强制将每个对象包含在
生成的共享库中.此选项可能不止一次使用.
我正在尝试在Fedora中安装带有-fPIC支持的GHC.我已经抓住了一个源tarball,因为它似乎没有二进制文件.
在Build.mk中,我已将快速构建类型更改为
ifeq "$(BuildFlavour)" "quick"
SRC_HC_OPTS = -H64m -O0 -fasm -fPIC
GhcStage1HcOpts = -O -fasm -fPIC
GhcStage2HcOpts = -O0 -fasm -fPIC
GhcLibHcOpts = -O -fasm -fPIC
SplitObjs = NO
HADDOCK_DOCS = NO
BUILD_DOCBOOK_HTML = NO
BUILD_DOCBOOK_PS = NO
BUILD_DOCBOOK_PDF = NO
endif
Run Code Online (Sandbox Code Playgroud)
不幸的是,在编译时我仍然得到ld错误
ghc -fglasgow-exts --make -shared -oHs2lib.a /tmp/Hs2lib924498/Hs2lib.hs dllmain.o -static -fno-warn-deprecated-flags -O2 -package ghc -package Hs2lib -i/home/phyx/Documents/Haskell/Hs2lib -optl-Wl,-s -funfolding-use-threshold=16 -optc-O3 -optc-ffast-math
Linking a.out ...
/usr/bin/ld: /tmp/Hs2lib924498/Hs2lib.o: relocation R_X86_64_32 against `ghczmprim_GHCziUnit_Z0T_closure' can not be used when making a shared object; …Run Code Online (Sandbox Code Playgroud) 为什么某些静态库(lib*.a)可以以与共享库(lib*.so)链接(ld -l switch)相同的方式链接,但有些不可以?
我一直被教导所有库,无论是否静态,都可以与-l ...链接,但是我到目前为止遇到了一个库(GLFW),如果我发出"未定义的引用"链接错误,它什么都不做试图以这种方式链接它.
根据对这个问题的回答,链接静态库的"正确"方法是将它们与我自己的目标文件一起直接包含在内,而不是使用-l.而且,就GLFW库而言,这肯定解决了这个问题.但是我正在使用的每个其他静态库在与-l链接时工作得很好.
所以:
如何将静态库合并为单个库?
我有三个静态库libSignatureLibary_armv6.a,libSignatureLibary_armv7.a和libSignatureLibary_i368.a
现在我想将这三个文件合并到一个可以命名为libSignatureLibary.a的单个库中
谷歌搜索时我发现lipo是开源工具!
我是否需要运行任何额外的脚本语言才能合并
或在终端脂肪中并传递脂质的参数.
任何建议我可以为这三个建立公共库.
@thanks提前Kiran
我有一个正在建设的图书馆.当我运行以下任何一个时,我的所有对象都会连续编译和链接:
ar rcs lib/libryftts.a $^
gcc -shared $^ -o lib/libryftts.so
在我的Makefile中.我也能够成功安装它们/usr/local/lib
当我用nm测试文件时,所有的功能都在那里.我的问题是,当我跑步gcc testing/test.c -lryftts -o test && file ./test或gcc testing/test.c lib/libryftts.a -o test && file ./test
它说:
test: ELF 64-bit LSB shared object而不是test: ELF 64-bit LSB executable像我期望的那样.我究竟做错了什么?
最近我开始为一个旧的静态库编写测试用例.我已将库加载到Xcode 5,由于静态库已旧,我必须手动添加TestProject和Test Target.
当我尝试"产品 - >测试"时,它启动模拟器,控制台显示以下错误
无法加载/xxx/xxx/xxx/StaticLibTest.xctest中的测试包,因为发生了意外错误:Error Domain = NSCocoaErrorDomain Code = 3587"无法加载软件包"StaticLibTest.xctest",因为它已损坏或丢失必要的资源." (dlopen_preflight(/xxx/xxxx/xxx/Debug-iphonesimulator/StaticLibTest.xctest/StaticLibTests):找不到合适的图像.找到了:
我不知道为什么会出现这个错误.
任何指出正确方向的帮助都将非常感激.
我有一个Xcode项目,它生成一个静态库.我的团队计划在Swift中进行所有新开发.无法将Swift文件添加到静态库项目中.我们正在放弃对iOS 7的支持,因此现在可以在我们的iOS应用程序中包含框架.因此,我打算将我的静态库项目转换为框架项目.
我看过,但我找不到任何有关如何执行此转换的工具或建议.静态库很大(超过100个.m文件).
我希望得到一个更好的答案,而不是创建一个新的并行框架目标.我试过两次.第一次作为一个快速的目标,但我无法轻松导入所有的Objective C文件.接下来,作为Objective C目标,但不再有.pch.