LINUX.ORG.RU

Статическая сборка HelloWorld на С# / dotnet

 ,


0

2

Умеет кто-нибудь dotnet publish -c Release так, чтобы не было

$ ldd HelloWorld
	linux-vdso.so.1 (0x00007fc945c1b000)
	libm.so.6 => /usr/lib/libm.so.6 (0x00007fc94590b000)
	libc.so.6 => /usr/lib/libc.so.6 (0x00007fc945600000)
	/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x00007fc945c1d000)
?

Практического вопроса нет, просто любопытно - почему на Go я могу собрать ровно тот же HelloWorld под Linux статически, а на Шарпе нет?

Всякое из Гугла SelfContained, PublishAot ничего не меняют.

★★★★
Ответ на: комментарий от anonymous

Если ничего не путаю - оно же даже не просто managed получается. Оно еще и к версии libc привязывается?

Т.е. - вот ребятки пишут свои микросервисы и складывают их в поды Кубера. За которым какой-то конкретный Linux, как я понимаю.

Т.е. получается зависимость от конкретного дистрибутива Linux? Или ерунду говорю?

Toxo2 ★★★★
() автор топика

Думаю тебе не статическая сборка нужна, а один .elf который можно перемещать между системами, для этого достаточно запаковать в один .elf и оригинальный исполняемый файл и его библиотеки, утилит не знаю, но уверен их уже много, по первым ссылкам в гугле находится вот это например: https://sourceforge.net/projects/statifier/

Через упаковщик можно решить и проблему с ресурсами, иногда нужны какие то иконки, таблицы данных, их тоже можно запаковать.

MOPKOBKA ★★★★★
()
Последнее исправление: MOPKOBKA (всего исправлений: 3)
Ответ на: комментарий от MOPKOBKA

libc у всех одна

Ну, как сказать... Вон Ubuntu свои заплатки на неё так накладывает, что поведение в локализации меняется.

Как раз один вариантов, который Гугл предлагал и который я не пробовал - собирать с musl.

Интересно же - есть тут живые люди, которые умеют собирать dotnet статически.

Toxo2 ★★★★
() автор топика
Последнее исправление: Toxo2 (всего исправлений: 1)
Ответ на: комментарий от anonymous

какая версия .NET?

$ pacman -Qs dotnet
local/dotnet-host 9.0.8.sdk109-1
    A generic driver for the .NET Core Command Line Interface
local/dotnet-runtime 9.0.8.sdk109-1
    The .NET Core runtime
local/dotnet-runtime-8.0 8.0.19.sdk119-1
    The .NET Core runtime
local/dotnet-sdk-8.0 8.0.19.sdk119-1
    The .NET Core SDK
local/dotnet-targeting-pack 9.0.8.sdk109-1
    The .NET Core targeting pack
local/dotnet-targeting-pack-8.0 8.0.19.sdk119-1
    The .NET Core targeting pack

А когда собирается пишет:

Версия MSBuild 17.8.32+74df0b3f5 для .NET
  Determining projects to restore...
  All projects are up-to-date for restore.
  HelloWorld2 -> /net8.0/linux-x64/HelloWorld2.dll
  Generating native code
  HelloWorld2 -> /net8.0/linux-x64/publish/

Интересно, почему 8.0 собирает, когда рядом вроде 9.0 есть. Пойду, попробую удалить 8.0 что ли...

Toxo2 ★★★★
() автор топика
Ответ на: комментарий от anonymous

Ну я все таки хотел ключами, либами и т.д. т.е. самим go.

Вон автор другой вопрос спрашивает, может там тоже есть какой сторонний проект на эту тему.

mx__ ★★★★★
()
Ответ на: комментарий от Toxo2

Пойду, попробую удалить 8.0 что ли...

Вычистил из своего ArchLinux всё, что было про net8.0, оставил только net9.0

Теперь собирается без libm.so.6 => /usr/lib/libm.so.6 ) Прогресс )

Toxo2 ★★★★
() автор топика
Ответ на: комментарий от George

Там нет статик флагов, по умолчанию один бинарник, хоть в 100 мегов или больше.

Давно были советы про всякие флаги типа шаред но оно не катило …

нужно проверить этот gcc-go, пишут что он все равно go-lib рядом навалит … хз точно.

mx__ ★★★★★
()
Ответ на: комментарий от mx__

интересный вопрос, на самом деле. сейчас собрал на 1.20 на убунте без кросс-компиляции, и ldd мне показывает

	linux-vdso.so.1 (0x00007ffdfa940000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x000076be6be00000)
	/lib64/ld-linux-x86-64.so.2 (0x000076be6c15e000)

то есть бинарник таки динамически слинкован. собирал тупо go build

George
()

Всякое из Гугла SelfContained, PublishAot ничего не меняют.

Да в общем и не должны. Этими вот попытками все вкомпилять граблей больше добавляется, чем решается проблем. А то бы на COFFa.out сидели и не жужжали, а зачем-то ELF втащили. А в «go который смог» только вопрос времени, в каком ведре он у тебя не запустится, даже если щас «линкуецца!». В дотнете просто не притворяются, что ты можешь в граните отлиться — дропают LTS по хитрому плану. А native aot еще и в 32битном арме не поддерживается, т.к... поддержку 32битных армов хотели дропнуть в Net 9... Но перехотели. Потому что Neon учить влом для поддержки векторных оптимизаций, но большой болт положить не дали «вы чо, у нас клиенты!» — поэтому насыпали нимношк болтиков там и тут.

slackwarrior ★★★★★
()
Ответ на: комментарий от slackwarrior

Красиво излагаете, конечно. И я далеко не Гуру.

Но вот что вижу, то и пою: Гошный ELF, только что собранный на ArchLinux c glibc, беру и запускаю в VoidLinux с musl. Пусть HelloWorld, но запускается же.

А с dotnet фигу.

Toxo2 ★★★★
() автор топика
Ответ на: комментарий от sanyo1234

Долго гуглил, пробовал по разному, но не могу собрать «Hello World» динамически на Go, хоть тресни.

Есть ли в этом недостатки?

А оно сможет подгрузить в процесс vendor-реализации ускорителей на API типа BLAS/Vulkan/GL? Не все полезные API это ядро, бывает и в виде библиотек

GPFault ★★★
()
Ответ на: комментарий от Toxo2

Пусть HelloWorld, но запускается же.

С этих оговорок и начинаются «далеко идущие выводы». Они же «ошибка выжившего». Но недалеко и не надолго. До следующего раза, когда «больше чот не запускается, вендоры памагите!». А в ответ «Не то ведро, не тот глибц, не так звезды сошлись». Нужно только несколько дольше посидеть на берегу.

slackwarrior ★★★★★
()
Ответ на: комментарий от slackwarrior

Не, шут с ним с Го. Один раз он действительно пригодился. Собрал в Linux под Windows всякое, делающее нечто с PostgreSQL и отправил людям почтой. Удобно и просто. И не надо людям ничего объяснять про env и прочую чепуху. «Просто запусти, и оно сделает то, что ты просил». Я её даже не проверял под Windows (ибо не было под рукой).

Меня в этой истории больше смущает некоторое недопонимание мной писательства микросервисов на C#, с последующей публикацией их в Кубе. Как это может надежно работать и динамически расширяться, если оно прибито к glibc, как выясняется? Вероятно надо пойти профессионалов спрашивать. Но профессионалы совершенно законно могут сказать «не твоего собачьего ума дело».

Toxo2 ★★★★
() автор топика
Ответ на: комментарий от Toxo2

Потому что компилятор go это кросс компилятор. Он собирает не под тот Линукс, на котором ты его запускаешь, а под некий common greatest denominator линуксов. Он линкует бинарник не с системным glibc, а с стабом glibc, который несёт с собой. И этот стаб содержит символы с низкими номерами версий. Поэтому результат запускается везде.

А компилятор си# видимо не кросс.

iliyap ★★★★★
()
Ответ на: комментарий от Toxo2

с последующей публикацией их в Кубе. Как это может надежно работать и динамически расширяться, если оно прибито к glibc, как выясняется?

В kubernetes всё в контейнерах, а в контейнере лежат изолированные нужные зависимости нужной версии.

Это как раз до контейнеризации и кубернетисов, приходилось думать о том, как оно будет деплоиться. Контейнеры эту часть задачи упростили (хотя на ЛОР очень много противников контейнеров).

Chiffchaff
()
Ответ на: комментарий от Toxo2

В контейнере лежит всё, что нужно для работы приложения. Начиная от рантайма с дотнетом и заканчивая какими-то нужными либами. Поэтому любой контейнер легко переносится с машины на машину.

Zhbert ★★★★★
()
Ответ на: комментарий от ugoday

Хорошо. Почти понял.

Значит самим разработчикам абсолютно без разницы, как именно оно там внутри контейнера собирается. Разработчики озабочены только написанием букв кода (ну и там всякими почти орфографическими правилами написания букв)

Тогда осталось два вопроса:

1. А чья это зона ответственности? Это DevOps ими командует? «Собирать будем эдак и никак иначе, потому что я так решил»?

2. А если разработчики передают исходный код третьей стороне - опять же DevOps'ы и свою часть обслуживания передают? Если приложение может использовать разные glibc оно же и вести себя может по-разному, я так понимаю.

Toxo2 ★★★★
() автор топика
Ответ на: комментарий от Toxo2

Решают разработчики, вываливают девопсу требования к тому, как их поделка работает. А те уже пакуют в контейнеры и настраивают CI/CD.

Zhbert ★★★★★
()
Последнее исправление: Zhbert (всего исправлений: 1)
Ответ на: комментарий от iliyap

Он собирает не под тот Линукс, на котором ты его запускаешь, а под некий common greatest denominator линуксов. Он линкует бинарник не с системным glibc, а с стабом glibc, который несёт с собой. И этот стаб содержит символы с низкими номерами версий.

Шикарное пояснение. Спасибо.

Toxo2 ★★★★
() автор топика
Ответ на: комментарий от Toxo2

если оно прибито к glibc

Во первых glibc не поддерживает статическую сборку.
И ничего там не прибито, просто собери с musl и все.
Вот пример файла проекта:

<Project Sdk="Microsoft.NET.Sdk">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>net9.0</TargetFramework>
        <ImplicitUsings>enable</ImplicitUsings>
        <Nullable>enable</Nullable>
        <PublishAot>true</PublishAot>
        <InvariantGlobalization>true</InvariantGlobalization>
        <StaticExecutable>true</StaticExecutable>
        <RuntimeIdentifier>linux-musl-x64</RuntimeIdentifier>
    </PropertyGroup>
</Project>
Собирать рекомендую под alpine.

arax ★★★
()
Последнее исправление: arax (всего исправлений: 1)
Ответ на: комментарий от Toxo2
  1. А чья это зона ответственности? Это DevOps ими командует? «Собирать будем эдак и никак иначе, потому что я так решил»?

Да.

  1. А если разработчики передают исходный код третьей стороне - опять же DevOps’ы и свою часть обслуживания передают?

Если код передаётся третьей стороне, то пущай третья сторона его и собирает.

оно же и вести себя может по-разному

Вот поэтому образа и придумали. Образ фиксирует зависимости и версию кода. Кубернетес предоставляет универсальную среду исполнения. Приколы вида «на ноуте разработчика работает, а на проде падает» не исключены полностью, но вероятность их сильно меньше.

ugoday ★★★★★
()
Ответ на: комментарий от arax

Супер! Красава.

Установил на VoidLinux (musl) dotnet9.0 Собрал.

Вот теперь действительно настоящий исполнимый файл получился, который и на ArchLinux выполняется.

И даже размер самого файла меньше, чем вариант на GoLang.
И судя по smem еще и памяти жрёт меньше, чем GoLang.

(там не то чтобы совсем HelloWorld, скажем - HelloWorld каждую секунду на обоих языках)

В общем вот так - мне нравится.

Toxo2 ★★★★
() автор топика