我目前正在尝试将C应用程序移植到AIX,我感到很困惑.什么是.a和.so文件以及它们在构建/运行应用程序时如何使用?
我有一小段代码依赖于许多静态库(a_1-a_n).我想将该代码打包到静态库中,并将其提供给其他人.
我的静态库,让我们称之为X,编译好.
我创建了一个使用X函数的简单示例程序,但是当我尝试将它链接到X时,我从库a_1 - a_n中得到许多关于丢失符号的错误.
有没有办法可以创建一个新的静态库,Y包含X和X所需的所有功能(a_1 - a_n中的选定位),这样我就可以为人们分配Y来链接他们的程序了吗?
更新:
我已经看过只是使用ar转储所有内容并制作一个mega-lib,然而,最终包含了许多不需要的符号(所有.o文件大约为700 MB,但是,静态链接的可执行文件是7 MB).有没有一种很好的方法只包括实际需要的东西?
这看起来与如何将多个C/C++库合并为一个密切相关?.
我正在进行C静态库和程序的测试设置.库代码位于我项目的子目录'foo'中,包含以下文件:
富/ foo.c的:
#include <stdio.h>
void foo(void) {
printf("something");
}
Run Code Online (Sandbox Code Playgroud)
富/ foo.h中:
#ifndef foo_h__
#define foo_h__
extern void foo(void);
#endif
Run Code Online (Sandbox Code Playgroud)
我的程序代码如下:
test.c的:
#include "foo.h"
int main() {
foo();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我有一个名为"build"的构建脚本,其中包含以下内容:
建立:
#!/bin/bash
gcc -c -Wall -Werror foo/foo.c
ar rcs libfoo.a foo.o
gcc -static -o test test.c libfoo.a # I have also tried -L. -lfoo
Run Code Online (Sandbox Code Playgroud)
但是当我运行build时,它会给我以下错误:
test.c:1:17: fatal error: foo.h: No such file or directory
#include "foo.h"
^
Compilation terminated
Run Code Online (Sandbox Code Playgroud)
但是,当我省略#include行时,它确实有效,但我更喜欢在静态库中使用头文件.我做错了什么,我该如何解决?
我刚刚在android中进行了本机开发.我成功地将我的AndroidStudio 2.2.2准备好用于本机开发
我还构建了示例hello-jni项目
我想要实现的目标
我正在尝试使用用c ++设计的现有库(我将提供静态库.a扩展名或.so文件)
关于本土发展的几点混乱
1)我应该使用现有c ++库的.cpp和.h文件而不是.a或.so文件吗?
2)我是否需要制作CMakeLists.text:据我搜索我的.a文件不是使用ndk-build生成的,所以我需要制作它.
如果我使用.cpp和.h文件,我应该制作Android.mk和Application.mk
CMakeLists.text是否将我新开发的android项目编译为库或我现有的.a文件?
3)我在哪里将.a文件放在我的项目中.它在jni文件夹下吗?
4)我的java类文件是否应该定义具有与c ++文件中实现的关键字本机相同的方法(例如:在c ++文件方法名称getData()中,java类应该包含公共本机getData())
如果在一个构建脚本中构建静态库,并且想要在链接最终可执行文件时使用这些静态库,则提示.a
文件的顺序非常重要:
g++ main.o hw.a gui.a -o executable
Run Code Online (Sandbox Code Playgroud)
如果gui.a
使用hw.a
链接中定义的内容将失败,因为在hw.a
处理时,链接器尚不知道稍后需要该定义,并且不将其包含在is.generated可执行文件中.与连接线手动摆弄周围是不实际的,所以解决方案是使用--start-group
和--end-group
它通过库使得连接器运行两次,直到没有未定义的符号被发现了.
g++ main.o -Wl,--start-group hw.a gui.a -Wl,--end-group -o executable
Run Code Online (Sandbox Code Playgroud)
然而,GNU ld手册说
使用此选项会产生显着的性能成本.最好只在两个或多个档案之间存在不可避免的循环引用时才使用它.
所以我认为最好把所有.a
文件放在一个.a
带有索引(-s
GNU ar选项)的文件中,该文件说明文件需要链接的顺序.然后只给出一个.a
文件g++
.
但我想知道这是否比使用组命令更快或更慢.这种方法有什么问题吗?我也想知道,有没有更好的方法来解决这些相互依赖问题?
编辑:我编写了一个程序,它接受一个.a
文件列表并生成一个合并.a
文件.使用GNU通用ar
格式.将LLVM的所有静态库打包在一起就像这样工作
$ ./arcat -o combined.a ~/usr/llvm/lib/libLLVM*.a
Run Code Online (Sandbox Code Playgroud)
我将速度与.a
手动解.a
压缩所有文件进行比较,然后使用ar
重新计算索引将它们放入新文件中.使用我的arcat
工具,我获得大约500毫秒的一致运行时间.使用手动方式,时间变化很大,大约需要2秒.所以我认为这是值得的.
代码就在这里.我把它放到公共领域:)
.a存档格式标头需要时间戳.当我重建静态库时,这导致了无数的麻烦,主要是因为我无法完全重现原始二进制文件.
例如(这是在我的Mac上,但在x64 linux中也是如此):
$ cat foo.h
int foo();
$ cat foo.c
#include "foo.h"
int foo() { return 3; }
$ gcc -fno-pic -m64 -arch x86_64 -I/usr/local/include -O3 -c foo.c -o foo.o -fpic
$ ar rcs libfoo.a foo.o
$ md5 libfoo.a
MD5 (libfoo.a) = 0d0e6606185de4e994c47f4a0e54c1c4
$ mv libfoo.a libfoo.a1
$ ar rcs libfoo.a foo.o
$ md5 libfoo.a
MD5 (libfoo.a) = 22a69d42e1325ae8f978c2a18a4886da
Run Code Online (Sandbox Code Playgroud)
为了向自己证明唯一的区别是时间,我采用了基于hexdump的差异:
$ diff <(hexdump libfoo.a) <(hexdump libfoo.a1)
2,3c2,3
< 0000010 20 20 20 20 20 20 20 20 31 33 …
Run Code Online (Sandbox Code Playgroud) 我正试图通过cocoapods运送静态库.我的图书馆没有任何构建方向,现在它已经下载到我的iOS应用程序.我不需要为每个使用它的应用程序构建库,而只需下载lib文件并包含头文件.有没有办法用podspec文件执行此操作?
这是我到目前为止所拥有的:
Pod::Spec.new do |s|
s.name = "RTMPLib Library"
s.version = "1.0.0"
s.summary = "RTMPLib Library"
s.homepage = "https://github.com/jumper/RTMPLib.git"
s.license = { :type => 'MIT', :file => 'LICENSE' }
s.author = { "jon morehouse" => "jon@jumperapp.com" }
s.source = { :git => "https://github.com/jumper/RTMPLib.git", :tag => "#{s.version}" }
s.platform = :ios, '7.0'
# arc components
s.requires_arc = false
s.preserve_paths = 'inc/rtmplib/*.h'
s.vendored_libraries = 'lib/rtmplib.a'
s.libraries = 'rtmplib'
s.xcconfig = { 'HEADER_SEARCH_PATHS' => '${PODS_ROOT}/#{s.name}/inc/rtmplib/**'}
s.preserve_paths = 'L.framework'
end
Run Code Online (Sandbox Code Playgroud)
实际的代码结构可以在这里找到:Git Repo
我正在尝试将SDK添加到我的Xcode项目中.SDK包含.a文件和(标题).h文件.标头将导入到我的Bridging-Header文件(已成功).
在标题中有一个 #include <map>
当我运行项目时,我得到了一个
找不到Erorr'map'文件
当我cmd +点击它Xcode带我到LLVM编译器基础设施.
这里出了什么问题?
我正在使用Xcode Version 7.2(7C68)和Swift 2.0.
我有一个犹豫不决的关于将我的项目转换为lib或框架,以便在另一个项目中使用它并隐藏我的代码.
我一直在网上寻找关于什么是更好,框架或lib的一些材料.有几种框架(大多数框架都不受Apple支持,通常需要一些"法律黑客"来构建它们,例如假框架和动态框架......).
有人可以推荐并解释什么是更好的选择吗?框架或库(.a文件).
.a ×10
c ×3
ios ×3
linker ×3
unix-ar ×3
c++ ×2
.so ×1
android ×1
android-ndk ×1
cocoapods ×1
compilation ×1
file ×1
frameworks ×1
gcc ×1
header-files ×1
linux ×1
objective-c ×1
swift ×1
unix ×1
xcode ×1