# mac m1(arm64) 환경에서 my 라는 프로젝트에서 빌드를 할때
# my/include 와 my/lib 에 디렉토리에 소스로 빌드한 protobuf 등의 라이브리 결과물이 있고
# 이를 링크하는 my 프로젝트에서 cmake > make 빌드 중 다음과 같은 에러가 발생했다.
Undefined symbols for architecture arm64:
"grpc_call_run_in_event_engine(grpc_call const*, absl::lts_20250127::AnyInvocable<void ()>)", referenced from:
... 생략 ... "google::protobuf::internal::AssignDescriptors(google::protobuf::internal::DescriptorTable const* (*)(), absl::lts_20250127::once_flag*, google::protobuf::Metadata const&)", referenced from:
... 생략 ...
# 동적라이브러리(.dylib) 파일들 경로는 이상 없이 lib/을 링킹하고 있었다
# 해당 dylib 파일의 타입도 다음과 같이 arm64 로 빌드되어 있었다.
file /Users/ysoftman/workspace/my/lib/libprotobuf.25.6.0.dylib
/Users/ysoftman/workspace/my/lib/libprotobuf.25.6.0.dylib: Mach-O 64-bit dynamically linked shared library arm64
# protobuf 에서 AssignDescriptors() 심볼도 다음과 같이 확인하니 존재했다.
nm -gU /Users/ysoftman/workspace/my/lib/libprotobuf.25.6.0.dylib | rg AssignDescriptors
00000000000d2fa8 T __ZN6google8protobuf8internal17AssignDescriptorsEPFPKNS1_15DescriptorTableEvEPN4absl12lts_202407229once_flagERKNS0_8MetadataE
00000000000d2ff4 T __ZN6google8protobuf8internal17AssignDescriptorsEPKNS1_15DescriptorTableE
# protobuf 라이브러리에서 사용하는 dylib 를 다음과 같이 확인하니
# abseil(absl, c++ standard 에 없는 기능들이 있는 구글에서 만든 오픈소스 라이브러리) 2407 버전을 사용하게 되어 있다.(/opt/homebrew/opt.. 경로를 사용하고 있음)
# 그런데 위 에러에 보이는 absl 20250127 보다 이전이다.
otool -L /Users/ysoftman/workspace/my/lib/libprotobuf.25.6.0.dylib
... 생략 ...
/opt/homebrew/opt/abseil/lib/libabsl_log_initialize.2407.0.0.dylib (compatibility version 2407.0.0, current version 0.0.0)
/opt/homebrew/opt/abseil/lib/libabsl_statusor.2407.0.0.dylib (compatibility version 2407.0.0, current version 0.0.0)
... 생략 ...
# my/lib/libprotobuf.25.6.0.dylib 소스 빌드시 프로젝트 absl 은 패키지(시스템 기본 설정, brew install abseil로 설치됨)를 이용하게 되어 있는게 문제였다.
# 참고로 brew uninstall abseil 하면 시스템에서 이미 mysql 등에서 사용하고 있어 디펜던시가 있다.
cmake -DCMAKE_BUILD_TYPE=RelWithDebInfo \
-DCMAKE_INSTALL_PREFIX:PATH=$PREFIX \
-DCMAKE_INSTALL_LIBDIR:PATH=lib \
-DCMAKE_CXX_STANDARD=17 \
-DBUILD_SHARED_LIBS=1 \
-Dprotobuf_BUILD_TESTS=0 \
-Dprotobuf_ABSL_PROVIDER=package .
# 정리하면 abseil 버전이 다음과 같이 2개가 있는 상태다.
# 시스템에 기본 버전: /opt/homebrew/Cellar/abseil/20240722.1
# 커스텀 빌드: /Users/ysoftman/workspace/my/lib/libabsl_xxx.2501.0.0.dylib
# my/lib/ 로 설치 전 커스텀 빌드 소스들(cmake 정보등) my/abseil-cpp-20250127.0 에 있다.
# protobuf dylib 빌드시 다음 2개의 값을 설정하면 커스텀한(absl 2501버전) dylib 를 참조해 빌드할 수 있다.
# 참고로 아래 변수이름은 protobuf 소스 > cmake > abseil-cpp.cmake 를 참고해 알 수 있었다.
# protobuf cmake 에 수행시 다음과 같이 커스텀 absl 을 사용해 빌드(cmake and build)
-Dprotobuf_ABSL_PROVIDER=module \
-DABSL_ROOT_DIR="/Users/ysoftman/workspace/my/abseil-cpp-20250127.0" \
# grpc 도 에러나 발생하니 수정
# grpc 빌드는 absl protobuf re2 cares 다음과 같이 빌드(cmake and bulid)
# 참고로 아래 변수이름은 gproc 소스 > cmake > xxx.cmake 를 참고해 알 수 있었다.
-DgRPC_ABSL_PROVIDER=module \
-DABSL_ROOT_DIR="/Users/ysoftman/workspace/my/abseil-cpp-20250127.0" \
-DgRPC_PROTOBUF_PROVIDER=module \
-DPROTOBUF_ROOT_DIR="/Users/ysoftman/workspace/my/protobuf-25.6" \
-DgRPC_RE2_PROVIDER=module \
-DRE2_ROOT_DIR="/Users/ysoftman/workspace/my/re2-2024-07-02" \
-DgRPC_CARES_PROVIDER=module \
-DCARES_ROOT_DIR="/Users/ysoftman/workspace/my/c-ares-1.34.4" \
# 또는 PROVIDER=package 로 둔 상태에서 CMAKE_PREFIX_PATH(include,header경로)를 설정해도 된다.
-DCMAKE_PREFIX_PATH="/Users/ysoftman/workspace/my"
# 위와 같은 커스텀 dylib 를 생성하려면
# absl, re2 --> protobuf
# absl, re2, protobuf --> grpc
# 로 관련된 모든 ~/Users/ysoftman/workspace/my...의 커스텀 경로를 해줘야해서 복잡하고 불편한다.
# 그리고 my 프로젝트에서 빌드시 커스텀 라이브러리 사용으로 또 다른 에러가 발생했다.
# 그냥 다음 패키지(라이브러리)들은 소스 빌드를 하지 않고 설치하고 -DxxxPROVIDER=package 로 원복
# 커스텀 라이브러리들 목록에서 제외(my/{include,lib}에 생성되지 않아)하면 my 프로젝트도 다음 시스템 패키지를 사용해 문제 없이 빌드됐다.
brew install abseil re2 protobuf grpc