ar cr
, libabc.a
및 에서 만든 2 개의 정적 Linux 라이브러리가 libxyz.a
있습니다.
하나의 정적 라이브러리로 병합하고 싶습니다 libaz.a
.
어떻게 할 수 있습니까?
두 라이브러리를 응용 프로그램의 최종 링크에 제공하지 않고 병합 된 정적 라이브러리를 만들고 싶습니다.
ar cr
, libabc.a
및 에서 만든 2 개의 정적 Linux 라이브러리가 libxyz.a
있습니다.
하나의 정적 라이브러리로 병합하고 싶습니다 libaz.a
.
어떻게 할 수 있습니까?
두 라이브러리를 응용 프로그램의 최종 링크에 제공하지 않고 병합 된 정적 라이브러리를 만들고 싶습니다.
답변:
두 .a
파일 에서 객체를 .a
추출하고 추출 된 .o
s를 사용하여 파일을 만들 수 있습니다 .
ar -x libabc.a
ar -x libxyz.a
ar -c libaz.a *.o
libabc.a
동일한 이름 (다른 디렉토리에서 생성 된 형식)을 가진 객체를 포함 할 수 있습니다. 그러면 재 조립이 작동하지 않습니다!
ar -c
나를 위해 작동하지 않았습니다 (Ubuntu 14.04). 나는 ar: no operation specified
. 나는 ar -qc
대신했고 그것은 잘 작동했습니다.
기본적 으로이 작업을 수행하는 방법에는 세 가지 이상이 있습니다. 가장 이식 가능한 첫 번째 방법은 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
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!
libtool
하면 다음 오류가 발생합니다. libtool: link: unable to infer tagged configuration libtool: error: specify a tag with '--tag'
이 문제를 해결하는 방법에 대한 아이디어가 있습니까?
--Wl,-whole-archive
옵션은 여러 LIB * .A에 대한 원래의 연결 명령에 필요한, 나는에 모든 LIB * .A를 결합해야한다 one.a
. 다시 연결하면에서 --Wl,-whole-archive
작동하지 않습니다 one.a
. 당신의 제안은 무엇입니까? stackoverflow.com/questions/56323197/…
단순히 다음과 같이하면 :
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
이렇게하면 링커가 모든 것을 처리합니다!
-fPIC
.
각 라이브러리에서 부분 링크를 수행하고 두 결과 오브젝트 파일의 아카이브를 만드는 것이 더 좋습니다. 그렇게하면 공유 라이브러리처럼 작동합니다.
당신은
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
libtool
기반 솔루션 :libtool -static -o new.a old1.a old2.a