protobuf cmake Visual Studio 編譯安裝 (全命令列)

QU头發表於2024-09-12

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

相關文章