Я пытаюсь обратиться к громоздкой библиотеке C++ из OCaml, и у меня возникают проблемы с ocamlopt, который сразу выдает ошибку с кодом 2.
Я делаю весь танец с созданием интерфейса C, и я могу заставить его работать в целом, но как только я ссылаюсь на эту библиотеку, сборка прерывается.
Есть ли способ узнать, что именно не работает? Я попробовал флаг -verbose, но он просто печатает аргументы командной строки (которые довольно длинные).
Не могли бы вы дать какие-нибудь советы о том, как расследовать такой тихий сбой?
Это CentOS Linux. Выхода нет, поэтому я в недоумении, что делать.





TL;ДР; проверьте, достаточно ли у вас памяти и/или места на диске.
Нечто подобное может произойти, когда ocamlopt либо уничтожается сигналом, либо заканчивается память (или и то, и другое), проверьте вывод dmesg, найдите сообщения OOM от ядра, также используйте htop, чтобы получить представление об объеме памяти.
Кроме того, поскольку это происходит, когда вы пытаетесь скомпоновать библиотеку C++, скорее всего, это процесс ld, который дает сбой (опять же, скорее всего, с OOM), поскольку ocamlopt использует системный компоновщик.
Ах, dmesg ничего мне не сказал, но я попробовал strace ld и нашел это: write(2, "ld", 2ld) = 2 write(2, ": no input files\n", 17: no input files ) = 17
это была хорошая идея использовать strace! Итак, у нас есть три проблемы: 1) вы не видите вывод - это может быть ошибка в компиляторе, но, насколько мне известно, он использует system(2) для вызова системного компоновщика без каких-либо перенаправлений (strace dup может доказать мою неправоту ). Так что, скорее всего, ваша система сборки куда-то перенаправляет stderr. 2) компилятор недостаточно очищает ввод, что приводит к сбою компоновщика. 3) скорее всего, вы используете ocamlopt как-то неправильно (и уж точно не так, как ожидалось).
Решения для (1), если он действителен, отправьте вопрос на github.com/ocaml/ocaml. Для (2) отправьте запрос функции в том же месте. Для (3) отправьте вопрос в SO или просто обновите свой, чтобы мы могли выяснить, что не так с вашим вызовом. Во всяком случае, в противном случае нам нужно отправить еще одну проблему в систему отслеживания проблем OCaml.
Я думаю, что моя система сборки генерирует слишком длинную команду. Я пробовал помещать (экранировать) новые строки после каждого -ccopt (большинство из них -I с путем поиска каталога), и я определил точку, в которой количество аргументов слишком велико (в конце концов, моя маленькая программа не нужны все те заголовки, которые приходят из зависимостей). После того, как я пройду мимо ошибки компилятора, у меня все еще будет проблема с собственно компоновщиком (слишком много аргументов -cclib), поскольку компоновщику действительно нужны все зависимости. На данный момент я чувствую себя довольно обескураженным :(
Одна вещь, которую я хочу попробовать завтра, — передать gcc аргумент @file, чтобы посмотреть, сможет ли он таким образом обрабатывать аргументы. Я не смотрел, есть ли что-то подобное у ld.
Хорошо, я только что подтвердил, что ld также принимает параметр @file, так что это многообещающе.
На случай, если кто-то еще столкнется с этим снова: проблема заключалась в том, что драйвер сборки передавал слишком много аргументов -ccopt и -cclib. Когда я начал включать библиотеку C++ с множеством других зависимостей, казалось, что мы достигли критической точки.
Решение состояло в том, чтобы изменить правила компилятора и компоновщика OCaml драйвера сборки, чтобы записать все аргументы компилятора и компоновщика в файлы, чтобы их можно было передавать как один аргумент -ccopt @<compiler.args> или -cclib @<linker.args>. И gcc, и ld поддержка параметра командной строки @file.
Проблема с GitHub: ocamlopt позволяет компилятору/компоновщику молча выйти из строя, если передается слишком много аргументов -ccopt или -cclib.
Может помочь, если вы назовете используемую систему (Linux, MacOS, Windows) и включите несколько строк, показывающих ошибку, которую вы видите. Термин «код ошибки» не совсем ясен. Было бы крайне странно, если бы ocamlopt (да и вообще любая серьезная программа) вызывала
exit(2)без предварительного написания поясняющего сообщения. Возможно, сообщение об ошибке заканчивается где-то в стороне.