我有一个类似的问题,但在我的情况下,我试图弄清楚如何在 Windows 中做到这一点。我想要静态库,但链接到动态运行时(/MD 与 /MT。)
尝试自己构建 gRPC。最终选择了vcpkg 路线,这要好得多,尤其是在 Windows 中使用开源软件时!
但是,在 Windows 上,vcpkg 默认只构建 2 个东西:完全动态或完全静态。我想要的是与动态运行时链接的静态库。为此,您必须创建自己的三元组。这是我的做法:
git clone https://github.com/Microsoft/vcpkg.git
cd vcpkg
bootstrap-vcpkg.bat
vcpkg integrate install
vcpkg integrate powershell
cd triplets
copy x64-windows.cmake x64-windows-mixed.cmake
编辑x64-windows-mixed.cmake,使其包含以下 3 行:
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
然后安装并构建 gRPC 和 protobufs:
cd ..
vcpkg.exe install grpc:x64-windows-mixed protobuf:x64-windows-mixed
如果您使用的是 Linux,那么看起来默认的三元组可能已经正确,因为 x64-linux.cmake 文件默认为:
set(VCPKG_TARGET_ARCHITECTURE x64)
set(VCPKG_CRT_LINKAGE dynamic)
set(VCPKG_LIBRARY_LINKAGE static)
set(VCPKG_CMAKE_SYSTEM_NAME Linux)
一旦您在 vcpkg 中构建了所有内容,您将需要自定义您自己项目的 cmake 文件以查找正确的软件,并链接到正确的 .a 文件。我没有在 linux 上尝试过,但在 Windows 中,我的项目包括以下内容:
FIND_PACKAGE ( protobuf CONFIG REQUIRED )
FIND_PACKAGE ( c-ares CONFIG REQUIRED )
FIND_PACKAGE ( gRPC CONFIG REQUIRED )
FIND_PACKAGE ( ZLIB REQUIRED )
FIND_PACKAGE ( OpenSSL REQUIRED )
FIND_PACKAGE ( Threads REQUIRED )
为了确保我有正确的 vcpkg 包含目录,我使用了这个:
FIND_PATH ( SYSTEM_INCLUDE_DIR zlib.h )
INCLUDE_DIRECTORIES ( ${SYSTEM_INCLUDE_DIR} )
然后在链接时,我确保TARGET_LINK_LIBRARIES 包含以下内容:
PUBLIC Threads::Threads
protobuf::libprotoc protobuf::libprotobuf protobuf::libprotobuf-lite
gRPC::gpr gRPC::grpc gRPC::grpc++ gRPC::grpc_cronet
c-ares::cares c-ares::cares_static
OpenSSL::SSL OpenSSL::Crypto
ZLIB::ZLIB )
第一次运行cmake时,记得指定工具链文件和前缀路径。在 Windows 上,我还必须告诉它使用哪个三元组。该命令如下所示:
mkdir build
cd build
cmake \
-DCMAKE_BUILD_TYPE=Debug \
-DCMAKE_TOOLCHAIN_FILE=/src/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DCMAKE_PREFIX_PATH=/src/vcpkg/installed/x64-windows-mixed \
-DVCPKG_TARGET_TRIPLET=x64-windows-mixed \
..
(最后一个命令在 Windows 中不能以这种方式分解,我在这里只是为了帮助显示我传入的参数。)