[英]Compiling C++ with Boost 1.68.0 on Windows using CMake and MinGW
[英]Error compiling a c++ database on windows with cmake
對於我的碩士學位,我需要在一個名為 Dukedb 的數據庫上工作(它在 git 集線器上)。 通常在 Linux 上,您可以簡單地克隆它並“制作”它來安裝。
在安裝 CMake 和 Cygwin 之后,我在 windows 上也感到厭煩。
但是在編譯過程中我得到了錯誤
'DUCKDB~2/duckdb/THIRD_~1/catch/catch.hpp:1445:96:
錯誤:ISO C++ 禁止指針和 integer [-fpermissive] 之間的比較auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs;= rhs); }'
由於我懷疑duckdb的創建者確實搞砸了,我認為嘗試將C文件編譯為C++文件可能存在編譯器錯誤。
我的主要問題是:如何在 windows 上配置 make 命令以阻止它產生此錯誤?
我在安裝了 gcc 5.1 和當前 cmake 的 windows 7 和 10 系統上都進行了嘗試,並且都產生了這個錯誤。
編輯:這是完整的錯誤文本
[ 87%] 構建 CXX object 測試/sql/capi/CMakeFiles/test_sql_capi.dir/ub_test_sql_capi.cpp.obj 包含在 C:/duckdb/test/sql/capi/test_capi.c 的文件中。 cpp:0:
C:/DUCKDB~2/duckdb/THIRD_~1/catch/catch.hpp: 在 'bool >Catch::compareNotEqual(const LhsT&, RhsT&&) [with LhsT = void*; RhsT = const >long long int&]':
C:/DB/DUCKDB~2/duckdb/THIRD_~1/catch/catch.hpp:1471:37: 需要來自 'const >Catch::BinaryExpr Catch::ExprLhs::operator;=(const >RhsT&) [with RhsT = long long int; LhsT = void* const&]'
C:/DB/duckdb/test/sql/capi/test_capi.cpp:332:2: 從這里需要 C:/DB/DUCKDB~2/duckdb/THIRD_~1/catch/catch.hpp1: : ISO C++ 禁止比較 > 指針和 integer [-fpermissive] auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return >static_cast(lhs;= r }
我只在路徑等中編輯了我的用戶名。
我不知道圖書館,所以我不能給出肯定的答案。 我將使用https://github.com/cwida/duckdb的代碼。
根據問題代碼中的錯誤信息在test/sql/capi/test_capi.cpp
的第 332 行,即:
REQUIRE(stmt != NULL);
REQUIRE
是單元測試庫 Catch2 中的一個宏,它在解析給它的表達式時做了一些魔術。 重要的部分是stmt != NULL
實際上不會立即執行,而只能通過 function 間接執行。
stmt
在第 324 行聲明為
duckdb_prepared_statement stmt = nullptr;
並且duckdb_prepared_statement
是src/include/duckdb.h
第 94 行中的 typedef:
typedef void *duckdb_prepared_statement;
因此,有問題的行的目的是檢查stmt
在經過一些中間操作后是否仍然是nullptr
。
通常stmt != NULL
就可以了。 但是,由於 Catch2 宏引入了中間 function 調用而不是直接評估此表達式,因此不應用特定於文字的隱式轉換。
特別是NULL
根據標准是std::nullptr_t
類型的純右值或值為 0 的 integer 文字。其中哪一個(以及哪個 Z157DB7ZDF530023577515D366E8Z)是實現定義的。
通常禁止比較整數和指針,但是值為零的 integer 文字有一個特殊例外,允許它們隱式轉換為任何指針類型的 null 指針。 如果stmt != NULL
將被直接評估,就會發生這種情況。
然而,由於 Catch2 的插入, NULL
首先被傳遞,然后通過變量與stmt
進行比較,這使得特殊的零文字規則不再適用。 因此,如果NULL
在當前實現中是 integer 文字,則通過REQUIRE
將stmt
與NULL
進行比較將失敗。
Catch2 確實考慮了這個問題,並且在third_party/catch/catch.hpp
中存在compareNotEqual
的重載,它處理了NULL
為零 integer 文字的int
或long
類型的情況,但由於某種原因,不考慮long long
的情況. 不知道這是否是 Catch2 的問題,還是僅存在於duckdb 中包含的克隆版本中。
因此,如果實現對NULL
使用long long
類型的零字面量,那么您觀察到的錯誤將會發生。
真正的duckdb應該使用nullptr
而不是NULL
(就像它在初始化中所做的那樣),它沒有這些問題,正是因為這些問題才被添加到語言中。
我想你可以簡單地嘗試通過用nullptr
替換NULL
來解決這個問題(也許在其他測試用例中也是如此)。
但是,有問題的代碼僅存在於文件中,這些文件本身就是實際庫代碼的單元測試。 因此,cmake 應該有一些選項,或者使該選項將禁用構建單元測試,以便您可以忽略此特定錯誤,希望它不會出現在實際庫代碼中的任何地方。
如果我的評估是正確的,那么您可能需要考慮使用duckdb 提交一個錯誤報告,假設他們首先支持您的平台。
與使用 Cygwin 相比,使用 CMake 結合 Visual Studio 編譯項目可能更容易。 這是作者自己在 Windows 上編譯和測試 DuckDB 的方式。
使用 CMake,生成一組 Visual Studio 項目文件。 然后在 Visual Studio 中打開這些項目文件(我們使用 Visual Studio Community 2019),編譯並運行測試套件(unittest)。 可以通過將測試名稱添加為命令行參數來運行單個測試。
DuckDB 目前似乎沒有發布版本。 所以不要以為創作者沒有留下任何錯誤......
您可以添加編譯器標志-fpermissive
以忽略錯誤(例如make CXX="g++ -fpermissive"
)。
但是忽略這樣的錯誤並不總是安全的。
所以我試圖解決這個問題,我能夠在 Windows 上構建一個版本。 有關我的解決方案,請參閱https://github.com/cwida/duckdb/issues/361 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.