임베디드 관련 카테고리/C++

CMake와 Meson에서 만든 정적 라이브러리 .a 파일, 호환이 될까?

CBJH 2025. 4. 11. 14:45
728x90
반응형

cmake, https://github.com/mesonbuild, {Fast, Correct} — Choose two, Build and test software of any size, quickly and reliably

 

C++ 프로젝트를 빌드할 때 자주 사용되는 빌드 시스템인 CMakeMeson, Bazel.
이 두 빌드 시스템은 내부 구조가 다르지만, 둘 다 .cpp 파일을 컴파일해 .o를 만들고, .o를 모아서 .a라는 정적 라이브러리를 생성한다는 점은 같습니다.

그렇다면,

CMake로 만든 .a 정적 라이브러리 파일을 Meson 프로젝트에서 사용할 수 있을까요?
혹은 그 반대는 가능할까요?

결론부터 말씀드리면, 가능합니다. 하지만 몇 가지 조건을 만족해야 해요.


정적 라이브러리 .a의 정체

정적 라이브러리(.a)는 여러 개의 오브젝트 파일(.o)을 묶은 압축 파일로, 실행파일을 만들 때 링커가 참조하는 대상입니다.

📦 예시:

ar rcs libmylib.a file1.o file2.o

이 파일은 libmylib.a라는 이름의 정적 라이브러리가 되어, 이후 다른 프로젝트에서 사용할 수 있습니다.


🔄 CMake와 Meson 간 .a 라이브러리 호환이 가능한 조건

CMake에서 만든 .a 파일을 Meson에서 사용하거나, 반대로 사용하려면 아래 조건들을 만족해야 해요.


1. 🔧 동일한 컴파일러 (또는 ABI 호환)

  • GCC와 Clang처럼 컴파일러 종류가 다르면 ABI가 다를 수 있습니다.
  • 컴파일러 버전이 크게 다르면, 심볼 이름 규칙(name mangling)이 달라져 충돌할 수 있어요.

🟡 예시:

# CMake에서 GCC로 만든 경우
g++ -c -o foo.o foo.cpp
ar rcs libfoo.a foo.o

Meson에서도 동일한 컴파일러를 사용해야 합니다.


2.  C++ 표준 일치 (-std=c++17, c++14 등)

CMake와 Meson이 다른 C++ 표준을 사용하면 컴파일 시 오류가 발생하거나, 링크 시 충돌할 수 있어요.

✔️ CMake 예시:

target_compile_features(mylib PUBLIC cxx_std_17)

✔️ Meson 예시:

add_project_arguments('-std=c++17', language: 'cpp')

3.  -fPIC 옵션 여부 (Position Independent Code)

  • .a 파일을 동적 라이브러리(.so)로 변환하려면 -fPIC 옵션이 필요해요.
  • CMake에서는 CMAKE_POSITION_INDEPENDENT_CODE 옵션으로 설정합니다.

✔️ CMake:

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

✔️ Meson:

static_library('foo', sources, pic: true)

4.  경로 및 링커 설정

Meson에서 외부 .a 파일을 사용할 때는 직접 명시해줘야 합니다.

✔️ Meson 예시:

libfoo = declare_dependency(
  link_args: ['-L/path/to/lib', '-lfoo'],
  include_directories: include_directories('/path/to/include')
)

또는 .cpp를 가져와서 static_library()로 다시 만들 수도 있어요.


❗ 주의할 점 요약

항목맞아야 호환 가능주의사항
컴파일러 종류 / 버전 GCC vs Clang, 버전 차이 주의
C++ 표준 버전 c++14, c++17 등 통일
-fPIC 사용 여부 공유 라이브러리 목적이면 필수
플랫폼 (x86, ARM 등) 크로스 컴파일 시 주의

 정적 라이브러리 내부 확인하는 방법

.a 파일에 어떤 심볼이 들어 있는지 궁금할 때는 아래 명령어를 사용해보세요:

nm libfoo.a
  • 심볼 정보를 통해 어떤 함수나 변수가 포함되어 있는지 확인할 수 있어요.
  • 이름이 _Z...처럼 복잡하다면 C++ 심볼(mangled)이라는 뜻이니 컴파일러 호환성이 중요합니다.

 마무리 정리

  • 정적 라이브러리 자체는 단순한 .o 파일의 모음이므로, 구조적으로는 호환이 가능합니다.
  • 하지만 컴파일러, 표준, 옵션, 플랫폼 등 ABI 호환 조건이 맞지 않으면 오류가 발생할 수 있어요.
  • 실무에서는 가능하면 .cpp 원본 파일을 가져와서 프로젝트 내에서 빌드하는 방식이 가장 안전합니다.

궁금한 점이나 추가로 보고 싶은 예시가 있다면 댓글로 남겨주세요!
이 글이 도움이 되셨다면 공감과 구독 부탁드립니다 😊