Как узнать, на какой libc.so будет ссылаться `rustc --target=$TARGET`?

Я хочу найти файл libc.so, который используется в сборке Rust, чтобы я мог запросить его с помощью --version. (Некоторые libc предоставляют информацию о своей версии через макросы C, поэтому альтернативой для них может быть использование контейнера cc в скрипте сборки. Но другие, такие как musl, этого не делают.)

Я могу выяснить, с каким libstd-*.so файлом будет связан двоичный файл или библиотека rust. Когда этот libstd.so связан с libc узла, запуск ldd на нем показывает, что libc.so. Но когда хост-система использует glibc, а целевая среда — musl, это не работает («Недопустимый заголовок ELF»). Вместо ldd я мог бы использовать readelf -d или objdump -p на libstd.so. Но они показывают только имя файла libc.so, который он использует, а не полный путь. И этого libc.so нет ни в одном из каталогов в LD_LIBRARY_PATH. (Я знаю, где он находится в моих собственных системах, но я пытаюсь найти его программно в произвольных системах.)

Запуск ldconfig -p дает мне информацию только о libc для хост-системы.

Было бы здорово, если бы существовал rustc-эквивалент gcc и clang -print-file-name=libc.so, чтобы я мог сделать что-то вроде rustc --target=$TARGET --print-file-name=libc.so.

Другие идеи о том, как я мог бы получить эту информацию?


person dubiousjim    schedule 25.04.2020    source источник


Ответы (1)


Вы можете передавать аргументы компоновщика в rustc следующим образом:

rustc -C link-args=...

Чтобы узнать, какой libc.so используется, я считаю, что достаточно следующей команды:

rustc -C link-args=-Wl,-t ...

Из man ld:

  -t
  --trace
       Print the names of the input files as ld processes them. ...

Обновление:

Это не сработало: rustc "съедает" вывод компоновщика.

Я смог получить желаемый результат косвенно:

echo 'fn main() { println!("")}' | rustc -C link-args=-Wl,-Map=map.out -o foo -
grep 'libc\.so' map.out
libc.so.6                     /usr/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-f25e49a311b0f577.rlib(std-f25e49a311b0f577.std.cy8lhng1-cgu.2.rcgu.o) (setuid@@GLIBC_2.2.5)
LOAD /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/libc.so
LOAD /lib/x86_64-linux-gnu/libc.so.6
person Employed Russian    schedule 25.04.2020
comment
Хм. echo 'fn main() { println!("")}' | rustc -C link-args=-t -o foo --target=$TARG0 - не выводит stderr или stdout, хотя полученный двоичный файл связан с libc.so.6. (На самом деле тело main может быть пустым, но оно все еще связано с libc.) - person dubiousjim; 25.04.2020
comment
@dubiousjim Похоже, rustc потребляет вывод компоновщика. Вам может понадобиться добавить --verbose или аналогичный флаг. - person Employed Russian; 25.04.2020
comment
Спасибо! Вот немного более минимизированный: echo 'fn main() {}' | rustc -C link-args=-Wl,-Map=map.out -o /dev/null - && egrep '^LOAD .*/libc[-._]so' map.out. Я пытался записать карту в /dev/stdout, но это не сработало. - person dubiousjim; 25.04.2020
comment
Однако, к сожалению, если вы добавите флаг --target к команде rustc, в результирующем файле карты не будет файлов .so. Даже если явная цель совпадает с хост-системой. Тем не менее, я думаю, что это некоторый прогресс, и я ценю даже его достижение. - person dubiousjim; 25.04.2020
comment
Извините, я был неправ. Если явная цель совпадает с хост-системой, libc.so присутствует в файле карты. Но не тогда, когда цель другая, как раз в этом случае я ищу решение. - person dubiousjim; 26.04.2020
comment
Похоже, когда хост является glibc, rustc может только статически связать цели musl. Так что ни бинарник, ни карта не указывают на musl libc. Кажется, что каталог libstd-*.so в .../rustlib/$TARGET/lib связан с libc, но, как я сказал в начальном вопросе, инструменты, которые я могу использовать для запроса, не сообщают полный путь к этой libc. Каким-то образом мне нужно выяснить, какой путь поиска библиотеки использует rustc, когда указан --target. Это не то значение, которое отображается в файле, создаваемом как LD_LIBRARY_PATH. - person dubiousjim; 26.04.2020
comment
Для тех, кто придет сюда позже и захочет сделать это, я открыл вопрос для ржавчины. Обсуждение там говорит мне, что цель x86_64-unknown-linux-musl rustc не использует системный MUSL, а объединяет свою собственную копию/версию. - person dubiousjim; 26.04.2020