CMake - 링커 의존성

mohadang·2022년 8월 13일
0

CMake

목록 보기
22/24
post-thumbnail

링킹 순서 과정에서 오류

  • GNU 링커에서만 오류 발생 가능성 있음
cmake_minimum_required(VERSION 2.8)
project(foo)

add_library(bar bar.cpp)
add_library(boo boo.cpp)

add_executable(foo foo.cpp)
# 링크는 왼쪽에서 오른쪽 순으로 처리한다. 그래서 bar 부터 먼저 처리
target_link_libraries(foo PUBLIC bar boo)
# 소스 파일

[bar.cpp]
  int bar() {
    return 0x42;
  }

[boo.cpp]
  int bar();

  int boo() {
    return bar();
  }

[foo.cpp]
  int boo();

  int main() {
    return boo();
  }
# 의존성 순서
foo -> boo -> bar
red@DESKTOP-G15ND3V:~/cgold$ cmake --build _build/
Scanning dependencies of target boo
[ 16%] Building CXX object CMakeFiles/boo.dir/boo.cpp.o
[ 33%] Linking CXX static library libboo.a
[ 33%] Built target boo
[ 66%] Built target bar
[ 83%] Linking CXX executable foo
libboo.a(boo.cpp.o): In function `boo()':
boo.cpp:(.text+0x5): undefined reference to `bar()'    # bar를 참조 할 수 없음
collect2: error: ld returned 1 exit status
CMakeFiles/foo.dir/build.make:104: recipe for target 'foo' failed
make[2]: *** [foo] Error 1
CMakeFiles/Makefile2:99: recipe for target 'CMakeFiles/foo.dir/all' failed
make[1]: *** [CMakeFiles/foo.dir/all] Error 2
Makefile:102: recipe for target 'all' failed
make: *** [all] Error 2

- 위 예에서 발생하는 문제
  - 컴파일 완료후 3개의 파일 생성됨
    object CMakeFiles/foo.dir/foo.cpp.o
    archive libbar.a
    archive libboo.a
- CMakeFiles/foo.dir/foo.cpp.o 안에서 boo() 참조 하지만 boo() 심볼이 정의되지 않음
  - boo() 에대한 심볼 누락 발생
- libbar.a는 bar()를 정의함, 그러나 foo.cpp.o에서 발생한 boo()에 대한 심볼 누락을 해결할 수 없음
  - 그래서 bar() 심볼 드랍(필요 없는 것으로 인식)
- libboo.a 에서 int boo() 정의함 그리고 정의되지 않은 심볼 int bar()를 가지고 있음
  - int boo() 심볼을 누락에서 제거
  - 현재까지 int bar()가 심볼 누락 상태임
- 링커가 처리할 남은 파일 없음, bar()는 누락된 채로 남음

- bar()에대한 심볼 해석을 먼저 하였지만 마지막 파일의 링킹 과정에서 bar()에대한 심볼 누락이 발생하여 
  심볼 누락으로 덮어써버린 상황
  • 해결 방법 : target_link_libraries로 직접 의존성을 설정해 주어야함
cmake_minimum_required(VERSION 2.8)
project(foo)

add_library(bar bar.cpp)
add_library(boo boo.cpp)
target_link_libraries(boo PUBLIC bar bar) # boo -> bar

add_executable(foo foo.cpp)
target_link_libraries(foo PUBLIC boo) # foo -> boo
profile
mohadang

0개의 댓글