Как тип sf_count_t в sndfile.h определен в libsndfile?

Я пытаюсь работать с Nyquist (платформа для музыкального программирования, см.: https://www.cs.cmu.edu/~music/nyquist/ или https://www.audacityteam.org/about/nyquist/) как автономная программа и использует libsndfile (библиотека для чтения и записи звука, см.: http://www.mega-nerd.com/libsndfile/). Я делаю это на машине i686 GNU/Linux (Gentoo).

После успешной установки и запуска программы без ошибок я попытался сгенерировать звук с помощью одного из примеров, "(play (osc 60))", и встретил эту ошибку:

*** Fatal error : sizeof (off_t) != sizeof (sf_count_t)
*** This means that libsndfile was not configured correctly.

Дальнейшее изучение этого вопроса (и по электронной почте автору) оказалось несколько полезным, но решение все еще далеко от моего понимания. Автор рекомендовал посмотреть /usr/include/sndfile.h, чтобы увидеть, как определяется sf_count_t, и (эта часть) моего файла идентична его:

/* The following typedef is system specific and is defined when libsndfile is
** compiled. sf_count_t will be a 64 bit value when the underlying OS allows
** 64 bit file offsets.
** On windows, we need to allow the same header file to be compiler by both GCC
** and the Microsoft compiler.
*/

#if (defined (_MSCVER) || defined (_MSC_VER))
typedef __int64         sf_count_t ;
#define SF_COUNT_MAX          0x7fffffffffffffffi64
#else
typedef int64_t sf_count_t ;
#define SF_COUNT_MAX            0x7FFFFFFFFFFFFFFFLL
#endif

Выше автор отмечает, что нет опции для "32-битного смещения". Я не уверен, как бы я поступил. Вот конкретный файл, который автор Nyquist рекомендует мне изучить: https://github.com/erikd/libsndfile/blob/master/src/sndfile.h.in, а вот и все дерево исходных текстов: https://github.com/erikd/libsndfile

Вот некоторые соответствующие фрагменты ответа автора по электронной почте:

"Я предполагаю, что sf_count_t должен отображаться как 32-битный, и вы хотите, чтобы libsndfile использовал 64-битные смещения файлов. Я использую nyquist/nylsf, который является локальной копией источников libsndfile - это больше работы, поддерживая их в актуальном состоянии (и, вероятно, это не так) но гораздо проще создать и протестировать, когда у вас есть согласованная библиотека ".

"Я использую CMake и nyquist/CMakeLists.txt для создания nyquist".

"Возможно, на одной 32-битной машине значение sf_count_t по умолчанию составляет 32 бита, но я не думаю, что Nyquist поддерживает эту опцию".

А вот и исходный код Nyquist: http://svn.code.sf.net/p/nyquist/code/trunk/nyquist/

Эту проблему мне трудно решить, потому что она состоит из ниши использования относительно неясного программного обеспечения. Это также делает перспективы поддержки этой проблемы немного тревожными. Я немного знаю C++, но далеко не уверен в своей способности решить эту проблему. Спасибо за чтение и счастливых праздников всем. Если у вас есть какие-либо предложения, даже с точки зрения форматирования или редактирования, пожалуйста, не стесняйтесь!

1 ответ

Решение

Если вы посмотрите на источники в комплекте libsndfile в nyquistт.е. nylsfтогда вы видите, что sndfile.h предоставляется напрямую. Определяет sf_count_t как 64-разрядное целое число.

libsndfile Источники, однако, не имеют этот файл, скорее они имеют sndfile.h.in, Это входной файл для autoconf, который является инструментом, который будет генерировать правильный файл заголовка из этого шаблона. В настоящее время оно имеет следующее определение sf_count_t для систем Linux (и имел это с тех пор):

typedef @TYPEOF_SF_COUNT_T@ sf_count_t ;

@TYPEOF_SF_COUNT_T@ будет заменен autoconf создать заголовок с рабочим типом для sf_count_t для системы, которая будет построена для. Заголовочный файл предоставлен nyquist поэтому уже настроен (предположительно для системы автора).

off_t это тип, определенный стандартом POSIX и определенный в libc системы. Его размер в системе, использующей библиотеку GNU C, составляет 32 бита, если система 32-битная.

Это приводит к сбою проверки работоспособности, потому что размеры sf_count_t а также off_t не совпадают Сообщение об ошибке также является правильным, так как мы используем неправильно настроенный sndfile.h для сборки.

На мой взгляд, у вас есть следующие варианты:

  1. Спроси nyquist автору предоставить ненастроенный sndfile.h.in и использовать autoconf настроить этот файл во время сборки.

  2. Не используйте в комплекте libsndfile и ссылка против системы. (Это требует определенных знаний и работы для изменения скриптов сборки и заголовочных файлов, возможно, дополнительных неожиданных проблем)

  3. Если вы используете библиотеку GNU C (glibc): макрос препроцессора _FILE_OFFSET_BITS можно установить на 64 заставить размер off_t и остальная часть файлового интерфейса для использования 64-битных версий даже на 32-битных системах.

    Это может работать, а может и не работать, в зависимости от того, поддерживает ли ваша система это, и это не чистое решение, так как может быть дополнительная неверная конфигурация libsndfile происходит незамеченным Этот флаг может также вводить другие изменения интерфейса, на которые опирается код, вызывая дальнейшие ошибки / уязвимости при сборке или во время выполнения.

    Тем не менее, я думаю, что синтаксис для cmake должен был бы добавить:

    add_compile_definitions(_FILE_OFFSET_BITS=64)
    

    или в зависимости от версии cmake:

    add_definitions(-D_FILE_OFFSET_BITS=64)
    

    в соответствующем CMakeLists.txt,

  4. На самом деле README вnyquist/nylsf объясняет, как были созданы файлы для него. Вы можете попытаться получить исходный код того же libsndfile версия, на которой он основан, и повторите шаги, приведенные для создания nylsf настроен в вашей системе. Это может вызвать меньше проблем, чем 2. и 3., потому что не будет никаких изменений в версии / интерфейсе.

Другие вопросы по тегам