# Protobuf 3.14.0 和 CMake 的一些小細節

最近在試著用 CMake 去編一個的 Protobuf 3.14.0 的專案，在準備的過程遇到一些問題。

# 甚麼問題

一開始我是直接拿一個 [repository](https://github.com/shaochuan/cmake-protobuf-example) 來改，對他追加版本 (當然，環境也有裝 protobuf 3.14.0 ， CMAKE\_PREFIX 等路徑環境變數也有設置好) ，確保 Cmake 連結的是 3.14.0 的版本後：

FIND\_PACKAGE(Protobuf 3.14.0 REQUIRED)

便編譯成功了。

但是在執行時，卻直接跳出 Exception：

```
[libprotobuf FATAL google/protobuf/generated_message_util.cc:785] CHECK failed: (scc->visit_status.load(std::memory_order_relaxed)) == (SCCInfoBase::kRunning): terminate called after throwing an instance of ‘google::protobuf::FatalException’  
    what(): CHECK failed: (scc->visit_status.load(std::memory_order_relaxed)) == (SCCInfoBase::kRunning):   
Aborted
```

# 處理方式

根據一些 Google 和檢查 Cmake 的一些生成的檔案，這是因為沒有 link pthread 造成的。並且，追加

```cmake
set(THREADS_PREFER_PTHREAD_FLAG ON)  
find_package(Threads REQUIRED)  
target_link_libraries(main Threads::Threads)
```

確實也可以解決問題，讓程式正常執行。

可是，這樣似乎又有點詭異，**理論上來說 FindProtobuf 應該要負責也把連結 pthread 這個機制處理好，而不是交由使用者去另外連結 pthread。**

最後，我找到這個 [Issue](https://github.com/shaochuan/cmake-protobuf-example/issues/2)，把這行

TARGET\_LINK\_LIBRARIES(main proto ${PROTOBUF\_LIBRARY})

把它改成

TARGET\_LINK\_LIBRARIES(main proto ${PROTOBUF\_LIBRARIES})

就好了。

在[官方文件](https://cmake.org/cmake/help/v3.0/module/FindProtobuf.html)上，其實對這兩個變數也只有模糊(幾乎沒有)的說明：

*   PROTOBUF\_LIBRARIES — The protobuf libraries
*   PROTOBUF\_LIBRARY — The protobuf library

或許就只是因為 library 是單數，所以是只有 protobuf 本身，而 libraries 是完整的把 protobuf 和他所需要的其他東西引入。

### 參考資料

*   github repository: [cmake-protobuf-example](https://github.com/shaochuan/cmake-protobuf-example)
*   stackoverflow: [FatalException thrown by protobuf library on instantiation of message](https://stackoverflow.com/questions/52890529/fatalexception-thrown-by-protobuf-library-on-instantiation-of-message)
*   stackoverflow: [cmake and libpthread](https://stackoverflow.com/questions/1620918/cmake-and-libpthread)
*   github issue: [libprotobuf fatal error when running output file](https://github.com/shaochuan/cmake-protobuf-example/issues/2)
*   cmake document: [FindProtobuf](https://cmake.org/cmake/help/v3.0/module/FindProtobuf.html)
