Я пытаюсь работать с 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
Вот несколько важных отрывков из ответа авторов по электронной почте:
"I'm guessing sf_count_t must be showing up as 32-bit and you want libsndfile to use 64-bit file offsets. I use nyquist/nylsf which is a local copy of libsndfile sources -- it's more work keeping them up to date (and so they probably aren't) but it's a lot easier to build and test when you have a consistent library."
"I use CMake and nyquist/CMakeLists.txt to build nyquist."
"It may be that one 32-bit machines, the default sf_count_t is 32 bits, but I don't think Nyquist supports this option."
А вот исходный код Найквиста: http://svn.code.sf.net/p/nyquist/code/trunk/nyquist/
Мне трудно решить эту проблему, потому что она представляет собой нишевый вариант использования относительно малоизвестного программного обеспечения. Это также вызывает беспокойство у службы поддержки. Я немного знаю C++, но далеко не уверен, что смогу решить эту проблему. Спасибо за чтение и всех счастливых праздников. Если у вас есть предложения, даже по форматированию или редактированию, не сомневайтесь!
Не могли бы вы уточнить, присутствует ли системный файл libsndfile (из gentoo / portage) и как именно вы пытаетесь собрать nyquist?
@Kamil Cuk, боюсь, я не совсем понимаю ваш запрос или информацию в ссылке. В этом файле в строке 19: github.com/svn2github/nyquist/blob/… "off_t определен как int, и при переходе к моей собственной программе, где я клонировал исходный код и скомпилирован, он кажется неизменным (хотя я не знаю, как получить его значение, если оно есть) Я знаю, что вы хотите знать, какое значение были присвоены этим переменным, и я пока собираюсь получить эту информацию. Я попытаюсь выполнить соответствующую перекомпиляцию в ближайшее время.
off_t не должен быть определен в исходниках nyquist или libsndfile, он является частью стандарта POSIX и определен в libc. Так что также может быть полезно узнать, используете ли вы glibc (по умолчанию gentoo) или, например, мусл или uclibc. Связанное определение off_t заменяет системы, не относящиеся к POSIX. off_t и sf_count_t, кстати, являются типы, а не функциями или переменными.
@ user10605163, да, этот файл и библиотека взяты из Gentoo / Portage. Я собирал Найквист из исходного кода, используя ccmake, в соответствии с инструкциями здесь: github.com/svn2github/nyquist/tree/…. Что касается вашего второго комментария, похоже, я использую libc, но также установил glibc. И спасибо за разъяснение моего неправильного использования слова функции, я отредактирую OP, чтобы отразить это.
@ steve-blobs Я добавил еще один вариант, основанный на README в nyquist/nylsf, который я упустил. Также обратите внимание, что glibc (библиотека GNU C) является одной из возможных реализаций библиотеки C (или libc). Иметь их обоих - это нормально.





Если вы посмотрите на источники для 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.
Насколько я понимаю, у вас есть следующие возможности:
Попросите автора nyquist предоставить ненастроенный sndfile.h.in и использовать autoconf для настройки этого файла во время сборки.
Не используйте прилагаемый libsndfile и связывайте его с системным. (Это требует определенных знаний и работы для изменения сценариев сборки и файлов заголовков, возможно, дополнительные неожиданные проблемы)
Если вы используете библиотеку 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.
На самом деле README в nyquist/nylsf объясняет, как были созданы файлы для него. Вы можете попытаться получить исходный код той же версии libsndfile, на которой он основан, и повторить шаги, указанные для создания nylsf, настроенного для вашей системы. Это может вызвать меньше проблем, чем 2. и 3., потому что не будет внесено никаких изменений версии / интерфейса.
Я обязательно свяжусь с автором, при всем уважении к user10605163, конечно, попросив вышеупомянутый файл и поделившись любым решением (он попросил меня следить, если проблема была решена). Решение №2 также кажется хорошим способом решить эту проблему и может привести к более переносимому решению, но это на другой день, если решение 3 будет работать. В любом случае, запускается "$ ccmake". в каталоге со только что клонированным репо и строкой add_compile_definitions добавленный конец файла привел к: "Неизвестная команда CMake" add_compile_definitions ", так что, возможно, синтаксис был немного неправильным?
В продолжение этого, я думаю, желаемый синтаксис - add_definitions, который можно увидеть здесь: cmake.org/cmake/help/v3.0/command/add_definitions.html. Он прошел ccmake вот так, но gcc завершился неудачно: «gcc: error: _FILE_OFFSET_BITS = 64: Нет такого файла или каталога». Теперь я вижу, что вы предоставили решение 4, которое кажется немного более элегантным, и я начну смотреть на него.
@ steve-blobs Синтаксис не последних версий cmake - add_definitions(-D_FILE_OFFSET_BITS=64), посмотрите ответы и отредактируйте принятый ответ в stackoverflow.com/questions/9017573/…. Я упустил из виду, насколько недавно было изменение.
Вы знаете, как мне найти версию 1.0.17 libsndfile (версия, указанная в README.txt)?
Понятно, спасибо за исправление синтаксиса. Я еще не придумал ни одного из решений 1-4, но как только я это сделаю и подтвердю, что они работают, я помечу его как принятый, большое спасибо очень за подробный и чрезвычайно полезный ответ. Я был шокирован, получив хоть какую-то помощь по этому поводу, не говоря уже о такой быстрой, подробной и достаточно многословной помощи.
@ steve-blobs Кажется, что в git-repo нет тега выпуска, и на веб-сайте автора, похоже, нет ссылки на более старые выпуски, но я думаю, что вы можете легко угадать правильное имя ссылки, если возьмете скачать ссылку на сайте автора и немного подогнать под версию. Также будут зеркала дистрибутивов Linux, у которых есть копия.
Решение №3 сработало, и я буду работать над более портативным и элегантным решением, подобным другим, которые вы описали. Большое спасибо!!
Можете ли вы опубликовать, что означает
off_tна вашей машине? Какsf_count_tопределяется на вашем компьютере? (просто включите соответствующие заголовки и используйте такой трюк, чтобы проверить это). Что произойдет, если вы удалите чек из psf_open_fd и перекомпилируете? Что, если вы простоtypedef off_t sf_count_t;и перекомпилируете? libsndfile имеет другой чек.