libary 생성 레시피 작성

markyang92·2021년 8월 19일
0

yocto

목록 보기
15/53
post-thumbnail

static library

static library src

  • tree

  • src/arith.c

  • src/print.c

  • src/mylib.h

  • userprog.c

static library 생성

  • src: src/arith.o, src/print.o
$ ar rcs libmyhello.a arith.o print.o
ar optiondescription
r라이브러리에 오래된 object 파일이 있으면, 새 object 파일로 교체
carchive가 존재하지 않으면 생성
sarchive에 object file index 넣기, 이 index는 library에서 symbol-lookup 으로 컴파일러에서 사용될 것임

recipe

  1. local compile
$ gcc -Wall -I./src userprog.c -lmyhello -L./lib -o userprog
  1. recipe

결과

  1. image
  1. packages-split
  1. packages

shared library

shared library src

  • src는 위 static library것 그대로 사용함

shared library 생성

  1. .c파일 -> .o파일 컴파일 시 -fPIC 옵션
$ gcc -fPIC -c src1.c
$ gcc -fPIC -c src2.c
CFLAGSdescription
-fPICPosition Independent Code로 Compile. Shared library의 필수요소

  1. .o -> .so : shared library 생성

CFLAGSdescription
-sharedcompiler에게 executable한 object에게 link를 걸어 줄 수 있는 shared object를 만든다고 set하는 것

linker optiondescription
-Wl,[options]-Wl, 은 링커에게 전해주는 옵션. 뒤에 [options]에 링크 옵션을 넣는다.
-Wl,-soname,lib[name].so.1생성 하려는 shared librarysoname을 지어준다.
soname에는 major 버전만 명시

  1. main program build 시, 위에서 생성한 shared library 링크해서 빌드
$ gcc -L<library Path> main.c -l<library> -o main
  • -Lshared library 위치를 알려주어 Compile
  • -lshared library link

컴파일 되어도, shared library는 프로그램 실행 시 dynamic으로 링크 되기 때문에,
링커가 shared library 위치를 못찾을 수 있음!!

  • 그래서 -rpath를 사용함


$ gcc -I. -Wl,-rpath,/usr/bin -L. userprog.c -lmyhello -o userprog
혹은
$ gcc -I. -wl,-rpath=/usr/bin -L. userprog.c -lmyhello -o userprog

실행 시, 위치 (-rpath 안쓸경우)

  • shared library는 compile 때는 -L<path>를 지정 했기 때문에 알아먹었지만.. 실행 시는 동적으로 찾음
  1. /lib, /usr/lib, /usr/local/lib 에 위치 시키지 않았다면 아래와 같이 해야 shared library 위치를 알아먹음

  1. export LD_LIBRARY_PATH 환경 변수 지정
$ export LD_LIBRARY_PATH="$HOME/somewhere"

  1. /etc/ld.so.conf 에 shared libary위치 작성

3-1. /etc/ld.so.conf에 직접 위치 작성 (비추천)

최근에는 ld.so.conf 파일에 아래와 같은 문구 만 있음

include /etc/ld.so.conf.d/*.conf

즉, /etc/ld.so.conf.d/에 있는 내용을 include


3-2. /etc/ld.so.conf.d/libexample.conf 파일 작성

# libexample.conf 
/some/where/library/path

작성 후, /etc/ld.so.cache 를 갱신 하는 명령인 ldconfig 실행

$ ldconfig

Shared library 이름 규칙

  • libexample.so 라는 shared library 가 있다고 가정.
Naming Conventione.g.Description
Linker namelibexample.so링커가 '-lexample' 과 같이 링킹할 때 사용되는 이름
libexample.so -> libexample.so.1 소프트링크
Sonamelibexample.so.1모든 shared library 가 가지고 있는 soname
'libexample.so.1' 처럼 major 버전 명시
libexample.so.1 -> libexample.so.1.2 소프트링크
Real Namelibexample.so.1.2실제 파일


$ readelf -d <library>: soname 읽기


recipe

.so -> ${libdir} = /usr/lib
.h -> ${includedir} = /usr/include

  1. recipe

do_compile()

  1. S="${WORKDIR}/git" 이기 때문에, source들이 S에 unpack 된다.

  2. bitbake -c unpack myhello 결과

  1. bitbake -c compile myhello 결과
  • do_compile() 은 기본적으로 S 에서 이루어짐
  • binary 결과는 ${CC}로 컴파일 적용, 즉 --target용으로 컴파일 됨

do_compile() {
    # ${CC} -fPIC -c print.c
    arm-poky-linux-gnueabi-gcc  -march=armv7ve -mthumb -mfpu=neon -mfloat-abi=hard \
    -fstack-protector-strong  -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security \
    -Werror=format-security \
    --sysroot=/home/dhyang/poky/build/tmp/work/armv7vet2hf-neon-poky-linux-gnueabi/myhello/0.7-r0/recipe-sysroot \
    -fPIC -c print.c
    
    
    arm-poky-linux-gnueabi-gcc  -march=armv7ve -mthumb -mfpu=neon -mfloat-abi=hard \
    -fstack-protector-strong  -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security \
    -Werror=format-security \
    --sysroot=/home/dhyang/poky/build/tmp/work/armv7vet2hf-neon-poky-linux-gnueabi/myhello/0.7-r0/recipe-sysroot \
    -fPIC -c arith.c
    
    
    arm-poky-linux-gnueabi-gcc  -march=armv7ve -mthumb -mfpu=neon -mfloat-abi=hard \
    -fstack-protector-strong  -D_FORTIFY_SOURCE=2 -Wformat -Wformat-security \
    -Werror=format-security \
    --sysroot=/home/dhyang/poky/build/tmp/work/armv7vet2hf-neon-poky-linux-gnueabi/myhello/0.7-r0/recipe-sysroot \
    -Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed -fstack-protector-strong -Wl,-z,relro,-z,now \
    -shared -Wl,-soname,libmyhello.so.1 -o libmyhello.so.1.0 print.o arith.o
}

do_install()

  1. ${WORKDIR}/image 결과


결과

image

  • ${WORKDIR}/image

package

  • ${WORKDIR}/package

packages-split

  • ${WORKDIR}/packages-split

Unversioned Library

  • Shared library가 빌드될 때, Verision이 지정이 되어야하지만 때로는 안할 때도 있다.
  • 몇 라이브러리 벤더들은 자신들의 source code를 release 하지 않고, pre-built binary만 release 한다.
  • 이러한 unversioned library를 추가하면, error
    • default packaging rule은 versioned library를 가정하고 동작하기 때문이다.

Unversioned library 제작

  • shred library에서, Unversioned Library를 제작해보자.
do_compile() {
    ${CC} -c -fPIC print.c
    ${CC} -c -fPIC arith.c
    ${CC} -${LDFLAGS} -shared -o libmyhello.so print.o arith.o
}

do_install() {
    install -d ${D}${libdir}
    install -m 0755 libmyhello.so ${D}${libdir}
    install -d ${D}${includedir}
    install -m 0644 mylib.h ${D}${includedir}
}

  • bitbake build 하면 엄청난 ERROR 유발한다.

  • ${WORKDIR}/packages-split


  • "libyhello.so"는 ${PN}-dev로 packed된다. 이는 QA warning을 이르키는데, non-symbolic link library is in a -dev package이기 때문이다.
  • 이 문제를 해결하기 위해, unversioned library가 package 때, ${PN}에 속하게 해야한다.
  • 다음은 요약된 디폴트 FILES variable in bitbake.conf이다.
SOLIBS = ".so.*"
SOLIBDEV = ".so"
FILES_${PN} = "... ${libdir}/lib*${SOLIBS} ..."
FILES_SOLIBESDEV ?= "... ${libdir}/lib*${SOLIBSDEV} ..."
FILES_${PN}-dev = "... ${FILES_SOLIBSDEV} ..."
  • SOLIBS는 real shared object libraries을 매치하는 pattern을 정의한다.
  • SOLIBSDEV는 form (unversioned symlink) development를 매칭한다.
  • 2개의 Variable은 FILES_${PN}과 FILES_${PN}-dev에 사용된다.
  • real libraries는 ${PN}에 놓고, unversioned symbolic link는 PN-dev.

unversioned libraries를 패키지하기 위해, 아래와 같이 변수를 수정해야한다.

SOLIBS = ".so"
FILES_SOLIBSDEV = ""

위 수정으로 .so 가 real library가 되고 FILES_SOLIBDEV가 unset되어 그결과 PN-dev에서 어떠한 libraries들도 패키지되지 않는다.



암시적인 -dev package RDEPENDS


  • -dev 패키지에 '심볼릭 링크가 아닌 .so' 파일이 추가될 경우, 기본 A패키지가 A-dev패키지를 RDEPENDS 해버린다.
profile
pllpokko@alumni.kaist.ac.kr

0개의 댓글