protobuf cmake Visual Studio 編譯安裝
中間踩了挺多的坑的, 這篇文章記錄一下.
重要前言: 所有在引用框中的命令都不要
輸入!!
cmake --install . # 在引用框中的不要輸入到命令列
cmake --install . --config Debug # 命令沒有被引用框包裹, 需要輸入到命令列中
0x00 環境配置
vs2022, git, cmake
0x01 原始碼下載
注意: 建議使用git clone的方式下載, 如果是透過github的Release下載的, 你得手動的配置protobuf的三方依賴.
git clone -b v28.0 https://github.com/protocolbuffers/protobuf-28.0.git
這裡v28.0
是版本號(本質是一個tag)
透過git submodule下載protobuf第三方依賴.
git submodule update --init --recursive
cd protobuf-28.0
cmake編譯前的配置
在專案中建立一個臨時編譯目錄, (我這裡使用的是powershell可使用mkdir, 如果你沒有mkdir命令, windows建立資料夾的命令是md)
mkdir cmake_build
cd cmake_build
cmake指定原始碼位置和編譯位置(我這裡優先使用命令的方式, 如果需要圖形化的方式(cmake-gui)也有說明)
cmake -S .. -B . -L
-S
指定source目錄,-B
執行build目錄,-L
檢視專案的一些編譯選項
PS C:\code_dependencies\protobuf-28.0\cmake_build> git submodule update --init --recursive
....................
Submodule path '../third_party/abseil-cpp': checked out '4a2c63365eff8823a5221db86ef490e828306f9d'
Submodule path '../third_party/googletest': checked out '4c9a3bb62bf3ba1f1010bf96f9c8ed767b363774'
Submodule path '../third_party/jsoncpp': checked out '9059f5cad030ba11d37818847443a53918c327b1'
PS C:\code_dependencies\protobuf-28.0\cmake_build> cmake -S .. -B . -L
-- Selecting Windows SDK version 10.0.26100.0 to target Windows 10.0.19045.
--
-- 28.0.0
-- Could NOT find ZLIB (missing: ZLIB_LIBRARY ZLIB_INCLUDE_DIR)
CMake Warning at third_party/abseil-cpp/CMakeLists.txt:82 (message):
A future Abseil release will default ABSL_PROPAGATE_CXX_STD to ON for CMake
3.8 and up. We recommend enabling this option to ensure your project still
builds correctly.
-- Performing Test ABSL_INTERNAL_AT_LEAST_CXX17
-- Performing Test ABSL_INTERNAL_AT_LEAST_CXX17 - Failed
-- Performing Test ABSL_INTERNAL_AT_LEAST_CXX20
-- Performing Test ABSL_INTERNAL_AT_LEAST_CXX20 - Failed
-- Configuring done (1.5s)
CMake Error at third_party/abseil-cpp/CMake/AbseilHelpers.cmake:317 (target_link_libraries):
The link interface of target "random_mocking_bit_gen" contains:
absl::random_internal_mock_overload_set
but the target was not found. Possible reasons include:
* There is a typo in the target name.
* A find_package call is missing for an IMPORTED target.
* An ALIAS target is missing.
Call Stack (most recent call first):
third_party/abseil-cpp/absl/random/CMakeLists.txt:100 (absl_cc_library)
-- Generating done (2.3s)
CMake Generate step failed. Build files cannot be regenerated correctly.
-- Cache values
ABSL_BUILD_TESTING:BOOL=OFF
ABSL_FIND_GOOGLETEST:BOOL=OFF
ABSL_GOOGLETEST_DOWNLOAD_URL:STRING=
ABSL_LOCAL_GOOGLETEST_DIR:PATH=/usr/src/googletest
ABSL_PROPAGATE_CXX_STD:BOOL=OFF
ABSL_USE_GOOGLETEST_HEAD:BOOL=OFF
ABSL_USE_SYSTEM_INCLUDES:BOOL=OFF
BUILD_TESTING:BOOL=ON
CMAKE_CONFIGURATION_TYPES:STRING=Debug;Release;MinSizeRel;RelWithDebInfo
CMAKE_INSTALL_PREFIX:PATH=C:/Program Files (x86)/protobuf
EXECINFO_LIBRARY:FILEPATH=EXECINFO_LIBRARY-NOTFOUND
LIBRT:FILEPATH=LIBRT-NOTFOUND
protobuf_ABSL_PROVIDER:STRING=module
protobuf_ALLOW_CCACHE:BOOL=OFF
protobuf_BUILD_CONFORMANCE:BOOL=OFF
protobuf_BUILD_EXAMPLES:BOOL=OFF
..........
如果你想調整編譯選項的開關, 請使用-D選項指定Key=Value, 命令執行過後, 可以不用重複執行.
例如下面的命令指定(在引用框中的不要輸入到命令列)
cmake -S .. -B . -Dprotobuf_BUILD_SHARED_LIBS=ON -Dprotobuf_USE_EXTERNAL_GTEST=OFF -Dprotobuf_WITH_ZLIB=OFF
我的配置是這樣的, 你可以按需修改. (後面的`符號是powershell的換行輸入字元, 如果你是linux, 請替換成\)
cmake -S .. -B . `
-DABSL_PROPAGATE_CXX_STD=ON `
-DCMAKE_INSTALL_PREFIX="C:\code_dependencies\protobuf" `
-Dprotobuf_BUILD_EXAMPLES=ON `
-Dprotobuf_BUILD_LIBPROTOC=ON `
-Dprotobuf_BUILD_LIBUPB=OFF `
-Dprotobuf_BUILD_PROTOBUF_BINARIES=ON `
-Dprotobuf_BUILD_PROTOC_BINARIES=ON `
-Dprotobuf_BUILD_SHARED_LIBS=ON `
-Dprotobuf_BUILD_TESTS=ON `
-Dprotobuf_INSTALL=ON `
-Dprotobuf_INSTALL_EXAMPLES=ON `
-Dprotobuf_MSVC_STATIC_RUNTIME=ON `
-Dprotobuf_WITH_ZLIB=OFF `
-Dutf8_range_ENABLE_INSTALL=ON `
-L `
執行結果如下
PS C:\code_dependencies\protobuf-28.0\cmake_build> cmake -S .. -B . ` >> -DABSL_PROPAGATE_CXX_STD=ON ` >> -DCMAKE_INSTALL_PREFIX="C:\code_dependencies\protobuf" ` >> -Dprotobuf_BUILD_EXAMPLES=ON ` >> -Dprotobuf_BUILD_LIBPROTOC=ON ` >> -Dprotobuf_BUILD_LIBUPB=OFF ` >> -Dprotobuf_BUILD_PROTOBUF_BINARIES=ON ` >> -Dprotobuf_BUILD_PROTOC_BINARIES=ON ` >> -Dprotobuf_BUILD_SHARED_LIBS=ON ` >> -Dprotobuf_BUILD_TESTS=ON ` >> -Dprotobuf_INSTALL=ON ` >> -Dprotobuf_INSTALL_EXAMPLES=ON ` >> -Dprotobuf_MSVC_STATIC_RUNTIME=ON ` >> -Dprotobuf_WITH_ZLIB=OFF ` >> -Dutf8_range_ENABLE_INSTALL=ON ` >> -L ` >> -- Selecting Windows SDK version 10.0.26100.0 to target Windows 10.0.19045. -- -- 28.0.0 -- Configuring done (0.5s) -- Generating done (1.1s) -- Build files have been written to: C:/code_dependencies/protobuf-28.0/cmake_build -- Cache values ABSL_BUILD_TESTING:BOOL=OFF ABSL_FIND_GOOGLETEST:BOOL=OFF ABSL_GOOGLETEST_DOWNLOAD_URL:STRING= ABSL_LOCAL_GOOGLETEST_DIR:PATH=/usr/src/googletest ABSL_PROPAGATE_CXX_STD:BOOL=ON ABSL_USE_GOOGLETEST_HEAD:BOOL=OFF ABSL_USE_SYSTEM_INCLUDES:BOOL=OFF BUILD_TESTING:BOOL=ON CMAKE_CONFIGURATION_TYPES:STRING=Debug;Release;MinSizeRel;RelWithDebInfo CMAKE_INSTALL_PREFIX:PATH=C:/code_dependencies/protobuf EXECINFO_LIBRARY:FILEPATH=EXECINFO_LIBRARY-NOTFOUND GTest_DIR:PATH=GTest_DIR-NOTFOUND LIBRT:FILEPATH=LIBRT-NOTFOUND protobuf_ABSL_PROVIDER:STRING=module protobuf_ALLOW_CCACHE:BOOL=OFF protobuf_BUILD_CONFORMANCE:BOOL=OFF protobuf_BUILD_EXAMPLES:BOOL=ON protobuf_BUILD_LIBPROTOC:BOOL=ON protobuf_BUILD_LIBUPB:BOOL=OFF protobuf_BUILD_PROTOBUF_BINARIES:BOOL=ON protobuf_BUILD_PROTOC_BINARIES:BOOL=ON protobuf_BUILD_SHARED_LIBS:BOOL=ON protobuf_BUILD_TESTS:BOOL=ON protobuf_DISABLE_RTTI:BOOL=OFF protobuf_INSTALL:BOOL=ON protobuf_INSTALL_EXAMPLES:BOOL=ON protobuf_JSONCPP_PROVIDER:STRING=module protobuf_REMOVE_INSTALLED_HEADERS:BOOL=OFF protobuf_TEST_XML_OUTDIR:BOOL=OFF protobuf_USE_EXTERNAL_GTEST:BOOL=OFF protobuf_USE_UNITY_BUILD:BOOL=OFF protobuf_WITH_ZLIB:BOOL=OFF utf8_range_ENABLE_INSTALL:BOOL=ON utf8_range_ENABLE_TESTS:BOOL=OFF
當然你也可以使用
cmake-gui
圖形化的方式(我個人覺得沒有命令列裝逼), 這裡簡單提一嘴先點選
Configure
, 然後選中你需要的元件, 最後點選Generate
.
0x03 開始編譯
cmake --build . --config Debug --target ALL_BUILD # 你可以選擇Release或者Debug
注意: 這裡似乎不能加
-j
指定編譯的執行緒數量, 會報檔案重複徵用的錯誤.這裡優先使用命令列, 如果你覺得不適應, 在cmake_build(也就是當前目錄), 有.sln專案檔案, 透過VS開啟它, 編譯ALL_BUILD解決方案.
經過一段時間的編譯, 將他安裝在你在前面指定的安裝路徑中 (CMAKE_INSTALL_PREFIX="C:\code_dependencies\protobuf")
cmake --install . --config Debug # 需要和上面的Release或者Debug相同,
cmake --install . # 這裡有坑, 在引用框中的不要輸入到命令列
預設是的config是Release, 如果你編譯的是Debug, 但是沒有指定
--config Debug
會出現問題(編譯後檔案找不到)CMake Error at third_party/abseil-cpp/absl/cmake_install.cmake:55 (file): file INSTALL cannot find "C:/code_dependencies/protobuf-28.0/cmake_build/bin/Release/abseil_dll.dll": File exists. Call Stack (most recent call first): third_party/abseil-cpp/cmake_install.cmake:85 (include) cmake_install.cmake:37 (include)
cmake --install . --config Debug
install過程PS C:\code_dependencies\protobuf-28.0\cmake_build> cmake --install . --config Debug -- Installing: C:/code_dependencies/protobuf/lib/cmake/absl/abslTargets.cmake -- Installing: C:/code_dependencies/protobuf/lib/cmake/absl/abslTargets-debug.cmake -- Installing: C:/code_dependencies/protobuf/lib/cmake/absl/abslConfig.cmake -- Installing: C:/code_dependencies/protobuf/lib/cmake/absl/abslConfigVersion.cmake -- Installing: C:/code_dependencies/protobuf/include/absl -- Installing: C:/code_dependencies/protobuf/include/absl/algorithm ............ ............ ............ -- Installing: C:/code_dependencies/protobuf/share/protobuf/examples/MODULE.bazel -- Installing: C:/code_dependencies/protobuf/share/protobuf/examples/pubspec.yaml -- Installing: C:/code_dependencies/protobuf/share/protobuf/examples/README.md -- Installing: C:/code_dependencies/protobuf/share/protobuf/examples/WORKSPACE -- Installing: C:/code_dependencies/protobuf/share/protobuf/examples/WORKSPACE.bzlmod -- Installing: C:/code_dependencies/protobuf/lib/gmock.lib