Вопрос
Пожалуйста, помогите понять, когда CGO_ENABLED необходимо и неизбежно, и что происходит с процессом компиляции go.
Когда CGO_ENABLED является обязательным
После прочтения статей в ссылках выглядит, что go имеет встроенную поддержку кросс-компиляции для целевой платформы, CGO_ENABLED никогда не будет обязательным. Это правильно?
Ситуация, когда cgo и CGO_ENABLED абсолютно обязательна, - это когда компилятор go не может создать двоичный код для целевая платформа. Например, представьте, что я пишу встроенную программу платы управления Space X в Go, и мне нужно использовать библиотеку C и компилятор для платы. Для платы нет другой библиотеки или компилятора.
В этом случае я должен сделать CGO_ENABLED = 1 и сказать cgo компилятор и компоновщик, чтобы использовать и где двоичные файлы библиотеки C скопированы на моем ноутбуке, и настроить компиляторы CFLAGS et c et c. Возможно, мне пришлось бы использовать C для всего кодирования вместо использования Go в этом случае, но каким-то образом я оказался в ситуации, когда мне пришлось использовать Go. Это когда CGO_ENABLED = 1 будет необходимо. Это правильно?
В противном случае, если особенно go имеет поддержку для кросс-компиляции целевой платформы, использование CGO_ENABLED = 1 может быть сокращением, чтобы просто повторно использовать существующая C библиотека для целевой платформы. Это правильно или есть какая-то другая причина, по которой требуется CGO_ENABLED ?
Что происходит
Я полагаю, когда CGO_ENABLED = 1 , в основном в исполняемом файле, созданном командой go build , будет составлен двоичный файл из части Go и двоичный файл из библиотеки C. И во время выполнения выполнение идет вперед и назад между двумя двоичными мирами go и C. Go двоичная сторона не будет знать C сторону, поэтому инструменты go, такие как отладчик, не будут доступны.
Полагаю, зависит ли исполняемый файл от жестких ссылок на все библиотеки или использует динамическое связывание c, зависит от компилятора целевой платформы.
Это правильное понимание?
Причина CGO_ENABLED = 0 по умолчанию для кросс-компиляции заключается в том, что мы должны использовать встроенную поддержку цели go для цели кросс-компиляция платформы и не должно быть причин не делать этого.
Причина, по умолчанию CGO_ENABLED = 1 для собственной локальной платформы, в том, что компилятор cgo знает (или автору компилятора известно) доступная архитектура локального компьютера и библиотеки ОС (или хорошо известные сторонние), следовательно, можно ожидать наилучшей оптимизации? Но я не уверен, что это правда, потому что сам компилятор go может быть лучше всего оптимизирован для локальной ОС и архитектуры, тогда зачем использовать cgo?
Пожалуйста, объясните, почему CGO_ENABLED = 1 по умолчанию для собственной локальной платформы.
Ссылки
cgo не Go
Некоторые люди, сталкиваясь с проблемой, думают: «Я знаю, я буду использовать cgo». Теперь у них две проблемы. cgo - это удивительная технология, которая позволяет Go программам взаимодействовать с C библиотеками. Это чрезвычайно полезная функция, без которой Go не будет в том положении, в котором она находится сегодня. cgo является ключом к способности запускать Go программы на Android и iOS. Тем не менее, и чтобы быть ясным, это мое мнение, я не говорю за кого-то еще, я думаю, что cgo чрезмерно используется в Go проектах. Я полагаю, что когда сталкиваешься с повторной реализацией большого фрагмента C кода в Go, программисты вместо этого используют cgo, чтобы обернуть библиотеку, полагая, что это более поддающаяся решению проблема. Я считаю, что это ложная экономика. Очевидно, что в некоторых случаях cgo неизбежно, особенно в тех случаях, когда вам необходимо взаимодействовать с графическим драйвером или системой управления окнами, которая доступна только в виде двоичного двоичного объекта. Но те случаи, когда использование cgo оправдывает свои компромиссы, реже встречаются, чем многие готовы признать. Поддержка Go для кросс-компиляции является лучшей в своем классе. Начиная с Go 1.5 вы можете выполнять кросс-компиляцию с любой поддерживаемой платформы на любую другую платформу с помощью официального установщика, доступного на веб-сайте проекта Go. По умолчанию cgo отключено при кросс-компиляции. Обычно это не проблема, если ваш проект чистый Go. Когда вы смешиваете зависимости от библиотек C, вы должны либо отказаться от возможности кросс-компиляции вашего продукта, либо вы должны тратить время на поиск и поддержку кросс-компиляции C наборов инструментов для всех ваших целей. Количество платформ, поддерживаемых Go, продолжает расти. Go 1.5 добавлена поддержка 64-битной ARM и PowerP C. Go 1.6 добавляет поддержку 64-битной MIPS, а архитектура IBM s390 рекламируется как Go 1.7. RIS C -V находится в стадии разработки. Если ваш продукт использует библиотеку C, у вас не только есть все проблемы кросс-компиляции, описанные выше, вы также должны убедиться, что код C, от которого вы зависите, надежно работает на новых платформах, поддерживаемых Go - и вы должны сделать это с ограниченной отладкой, которую предоставляет вам гибрид C / Go. Это подводит меня к следующему пункту.
Почему CGO_ENABLE оказывает такое влияние на виртуальную память?
the компилятор «эталонной» реализации Go (исторически называемой «g c»; той, которая доступна для загрузки с основного сайта) по умолчанию создает статически связанные двоичные файлы. Это означает, что такие двоичные файлы зависят только от так называемых «системных вызовов», предоставляемых ядром ОС, и не зависят от каких-либо общих библиотек, предоставляемых ОС (или третьими сторонами). На платформах Linux это не совсем верно: в настройках по умолчанию (сборка Linux для Linux, т.е. не кросс-компиляция) сгенерированный двоичный файл фактически связан с lib c и с libpthread (косвенно, через lib c).
cmd / cgo: документ о том, как CGO_ENABLED работает сегодня
Инструмент cgo включен по умолчанию для собственных сборок в системах, где он должен работать. По умолчанию это отключено при кросс-компиляции. Вы можете управлять этим, установив переменную среды CGO_ENABLED при запуске инструмента go: установите его в 1, чтобы разрешить использование cgo, и в 0, чтобы отключить его. Инструмент go установит ограничение сборки "cgo", если cgo включено. При кросс-компиляции вы должны указать C кросс-компилятор для использования cgo. Вы можете сделать это, установив переменную окружения CC_FOR_TARGET при построении цепочки инструментов с помощью make. bash, или установив переменную окружения CC каждый раз, когда вы запускаете инструмент go. Переменные среды CXX_FOR_TARGET и CXX работают аналогичным образом для кода C ++.
C? Go? Cgo!
- cgo