본문 바로가기
Linux

[Linux] 라이브러리 설치 후 빌드 시 라이브러리를 찾지 못하는 오류 해결 회고 ( 라이브러리 링킹 에러 )

by dragonDeok 2024. 6. 7.
728x90

문제 발생 상황


Linux에서 마이크로소프트에서 제공하는 오픈소스 패키지 관리자인 vcpkg를 설치하는 과정에서 C++ 코드 빌드 시 라이브러리를 찾지 못하는 문제 발생

  • vcpkg란?
    Windows, linux, MacOS 에서 C++ 라이브러리 관리를 도와주는 패키지 관리자

vcpkg 패키지 관리자 설치 방법


  1. MS 공식 문서
    위 문서를 참고하여 vcpkg를 linux에 설치
  2. 환경변수 PATH를 확인PATH에 있는 경로 중 한 곳에 vcpkg 라이브러리 설치 ( 나는 /usr/loca/bin에 설치 )
  3. echo $PATH
  4. ~/.bashrc 에 아래 내용 추가
  5. export VCPKG_ROOT=/usr/local/bin/vcpkg
    export PATH=$VCPKG_ROOT:$PATH
  6. source ~/.bashrc 를 입력하여 변경사항 적용

vcpkg로 C++ 라이브러리 다운로드 후 빌드 시 발생한 에러


에러 발생 원인

vcpkg install azure-core-cpp azure-identity-cpp
  • 위 커맨드를 입력하여 azure-core-cpp, azure-identity-cpp 라이브러리를 설치
  • 해당 경로에 패키지가 잘 설치되었는데 c++ 코드 빌드 시 헤더파일을 찾을 수 없다는 빌드 에러 발생

발생한 에러 원인 파악


설치한 라이브리러 파일들을 확인해보니 .a 형태의 정적 링크 파일이었음

처음에는 라브리러리가 있는 위치의 .a 정적 링크 파일들을 읽어들이지 못하는 것 같아서 빌드할 때
모든 .a 파일을 자동으로 링크하기 위해 아래 옵션을 사용하였다.
( -Wl,-whole-archive와 -Wl,-no-whole-archive 옵션 사이에 필요한 모든 정적 라이브러리 )

g++ -o Test
-Wl,-whole-archive
-lazure-core -lazure-identity
-Wl,-no-whole-archive
obj/test/Test.o
-L/usr/local/bin/vcpkg/installed/x64-linux/lib

하지만 이렇게 해도 libazure_core.a 파일을 링킹하지 못해 빌드 에러가 발생했다.
그래서 아래와 같이 예제 코드를 MS azure 공식 사이트에서 찾아서 빌드 시도했다.

먼저 아래 예제 코드를 실행

#include <azure/core.hpp>
#include <azure/identity.hpp>
#include <iostream>
using namespace std;

int main() {
  // try {
  //  auto uuid = Azure::Core::Uuid::CreateUuid();
  //  string uuidString = uuid.ToString();
  //  cout << "Generated UUID: " << uuidString << endl;
  // } catch (const exception& e) {
  //  cerr << "Failed to create UUID: " << e.what() << endl;
  //  return 1;
  // }
  auto credential = std::make_shared<Azure::Identity::ManagedIdentityCredential>();
}
  • 발생한 build error
    undefined reference to Azure::Core::Uuid::CreateUuid()
    undefined reference to Azure::Core::Uuid::ToStringabi:cxx11
    ...

여기서 의아함을 느껴 코드 주석처리를 바꿔서 다시 빌드해봤다.

#include <azure/core.hpp>
#include <azure/identity.hpp>
#include <iostream>
using namespace std;

int main() {
  try {
   auto uuid = Azure::Core::Uuid::CreateUuid();
   string uuidString = uuid.ToString();
   cout << "Generated UUID: " << uuidString << endl;
  } catch (const exception& e) {
   cerr << "Failed to create UUID: " << e.what() << endl;
   return 1;
  }
  auto credential = std::make_shared<Azure::Identity::ManagedIdentityCredential>();

}
  • 이전 코드에서 발생한 build error들 중 아래 두가지 에러는 발생하지 않음
    undefined reference to Azure::Core::Uuid::CreateUuid()
    undefined reference to Azure::Core::Uuid::ToStringabi:cxx11

그래서 문제없이 읽은 아래 부분만 코드에 남기고 빌드를 해봤더니 성공했다.

  try {
   auto uuid = Azure::Core::Uuid::CreateUuid();
   string uuidString = uuid.ToString();
   cout << "Generated UUID: " << uuidString << endl;
  } catch (const exception& e) {
   cerr << "Failed to create UUID: " << e.what() << endl;
   return 1;
  }

그 후 생성된 실행 파일을 nm을 통해 확인해보니 라이브러리들이 정적 링크 파일이기 때문에
전부 다 복사해와서 실행 파일의 용량이 매우 클텐데 내 생각과 달리 용량이 매우 작았다.

아! vcpkg로 설치한 정적 링크 라이브러리 파일들은 직접 코드에서 호출하면 빌드할 때 참조하지만
직접 호출하지 않으면 호출하지 않은 라이브러리는 참조하지 않는구나라는 것을 찾았다.

해결


vcpkg로 설치한 azure 라이브리러는 정적 링크 파일일 때 호출한 부분만 빌드시 복사해오는 것을
알아냈기 때문에 동적 링크 파일로 설치하면 해결될 것이라고 판단

  1. --triplet옵션을 사용하여 동적 라이브러리 설치
  2. vcpkg install azure-core-cpp azure-identity-cpp --triplet x64-linux-dynamic
  3. 빌드시 새로운 라이브러리 경로 지정
  4. g++ -o Test obj/test/Test.o -L/usr/local/bin/vcpkg/installed/x64-linux-dynamic/lib -lazure-core -lazure-identity
  5. 동적 라이브리러를 찾을 수 있도록 라이브러리 경로를 환경 변수에 추가
  6. export LD_LIBRARY_PATH=/usr/local/bin/vcpkg/installed/x64-linux-dynamic/lib:$LD_LIBRARY_PATH

위 과정을 통해 기존 코드 빌드시 정상적으로 설치한 라이브러리를 호출하였다.

'Linux' 카테고리의 다른 글

[Linux] Azure SDK 설치 시 라이브러리 경로 설정  (0) 2024.06.21