#включают требует #include прежде чем сделать сборку удачной - PullRequest
1 голос
/ 21 апреля 2020

Мне нужно использовать библиотеку avifile (https://packages.debian.org/stretch/libavifile-0.7-dev) в C ++.

В качестве минимального воспроизводимого примера у меня есть следующий файл main.cpp:

#include <avifile.h>

int main(void) {
    return 0;
}

Я пытаюсь создать файл main.cpp внутри контейнера Docker (для воспроизводимых сборок ), используя этот Dockerfile для установки только необходимых зависимостей:

FROM    debian:stretch

RUN     apt update \
 &&     apt install -y \
            g++ \
            libavifile-0.7-dev

Когда я создаю внутри контейнера:

g++ -o main.o main.cpp `avifile-config --libs` `avifile-config --cflags` 

, что разрешает следующую команду:

g++ -o main.o main.cpp -L/usr/lib/x86_64-linux-gnu -laviplay -I/usr/include/avifile-0.7

Сборка выдает много ошибок, например:

In file included from /usr/include/avifile-0.7/avm_stl.h:8:0,
                 from /usr/include/avifile-0.7/avifile.h:4,
                 from main.cpp:1:
/usr/include/avifile-0.7/avm_stl.h: In member function 'void avm::vector<Type>::erase(avm::vector<Type>::iterator)':
/usr/include/avifile-0.7/avm_stl.h:333:12: error: 'm_size' was not declared in this scope
     assert(m_size > 0);
            ^
In file included from main.cpp:1:0:
/usr/include/avifile-0.7/avifile.h: At global scope:
/usr/include/avifile-0.7/avifile.h:96:13: error: 'size_t' does not name a type
     virtual size_t GetHeader(void* pheader = 0, size_t size = 0) const =0;
             ^~~~~~
/usr/include/avifile-0.7/avifile.h:104:13: error: 'size_t' does not name a type
     virtual size_t GetAudioFormat(void* format = 0, size_t size = 0) const =0;
             ^~~~~~

Импорт #include <avifile.h> отвечает за ошибки. Ошибки связаны с заголовками avifile, поэтому я не могу их изменить. Похоже, что сборка не может найти некоторые базовые c вещи, такие как m_size и size_t. Если я добавлю #include <stdlib.h> до:

#include <stdlib.h>
#include <avifile.h>

int main(void) {
    return 0;
}

Затем он будет работать нормально.

Зачем мне включать stdlib.h вместе с avifile.h здесь? Я не очень знаком с C ++, но понимаю, что m_size, size_t, ... (все, что требуется для avifile) определено в stdlib.h, хотя.

Ответы [ 2 ]

2 голосов
/ 21 апреля 2020

Проблема, как вы уже поняли, состоит в том, что в avifile.h есть код, который использует переменные или члены класса, объявленные с типом size_t, который не встроенный тип данных, но определенный пользователем typedef, объявленный в одном из стандартных системных заголовков. Заголовок stdlib.h (хотя лучше использовать <cstdlib> в коде C ++) будет автоматически включать этот заголовок, если потребуется, как и другие системные заголовки, такие как <iostream> и <cstddef>.

Как правило, сторонние заголовки, такие как avifile.h, должны сами проверять наличие необходимых заголовочных зависимостей и явно #include их при необходимости. Однако, похоже, что в вашем случае этот заголовок не делает этого.

Итак, на данный момент вам следует убедиться, что вы всегда #include один из системных заголовков перед строкой #include <avifile.h>. В вашей ситуации я бы также связался с поставщиками этой библиотеки, чтобы сообщить им о проблеме, которая (ИМХО) должна рассматриваться как ошибка .

Кстати , m_size, о котором вы говорите, не стандартного типа, но, скорее всего, будет переменной-членом одного из классов, объявленных как size_t переменная.

2 голосов
/ 21 апреля 2020

Зачем мне включать stdlib.h вместе с avifile.h здесь?

Вы ответили себе чуть позже:

Я понимаю, что m_size, size_t, ... (все необходимые для avifile) определены в stdlib.h, хотя.

В частности, size_t определяется как stdlib.h, m_size - просто плохая переменная в вашем заголовке, определенная как тип size_t, и так как компилятор не может выяснить, что это за тип это, он не считает это определенным для целей дальнейшей проверки ошибок.

...