perl6 NativeCall не находит библиотеку на Дарвине

Я немного поиграю с NativeCall, чтобы познакомиться с этой стороной Perl6. Конечно, я сначала пытаюсь загрузить libstatgrab (что еще?).

Итак, я начну с самого простого - информации о хосте. Поскольку пока нет поддержки кластеров, это всего лишь один результат - никаких сложностей.

Код:

#!/usr/bin/env perl6 

use v6;
use NativeCall;

enum sg_error (
        SG_ERROR_NONE                   => 0,
        SG_ERROR_INVALID_ARGUMENT       => 1,
        ...
);

class sg_error_details is repr('CStruct') {
        has int32 $.error;
        has int32 $.errno_value;
        has Str $.error_arg;
};

sub sg_init(int32 $ignore_errors) returns int32 is native('statgrab') { * };

enum sg_host_state (
        sg_unknown_configuration        => 0,
        sg_physical_host                => 1,
        sg_virtual_machine              => 2,
        sg_paravirtual_machine          => 3,
        sg_hardware_virtualized         => 4
);

class sg_host_info is repr('CStruct') {
        has Str $.os_name;
        has Str $.os_release;
        has Str $.os_version;
        has Str $.platform;
        has Str $.hostname;
        has uint32 $.bitwidth;
        has int32 $.host_state;
        has uint32 $.ncpus;
        has uint32 $.maxcpus;
        has uint64 $.uptime;
        has uint64 $.systime;
};

sub sg_get_host_info(size_t is rw) returns Pointer is native('statgrab') is symbol('sg_get_host_info_r') { * };
sub sg_free_host_info(Pointer) is native('statgrab') is symbol('sg_free_stats_buf') { * };

sub MAIN() {
    my int32 $ignore_errors = 0;
    my $error = sg_init($ignore_errors);
    if $error != SG_ERROR_NONE {
        say "Maeh: $error";
        exit 1;
    }

    my size_t $num_host_infos = 0;
    my $res = sg_get_host_info($num_host_infos);
    if $num_host_infos > 0 {
        my $host_info = nativecast(sg_host_info, $res);
        with $host_info {
            say "You're using ", $_.os_name, " on ", $_.hostname;
        }
    }
    sg_free_host_info($res);
}

Его запуск (тупой) приводит к ошибке загрузки библиотеки:

$ perl6 statgrab.p6
Cannot locate native library 'libstatgrab.dylib': dlopen(libstatgrab.dylib, 1): image not found
  in method setup at /Users/sno/rakudo/share/perl6/sources/24DD121B5B4774C04A7084827BFAD92199756E03 (NativeCall) line 283
  in method CALL-ME at /Users/sno/rakudo/share/perl6/sources/24DD121B5B4774C04A7084827BFAD92199756E03 (NativeCall) line 570
  in sub MAIN at statgrab.p6 line 95
  in block <unit> at statgrab.p6 line 93

Хорошо - зададим ему путь поиска:

$ LD_LIBRARY_PATH=/opt/pkg/lib:$LD_LIBRARY_PATH perl6 statgrab.p6
Cannot locate native library 'libstatgrab.dylib': dlopen(libstatgrab.dylib, 1): image not found

Такая же картина при использовании DYLD_LIBRARY_PATH - который также поддерживается dlopen (3) на Дарвине.

Но изменение в каталоге работает:

$ (cd /opt/pkg/lib && perl6 /data/Projects/OSS/p6-Unix-Statgrab/statgrab.p6 )
You're using Darwin on ernie.[...]

Есть ли отсутствие сквозного пути поиска в способе вызова moarvm?


person Sno    schedule 20.02.2019    source источник
comment
Я использую Linux, поэтому не уверен, что могу здесь помочь, но каково содержимое каталога /opt/pkg/lib на Mac? Файл libstatgrab.dylib присутствует?   -  person Håkon Hægland    schedule 20.02.2019
comment
Я попытался запустить ваш сценарий на своем ноутбуке с Ubuntu 18.10 и получил загадочное сообщение об ошибке: ===SORRY!=== Stub code executed ..   -  person Håkon Hægland    schedule 20.02.2019
comment
Хорошо, ваш сценарий отлично работает в Ubuntu после удаления строки с ... из enum. Результат, который я получаю от запуска скрипта: You're using Linux on hakon-Precision-7530   -  person Håkon Hægland    schedule 20.02.2019
comment
Чтобы ответить на ваш первый вопрос: Да. Пожалуйста, посмотрите последний фрагмент кода, используя команду смены каталога. И да - я сократил код, так как переполнение стека обвинило меня в том, что в моем вопросе слишком много кода;) Наконец, вы говорите: работает в Linux, так что, вероятно, это проблема только Дарвина?   -  person Sno    schedule 21.02.2019
comment
Извините, что у меня нет доступа к машине OSX, но это может быть проблема только Дарвина. Не могли бы вы указать абсолютный путь к библиотеке: ... is native('/opt/pkg/lib/libstatgrab.dylib') ...?   -  person Håkon Hægland    schedule 21.02.2019
comment
Я только что установил libstatgrab 0.91 на Mojave по умолчанию: ./configure && make && make install, а затем следующий код работает нормально perl6 -e 'use NativeCall; sub sg_init(int32 $ignore_errors) returns int32 is native("statgrab") { * }; sg_init(1)'. Поэтому я не могу воспроизвести это на MacOS 10.14.3. Кроме того, приведенный выше сценарий (без ...) работает должным образом, afaics.   -  person Elizabeth Mattijsen    schedule 21.02.2019
comment
@ElizabethMattijsen - куда устанавливается ./configure по умолчанию? Я ожидаю / usr / local / lib, верно?   -  person Sno    schedule 21.02.2019
comment
Он был установлен в /usr/local/lib.   -  person Elizabeth Mattijsen    schedule 21.02.2019
comment
@ElizabethMattijsen, пожалуйста, попробуйте с ./configure --prefix = / opt (libstatgrab   -  person Sno    schedule 21.02.2019
comment
Я не знаю Дарвина или многих других системных вещей в целом, но, кстати, это не P6 / MoarVM. Актуальны ли эти SO? ​​Ошибка: библиотека dlopen () не загружена Причина: изображение не найдено < / а>? Альтернатива трюку DYLD_LIBRARY_PATH, начиная с Mac OS 10.11 El Capitan с защитой целостности системы? Кроме того, LD_DEBUG=all полезно?   -  person raiph    schedule 23.02.2019
comment
Привет, раиф, в тот момент у меня не было возможности заглянуть глубже. Я обсуждал это с Лиз на нашем собрании местных продавцов перла. Она обнаружила и исправила опечатку;) Неважно, показывают ли связанные ресурсы, как низкоуровневая программа должна загружать разделяемую библиотеку; ожидания пользователей для языка высокого уровня состоят в том, что он решает эти проблемы. Честно говоря, я думаю, что есть две проблемы - и в соответствующих ресурсах указывается на те, которых я не осознавал.   -  person Sno    schedule 25.02.2019
comment
Что бы ни думали по поводу. XS, он решает проблему PATH, предоставляя путь поиска связанной библиотеки через RPATH, обслуживающий инфраструктуру может изменить его для платформ, для которых скомпилирован модуль. Perl 6 решил использовать интерфейс только высокого уровня и должен решить эту проблему (возможно, он имеет такую ​​же критичность, как и CVE-2016-1238) Вторая проблема заключается в том, что разработчика модуля не следует заставлять искать общую библиотеку до загрузки модуля API. Это вызовет ляпы, так как время компиляции и время выполнения ...   -  person Sno    schedule 25.02.2019
comment
Для записей: $ otool -L /opt/pkg/lib/libstatgrab.dylib /opt/pkg/lib/libstatgrab.dylib: /opt/pkg/lib/libstatgrab.10.dylib (версия совместимости 11.0.0, текущая версия 11.0.0) /System/Library/Frameworks/IOKit.framework/Versions/A/IOKit (версия совместимости 1.0.0, текущая версия 275.0.0) /System/Library/Frameworks/CoreFoundation.framework/Versions/A/CoreFoundation ( версия совместимости 150.0.0, текущая версия 1560.12.0) /usr/lib/libSystem.B.dylib (версия совместимости 1.0.0, текущая версия 1252.200.5)   -  person Sno    schedule 25.02.2019
comment
Обнаруживаются ваши подсказки, чтобы копнуть немного дальше: env DYLD_LIBRARY_PATH = / opt / pkg / lib LD_DEBUG = all / Users / sno / rakudo / bin / moar --execname = perl6 --libpath = / Users / sno / rakudo / share / nqp / lib --libpath = / Users / sno / rakudo / share / nqp / lib --libpath = / Users / sno / rakudo / share / perl6 / lib --libpath = / Users / sno / rakudo / share / perl6 / runtime /Users/sno/rakudo/share/perl6/runtime/perl6.moarvm $ @ statgrab.p6 работает должным образом. Итак, создание perl6 в качестве сценария оболочки вместо очень маленького двоичного файла или просто мягкой ссылки или чего-то еще, что вызывает проблему.   -  person Sno    schedule 25.02.2019
comment
@Sno perl6, вероятно, переключится на использование небольшого двоичного файла вместо текущих сценариев оболочки после следующего выпуска.   -  person Patrick Böker    schedule 26.02.2019


Ответы (1)


doug$ perl6 -v
This is Rakudo Star version 2018.10 built on MoarVM version 2018.10
implementing Perl 6.c.

На довольно недавнем Rakudo Star на MacOS High Sierra скрипт у меня работал "из коробки":

  1. отредактировал скрипт, чтобы удалить '...'.
  2. Скрипту не удалось загрузить библиотеку (действительно отсутствует!)
  3. brew install libstatgrab
  4. Скрипт успешно выполнен:
vader:learning doug$ perl6 nativecall_mac_Sno.pl6 
You're using Darwin on Vader.local

Homebrew установил библиотеку следующим образом:

$ v /usr/local/lib
total 11904
-rw-r--r--  1 doug  admin  6080828 Sep 23 12:40 libmoar.dylib
lrwxr-xr-x  1 doug  admin       51 Mar 23 11:02 libstatgrab.10.dylib@ -> ../Cellar/libstatgrab/0.91/lib/libstatgrab.10.dylib
lrwxr-xr-x  1 doug  admin       44 Mar 23 11:02 libstatgrab.a@ -> ../Cellar/libstatgrab/0.91/lib/libstatgrab.a
lrwxr-xr-x  1 doug  admin       48 Mar 23 11:02 libstatgrab.dylib@ -> ../Cellar/libstatgrab/0.91/lib/libstatgrab.dylib
drwxr-xr-x  3 doug  admin      102 Mar 23 11:02 pkgconfig/

Для меня исполняемый файл perl6 действительно является сценарием оболочки, но он работал (не было необходимости передавать какие-либо дополнительные LD_LIBRARY_PATH=...).

doug$ file `which perl6`
/Applications/Rakudo/bin/perl6: POSIX shell script text executable, ASCII text, with very long lines
doug$ set | grep LIBRARY
doug$

У меня также были проблемы с моими сценариями nativecall, которые находили библиотеку, но я всегда решал их, исправляя установку библиотеки и / или предоставляя 'LD_LIBRARY_PATH'.

Извините, этот опыт был для вас не так хорош

person dmaestro12    schedule 23.03.2019
comment
См. Комментарий выше со ссылкой на SO «... Защита целостности системы». Я вспоминаю, что сейчас также столкнулся с этой проблемой по Дарвину. Болезненно. - person dmaestro12; 23.03.2019
comment
У меня также были проблемы с моими сценариями nativecall, которые находили библиотеку, но я всегда решал их, исправляя установку библиотеки и / или предоставляя 'LD_LIBRARY_PATH'. Но не о Дарвине, верно? - person raiph; 24.03.2019
comment
Комментарий Патрика Бокера выше предполагает, что разработчики надеются создать небольшую двоичную perl6 программу запуска вместо сценария оболочки, чтобы избежать проблемы с SIP. - person raiph; 24.03.2019
comment
@raiph Я использовал эту переменную ENV раньше в Дарвине, но, возможно, до того, как был введен SIP. Также возможно, что я временно отключил SIP, чтобы исправить проблемы с установкой библиотеки. Я просто знаю, что мне удалось решить аналогичные проблемы в своих (Дарвиновских) системах. - person dmaestro12; 05.04.2019