Ошибка компиляции базы данных c ++ в Windows с помощью cmake - PullRequest
0 голосов
/ 21 октября 2019

Для получения степени магистра мне нужно работать с базой данных, называемой duckdb (на git hub). Обычно в Linux вы можете просто его клонировать и «сделать» для установки.

Мне надоело то же самое на windows после установки CMake и Cygwin.

Но в середине компиляции я получаю ошибку

'DUCKDB ~ 2 / duckdb / THIRD_ ~ 1 / catch / catch.hpp: 1445: 96:
Ошибка: ISOC ++ запрещает сравнение между указателем и целым числом [-fpermissive]

 auto compareNotEqual( LhsT const& lhs, RhsT&& rhs ) -> bool { return static_cast<bool>(lhs != rhs); }'

Поскольку я сомневаюсь, что создатели duckdb все испортили, я думаю, что есть ошибка компилятора, пытающаяся скомпилировать файл C какФайл C ++, возможно.

Моя главная проблема: как мне настроить команду make на окнах, чтобы она не выдавала эту ошибку?

Я пробовал ее как на компьютерах с Windows 7, так и на 10 с gcc 5.1 и текущейУстановлен cmake, и оба выдают эту ошибку.

Редактировать: полный текст ошибки

[87%] Сборка объекта CXX test / sql / capi / CMakeFiles / test_sql_capi.dir / ub_test_sql_capi.cpp.obj В файле включеноиз C: /duckdb/test/sql/capi/test_capi.cpp: 1: 0, из test_capi.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 :: BinaryExprCatch :: ExprLhs :: operator! = (Const> RhsT &) [с 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.hpp: 1445: 96: ошибка: ISO C ++ запрещает сравнение> между указателем и целым числом [-fpermissive] auto compareNotEqual (LhsT const & lhs, RhsT && rhs) -> bool {return> static_cast (lhs! = Rhs);}

Я только отредактировал свое имя пользователя в пути и т. Д.

Ответы [ 2 ]

2 голосов
/ 21 октября 2019

Я не знаю библиотеку, поэтому не могу дать однозначного ответа. Я буду идти по коду в https://github.com/cwida/duckdb.

В соответствии с сообщением об ошибке в проблемном коде в строке 332 из test/sql/capi/test_capi.cpp, что:

REQUIRE(stmt != NULL);

REQUIREявляется макросом из библиотеки модульного тестирования Catch2, который выполняет некоторые действия, чтобы разобрать данное ему выражение. Важная часть заключается в том, что stmt != NULL на самом деле будет выполняться не сразу, а только через косвенное обращение к функции.

stmt объявлено в строке 324 как

duckdb_prepared_statement stmt = nullptr;

и duckdb_prepared_statementявляется typedef в строке 94 из src/include/duckdb.h:

typedef void *duckdb_prepared_statement;

Следовательно, задача проблемной строки - проверить, является ли stmt по-прежнему nullptr после некоторых промежуточных операций.

Обычно stmt != NULL было бы хорошо для этого. Однако поскольку макрос Catch2 вводит промежуточные вызовы функций, а не оценивает это выражение напрямую, неявные преобразования, характерные для литерала, не применяются.

В частности, NULL в соответствии со стандартом является либо prvalue типа std::nullptr_t или целочисленный литерал со значением 0. Какой именно из них (и какой целочисленный тип) определяется реализацией.

Сравнение целых чисел и указателей обычно запрещено, однако целочисленные литералы со значением ноль имеют специальное исключение, позволяющееони должны быть неявно преобразованы в нулевой указатель любого типа указателя. Это то, что произойдет, если stmt != NULL будет оцениваться напрямую.

Однако из-за прерывания Catch2 NULL сначала передается, а затем сравнивается через переменную с stmt, что делает специальныйнулевое буквальное правило больше не применяется. Поэтому сравнение stmt с NULL через REQUIRE не удастся, если NULL является целочисленным литералом в текущей реализации.

Catch2 действительно учитывает эту проблему и существуют перегрузки для compareNotEqual вthird_party/catch/catch.hpp, который учитывает случай, когда NULL является целочисленным литералом нулевого типа типа int или long, но по какой-то причине случай long long не рассматривается. Я не знаю, является ли это проблемой с Catch2 или это только в клонированной версии, включенной в duckdb.

Итак, если реализация использует нулевой литерал типа long long для NULL,тогда произойдет ошибка, которую вы наблюдали.

Действительно, duckdb должен использовать nullptr вместо NULL (как это происходит при инициализации), что не имеет этих проблем и было добавлено в язык из-за того, чтоэти проблемы.

Полагаю, вы можете просто попытаться решить эту проблему, заменив NULL на nullptr (возможно, и в других тестовых случаях).

Однако проблемный код тольков файлах, которые сами являются модульными тестами для фактического кода библиотеки. Так что должна быть какая-то опция cmake или make, которая отключит сборку модульных тестов, чтобы вы могли игнорировать эту конкретную ошибку, надеясь, что она не встречается нигде в реальном коде библиотеки.

ЕслиЯ был прав в своих оценках, возможно, вы захотите подать отчет об ошибке с помощью duckdb, предполагая, что они в первую очередь поддерживают вашу платформу.

1 голос
/ 30 октября 2019

Вместо использования Cygwin для компиляции проекта может быть проще использовать CMake в сочетании с Visual Studio. Именно так авторы сами компилируют и тестируют DuckDB в Windows.

Используя CMake, генерируйте набор файлов проекта Visual Studio. Затем откройте эти файлы проекта в Visual Studio (мы используем сообщество Visual Studio 2019), скомпилируйте и запустите набор тестов (unittest). Отдельные тесты можно запустить, добавив имя теста в качестве параметра командной строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...