두 개의 "ar"정적 라이브러리를 하나로 병합하는 방법은 무엇입니까?


92

ar cr, libabc.a및 에서 만든 2 개의 정적 Linux 라이브러리가 libxyz.a있습니다.
하나의 정적 라이브러리로 병합하고 싶습니다 libaz.a.
어떻게 할 수 있습니까?

두 라이브러리를 응용 프로그램의 최종 링크에 제공하지 않고 병합 된 정적 라이브러리를 만들고 싶습니다.


8
참조 : libtool기반 솔루션 :libtool -static -o new.a old1.a old2.a
osgx

2
완벽하게 작동합니다. 해당 라이브러리에 공통 file.o가 있는지 의심의 여지가 있습니다 (그러나 기능면에서는 다름) 여전히 작동할까요?
bindingofisaac

libtool -static -o new.a old1.a old2.a는 linux (centos 7)에서 작동하지 않습니다
출발

답변:


61

.a파일 에서 객체를 .a추출하고 추출 된 .os를 사용하여 파일을 만들 수 있습니다 .

ar -x libabc.a
ar -x libxyz.a
ar -c libaz.a  *.o

65
위험 해, 윌 로빈슨! 이것은 libabc.a와 libxyz.a의 멤버 이름이 겹치지 않는 경우 에만 작동 합니다 . 그렇지 않으면 하나를 덮어 쓰고 손실됩니다.
데이비드 감안할

7
또한 libabc.a동일한 이름 (다른 디렉토리에서 생성 된 형식)을 가진 객체를 포함 할 수 있습니다. 그러면 재 조립이 작동하지 않습니다!
Igor R.

17
ar -c나를 위해 작동하지 않았습니다 (Ubuntu 14.04). 나는 ar: no operation specified. 나는 ar -qc대신했고 그것은 잘 작동했습니다.
Max

ar t lib.a는 실제로 파일을 추출하지 않고 라이브러리의 파일을 보는 데 사용할 수 있습니다.
raj_gt1

automake에서 어떻게 할 수 있습니까?
shuva

123

기본적 으로이 작업을 수행하는 방법에는 세 가지 이상이 있습니다. 가장 이식 가능한 첫 번째 방법은 libtool을 사용하는 것입니다. libtool을 사용하여 다른 라이브러리를 빌드 한 후 .la libs를 automake libaz_la_LIBADD 변수에 추가하거나 Makefile에서 다음과 같이 직접 결합 할 수 있습니다.

libtool --mode=link cc -static -o libaz.la libabc.la libxyz.la

나머지 두 개는 GNU ar을 사용할 때 최소한 사용할 수 있습니다. 다음과 같은 MRI 스크립트 (예 : libaz.mri)를 사용할 수 있습니다.

create libaz.a
addlib libabc.a
addlib libxyz.a
save
end

그런 다음 ar을 다음과 같이 실행하십시오.

ar -M <libaz.mri

또는 아카이브 (옵션 -T)를 사용하면 내부에 중첩되지 않고 다른 아카이브를 추가 할 수 있습니다.하지만 단점은 정적 라이브러리를 배포하려는 경우 분리 된 객체가 누락된다는 것입니다.

ar -rcT libaz.a libabc.a libxyz.a

위의 모든 방법은 원본 아카이브에서 겹치는 멤버 이름을 정상적으로 처리합니다.

그렇지 않으면 겹치는 멤버 이름을 바꾸지 않도록 다른 디렉토리에 압축을 풀고 다시 압축해야합니다.

mkdir abc; cd abc; ar -x ../libabc.a
mkdir xyz; cd xyz; ar -x ../libxyz.a
ar -qc libaz.a abc xyz

19
일반 아카이브 (씬이 아님)를 원하는 사용자를 위해 수행 할 수있는 간단한 작업 중 하나는 씬 아카이브를 만든 다음 일반 아카이브로 변환하는 것입니다. 같은 것 : ar cqT libaz.a libabc.a libxyz.a && echo -e 'create libaz.a\naddlib libaz.a\nsave\nend' | ar -M. 이렇게하면 임시 씬을 생성 한 libaz.a다음 씬 아카이브를 일반 아카이브로 변환하여 이동 / 배포 할 수 있습니다. 또한 라이브러리 이름에 특수 문자 (공백, 더하기 또는 쉼표) (예 :)가있는 경우에도 정상적으로 처리됩니다 ar cqT libbundle.a libfoo++.a 'libbar baz.a'. 하지만 나에게서 +1!
Cornstalks 2014 년

주어진 첫 번째 MRI 스크립트 예제의 단점은 무엇입니까?
JB

좋은 대답입니다! 추출하고 다시 연결할 필요가없는 몇 가지 옵션을 확인하는 것이 좋습니다. 또한 @Cornstalks 아이디어가 좋다고 생각합니다. 대답에 추가해야할까요?
Lightbulb1 2015

이 명령을 사용하려고 libtool하면 다음 오류가 발생합니다. libtool: link: unable to infer tagged configuration libtool: error: specify a tag with '--tag' 이 문제를 해결하는 방법에 대한 아이디어가 있습니까?
Lars Nielsen

@Guillem @Cornstalks 좋은 대답입니다. 뭐라고 경우 --Wl,-whole-archive옵션은 여러 LIB * .A에 대한 원래의 연결 명령에 필요한, 나는에 모든 LIB * .A를 결합해야한다 one.a. 다시 연결하면에서 --Wl,-whole-archive작동하지 않습니다 one.a. 당신의 제안은 무엇입니까? stackoverflow.com/questions/56323197/…
thinkdeep

10

단순히 다음과 같이하면 :

ar x a.a
ar x b.a
ar c c.a  *.o 

aa와 ba에 같은 이름의 멤버가있는 경우 일부 개체 파일이 손실되므로 다른 아카이브의 멤버를 다른 폴더로 추출해야합니다.

ar x a.a && mv *.o a_objs
ar x b.a && mv *.o b_objs
ar c c.a a_objs/*.o b_objs/*.o

또한 하나의 아카이브에 같은 이름의 여러 멤버가있을 수 있습니다 (예 : aa). ar x aa 를 실행 하면 같은 이름의 멤버에 대해 하나만 얻을 수 있습니다.

하나의 아카이브에서 동일한 이름의 모든 멤버를 추출하는 유일한 방법은 'N'옵션으로 멤버 번호를 지정하는 것입니다.

ar xN 1 a.a  xxx.c.o && mv xxx.c.o xxx.c.1.o
ar xN 2 b.a  xxx.c.o && mv xxx.c.o xxx.c.2.o
...

이것은 지루한 작업이므로 해당 작업을 수행하려면보다 정교한 스크립트를 작성해야합니다.

하나의 선택적 솔루션은 여러 아카이브를 하나의 공유 라이브러리로 결합 할 수 있다는 것입니다.

g++ -shared -o c.so -Wl,--whole-archive a.a b.a 

이렇게하면 링커가 모든 것을 처리합니다!


1
사무엘, 감사합니다. 그러나 공유 라이브러리로 결합 할 때 모든 객체는 -fPIC.
osgx

0

각 라이브러리에서 부분 링크를 수행하고 두 결과 오브젝트 파일의 아카이브를 만드는 것이 더 좋습니다. 그렇게하면 공유 라이브러리처럼 작동합니다.

당신은

gcc -r --nostdlib

따라서 중간 아카이브를 만드는 대신 또는 다시 추출한 후

gcc -r --nostdlib $CFLAGS $OBJECTS_A -o $LIBNAME_A.o
gcc -r --nostdlib $CFLAGS $OBJECTS_B -o $LIBNAME_B.o

그때

ar -cr $LIBNAME_JOINED.a $LIBNAME_A.o $LIBNAME_B.o

그가 도서관을 요청했기 때문에 질문에 실제로 대답하는 것이 아닙니다. 많은 경우 라이브러리에 대한 소스가 없거나 다른 이유로 미리 빌드 된 상태로 유지하려고합니다.
폴라 트

0
ar -x libx264.a
mkdir sub && cd sub
ar -m ../libx264.a `ar -t ../libx264.a |sort|uniq|grep "\.o"`
ar -x ../libx264.a

이제 "macroblock-10.o"의 두 가지 버전이 있습니다.


0
ar crsT libaz.a libabc.a libxyz.a

여기에서 아카이브 아카이브를 만든 다음 T 플래그를 사용하여 결과를 '평탄화'(얇게)합니다. 그 안에 포함될 수있는 동일한 이름의 .o 파일에서 어떻게 작동하는지 확실하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.