Собрать Google — это всё равно что скомпилировать Windows 40 раз


Оглавление (нажмите, чтобы открыть):

Будьте всегда
в Настроении

Что это — компилятор, и как он работает

От Masterweb

Современные компьютерные технологии находятся в постоянной стадии совершенствования. С каждым днем выходят все новые и новые технологии, позволяющие воплотить в жизнь то, что еще недавно определялось как фантастика. Сильным изменениям поддаются и языки, как человеческие, так и компьютерные. В данной статье мы подробно расскажем, что это – компилятор, как с ним работать, для чего он создавался и где его сейчас можно встретить. Статья рекомендуется не только начинающим пользователям операционной системы Windows, но и программистам, желающим познать скрытые знания своей системы.

Язык для операционной системы

Для начала стоит абстрагироваться, ведь программирование – это не только вбивание определенных ключей-слов в машину, это еще и тщательно продуманные действия, связанные с компонентами системы. Изначально был двоичный код, потом программисты создали полумашинный язык программирования – ассемблер, но для чего?

Представьте себе, что вам надо считать на калькуляторе программиста каждый бит, потом правильно его связывать и многое другое. В ассемблере все стало чуточку проще, но все еще очень и очень непросто, если сравнивать с современными языками программирования, например, С++, который называют одним из сложнейших, но про него речь пойдет чуть позже.

В языке ассемблер все осуществляется благодаря регистрам процессора: деление, умножение, перемещение значения из точки А в точку Б и т. д. Основная его проблема, что он все еще является полумашинным, но все равно поддается прочтению человеку, в отличии от хаотично раскиданных битов. Еще одним минусом было ограниченное количество этих самых регистров.

В 80-х годах решили придумать язык программирования, благодаря которому можно будет легко и просто написать операционную систему. Так появился С и компилятор С GCC от компании GNU. Если вы пользуетесь Linux, то обязательно должны были видеть продукты данной компании. Кстати, ассемблер используется и поныне, ведь некоторые компиляторы создают объектные файлы с двоичным кодом, а другие исполнительные – с кодом на ассемблере. Все зависит от платформы разработчика.

Современный компилятор имеет следующие программы в себе:

    Дебагер – программа, которая отправляет сообщения об ошибке от линковщика, препроцессора, интерпретатора. Препроцессор – это программа, главной задачей которой является поиск специальных меток, начинающихся со знака #, и выполнение определенного рода команд. Например, добавления сторонней библиотеки для компиляции проекта. Интерпретатор – программа, которая переводит наш более-менее понятный язык программирования в двоичный код или ассемблер. Линковщик – программа, благодаря которой недостающие файлы автоматически подключаются.

Также существует 2 типа сборки проекта компилятором: динамическая и статическая. В первой добавляются лишь нужные проекту файлы, несмотря на среду разработки, а во втором случае — все в кучу (подключенные, конечно). Итак, из этого уже можно сказать, что компилятор – это целый список программ для сбора и обработки информации в понятный и логичный для компьютера вид. Дальше мы рассмотрим, с чего все начиналось.

Первые простейшие компиляторы

Может, вы удивитесь, но впервые объект нашей статьи (тогда его еще называли транслятор) появился в далеком 1954 году в Институте, специализирующемся на прикладной математике. Он включал в себя не настолько большой комплекс программ, как сейчас, но все равно был прорывом в науке на то время. Там не было дебагера, поэтому людям приходилось все делать буквально руками, причем используя при этом стандартную и дискретную математику, чтобы узнать, правильный ли результат получила электронно-вычислительная машина.

Возможна ли сборка без нового языка?

Если вы достаточно толковый программист, то вполне сможете выполнить эту задачу. Правда, для этого понадобится немало времени и сил. Кстати, раньше даже была профессия такая – программист-линковщик. Это только в новых языках программирования все автоматизировано, а раньше людям приходилось связывать куски кода Make файлами. Между прочим, некоторые проекты на Linux и сейчас можно собрать с помощью этих самых Make-файлов, нужно лишь указать их зависимости вручную.

После сбора кода линковщик отдавал работу уже компьютеру на обработку, где в итоге получал готовый бинарный код.

Как видите, компилятор – это не только программа, а еще и усилия множества людей. А они, как утверждал Генри Форд, пытаются автоматизировать каждый процесс.

Лучший компилятор Windows

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

Он живет и процветает в новом теле, если так можно сказать. Его наследником по праву является С++, хоть и его создателя воспрещают писать на нем код, похожий на С, многие программисты игнорирует это и делают, но почему допускается такое грубое нарушение правил?


    Во-первых, он взял солидную долю стандартных библиотек от С, и новые компиляторы G++ способны компилировать код С, что уже само по себе указывает на их схожесть. Во-вторых, С++ был создан, чтоб заместить С, и итоги этого мы видим сейчас. К слову, программа компилятор G++ не «ругается» до тех пор, пока не будет использован хотя бы один класс – в этом и есть основное отличие двух языков. Можно назвать G++ лучшим компилятором, не зря ведь благодаря ему пишут мобильные приложения, операционную систему Windows и т. д.

Совет начинающим программистам

Ваш путь будет тернист – это стоит знать прежде всего. Для начала работы с языком, например, если это С, вы обязательно должны будете ознакомиться с компилятором C. А если с ним не подружиться и не понять его логику, то ваши проекты один за одним будут лагать и вылетать.

Попытайтесь как можно больше читать книг не только про основы программирования, но и про историю создания языков, так вы обязательно начнете понимать саму суть процесса. Старайтесь совмещать практику и новые знания, так все куда быстрее запоминается. Кроме того, постарайтесь довести свой английский хотя бы до среднего уровня, иначе вам будет очень сложно в ориентировании по IDE.

В заключение

Надеемся, после прочтения данной статьи вы поняли, что это – компилятор, как он работает, зачем создавался и кому по сей день нужен. Стоит напомнить, что самое главное для программиста – это понимание ситуации, понимание основных принципов, поэтому очень надеемся, что статья вам в этом помогла.

Собрать Google — это всё равно что скомпилировать Windows 40 раз

Этот материал не претендует на абсолютную истину, может быть, что-то можно сделать проще и быстрее. Автор как знает, так и делает. Кроме того он не является большим экспертом в области nix-систем. Всё, что написано ниже, найдено на просторах интернета, в большинстве своём на не русскоязычных форумах, систематизировано и изложено на родном для автора языке — русском.

Коллеги, не задавайте мне вопросы по данной теме в личку, уже несколько лет как я забросил Android и не интересуюсь развитием ядер, как впрочем и самого Android-a.

Сообщение отредактировал PaWill — 08.03.16, 14:54

Часть 1. Необходимые инструменты и исходники

Для компиляции ядра нам потребуется nix-подобная операционная система. Я использовал Ubuntu 10.04 LTS — Long-term support 32-bit, которую установил на виртуальную машину VMware Workstation. Где всё это добро скачать/купить, как установить мы здесь обсуждать не будем. Если вы это не смогли сделать самостоятельно или с помощью гугла, то читать эту статью для вас ещё рано (или уже поздно). 🙂
И так, у нас всё установлено и работает. Теперь проверим все ли необходимые компоненты присутствуют в системе, возможно какие то пакеты придётся доустановить.
Запускаем терминал:

У вас, вероятней всего, не будет важного пакета — sun-java6-jdk on Ubuntu 10.04 (Lucid). Для его автоматической загрузки нужно в адреса репозитория добавить дополнительные ссылки. Введите в терминале:

После того как всё скачается и установится опять команда [1] пока не будет ошибок. Будем считать что с Ubuntu покончили.

Теперь нам потребуются собственно сами исходники ядра. Их можно найти на http://opensource.samsung.com/. В строке поиска вводим «I9000» и получаем:

Ещё нам потребуется кросс-компилятор, которым будем собирать ядро:
http://www.codesourcery.com/sgpp/lite/arm/. nux-gnu.tar.bz2 (80 МБ)


И последнее что потребуется — это initramfs.cpio. Я выдрал его из JS8. Как это сделать расскажу как-нибудь отдельно.
JS8_initramfs.tar ( 2,64 МБ )

Пока всё, продолжение следует.

Сообщение отредактировал PaWill — 19.03.11, 19:38

Часть 2. Распаковка исходников

Всё что вы скачали будет находится в каталоге /home/имя_пользователя/Загрузки. У меня этот путь выглядит как:

Кто компилирует компилятор и можно ли доверять открытому коду?

Xakep #246. Учиться, учиться, учиться!

В далеком 1984 году легендарный Кен Томпсон, создатель языка программирования C и операционной системы UNIX (вместе с Деннисом Ритчи), опубликовал классическую лекцию «Размышления о доверии к доверию» (Reflections on Trusting Trust), в которой наглядно показал, как можно внедрить троян в бинарный файл с помощью «бага» в компиляторе. Триггер для внедрения трояна в бинарный файл содержится в исходном коде компилируемой программы и может выглядеть как тривиальная функция. Если вы не знаете, как работает «жучок» в компиляторе, то даже самое тщательное изучение исходного кода программы не выявит в ней никаких опасностей. Но скомпилированный файл будет уже заражен.

Кен Томпсон продемонстрировал атаку подобного типа через компилятор C и программу, написанную на C. Но то же самое можно сделать и через любую другую систему интерпретации: ассемблер, загрузчик, даже аппаратный микрокод. И чем глубже сидит «жучок», тем сложнее его обнаружить, а баг, например, в аппаратном микрокоде обнаружить почти невозможно.

Главный вывод, который делает гуру компьютерной науки — никакое количество верификации исходных кодов или контроля не защитит вас от угрозы. Вы не можете доверять никакому коду, если вы только не написали его сами, особенно нельзя доверять «коду от компаний, которые берут на работу таких как я», писал Томпсон 29 лет назад (что интересно, сейчас он работает в компании Google).

Вероятно, именно классическая статья Томпсона подтолкнула голландского программиста Йоса ван ден Увера (Jos van den Oever) провести проверку популярных дистрибутивов Linux. Программист просто захотел проверить, можно ли самостоятельно из предоставленных исходных кодов скомпилировать бинарный файл, который побитно совпадает с бинарным файлом, распространяемым официально.

Ван ден Увер ни разу так и не смог скомпилировать двоичный файл, совпадающий с аутентичным. Это и не удивительно. Например, компилятор GCC из одних и тех же исходников выдает всегда разные версии бинарного файла, из-за разных меток времени. В этом смысле Clang/LLVM понадежнее: он хотя бы позволяет получить одинаковые бинарные файлы из одних и тех же исходников, даже если компилировать их на разных машинах.

Таким образом, проверить соответствие исходных кодов Linux и распространяемого бинарного файла не представляется возможным.

Можно ли скомпилировать исполняемые файлы Windows, на машине Linux?

В своей работе, все данные проекта находится на NFS, который доступен как из Linux и машин Windows (с использованием Samba). Вся работа выполняется на Linux, но я играю с идеей составления некоторых инструментов для Windows, так что я могу отлаживать с Visual Studio.

У меня уже есть хороший Makefile, который может построить код как 32-битной или 64-битной Linux, используя разные цели. Предполагая, что у меня есть версии для Windows всех внешних библиотек где-то на NFS, и при условии, что код достаточно чистый для компиляции под Windows, есть возможность собрать и связать свою программу для Windows, используя существующую Makefile, на Linux? В идеале я хотел бы назвать Makefile раз и иметь его построить все три 32-битном Linux, 64-битной Linux и Windows.

Дополнительный плюс будет возможностью скомпилировать его с любыми визуальными метаданными студии, чтобы сделать его легко отлаживать.

Да, вы можете добиться того, что с MinGW , например.

Тем не менее, вы, вероятно, придется адаптировать один или два варианта в вашем Makefile.

Вам нужен пакет кросс-компиляции. Вы также можете использовать вино LIB.

Есть целый ряд возможностей, я могу думать:


Вы можете попробовать запустить Visual Studio под Wine. Если Visual Studio не работает, вы все равно можете быть в состоянии запускать инструменты командной строки.

Выполнить полную установку Windows, в виртуальной машине. Я сделал это с Linux на Windows, но не наоборот, но я уверен, что это возможно.

Использование VNC для доступа к отдельным ПК с Windows с компьютера Linux

Использование кросс-сборки GCC вместо Visual Studio

Как можно скомпилировать C++ Linux/Andro > Задать вопрос

Вопрос в заголовке. Как можно скомпилировать бинарник для использования на Linux/Android/etc, используя Windows? Для сборки использую make, но, вроде, gcc не умеет собирать те же Linux’овые бинарники из-под винды.

Аналогичный вопрос для статичных и динамических библиотек. Как я понял, тот же NDK может компилировать .so файлы из-под Windows, однако, я так и не разобрался как.

UPD1: Под сборкой из-под Windows я имел ввиду именно сборку из-под Windows. Виртуальные машины — хороший вариант, но мне не подходит.

UPD2: Хорошими вариантами можно назвать следующие:

1. Установка CoLinux и компиляция с его помощью https://stackoverflow.com/a/21550741/10400333

2. Использование crosstool-ng для создания компилера для кросс-компиляции: https://stackoverflow.com/a/4770417/10400333

3 ответа 3

Могу сказать за обратный процесс. Из под линукса компилирование виндовых программ возможно. Только нужно скачивать виндовый компилятор mingw, который работает под линукс. Скорее всего в винде это также возможно.

Visual Studio 2020 позволяет разрабатывать программы для Linux. Но компиляция и отладка там происходит в Linux. Делается это так:

Запускается виртуальная машина с Линуксом (я делал это с VMware), там должен быть установлен компилятор и отладчик (все это подробно описано в хелпе VS). В сетевых настройках VM указывается IP, на котором эта VM должна сидеть (локальный адрес из 192.168.x.x годится).

В VS создается Линукс проект (при установке VS эта возможность должна быть включена), и в настройках указывается IP виртуальной машины. Это все, дальше разработка и отладка делается так же, как и для Windows.

VS 2020 поддерживает разработку и для мобильных платформ (на С++ для Андроид, к примеру), но сам не пробовал, так что ничего тут не могу сказать.

Собираем LAME прямо из исходников

Возможно, вы уже слышали про то, как некоторые энтузиасты собирают кодеки из исходных кодов сами и таким образом имеют доступ к новейшим кодекам.

Эта несложная задача для меня когда-то казалась неподъемной. Порой очень хотелось протестировать последние разработки кодека, несмотря на то, что они были нестабильны. По себе знаю, что нестабильность для энтузиастов — все равно, что масло в огонь, лишь разжигает интерес. Овладев умением сборки из исходных кодов, я хотел бы поделиться им с вами. Речь пойдет о сборке кодеков под Windows 7.

Репозиторий, CVS и зачем все это надо


Самые свежие исходные коды LAME (грубо говоря, текст программы) лежат в репозиториях на SourceForge.net. Репозиторий находится под довольно старой системой контроля версий: CVS. Для нее проще всего воспользоваться специальным клиентом, заточенным под Windows — TortoiseCVS (ссылка для скачивания).

Зачем вообще эта система контроля? Проще всего можно сказать, что это хранилище исходных текстов, которое позволяет легко разрабатывать один проект нескольким людям.

Устанавливаем TortoiseCVS, таким образом у вас появляется возможность скачать себе самые последние исходные коды кодека.

Исходные тексты в EXE

Итак, предположим, что есть у нас на руках текст программы. А дальше что? Просто так текст сам по себе ничего не делает. Нам нужно создать из него исполняемый файл или, в простонародии, «экзешник». Для разных языков программирования путь этого преобразования разный. Но большинство кодеков пишутся на языке Си из-за того, что кодекам очень важна производительность. Как известно, программы, написанные на Си, в большинстве случаев оказываются быстрее своих собратьев, написанных на других языках. Остановимся на том, как же преобразовать текст программы, написанный на языке Си в исполняемый файл (этот процесс также называется компиляцией и сборкой).

Но тут вступает в свою силу следующий нюанс: в основном многие кодеки по идейным соображениям имеют открытый исходный код (как у LAME). Потому и разрабатываются они не на Windows, а на Linux, опять же из соображений, что Linux бесплатен и тоже имеет открытые исходные коды. Так что изначально кодеки написаны для Linux и, как правило, с большим трудом компилируются Windows-средствами от Microsoft (Visual C++). Возникает задача: скомпилировать программу, изначально написанную в Linux для работы в Windows. И тут есть решение: MinGW. Этот набор утилит, который, если не вдаваться в дебри, специально создан для таких задач.

Компиляция программ Linux

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

Для подготовки программы к выполнению, специальная программа собирает ее из исходного кода на языке программирования в машинный код — команды процессора. Этот процесс называется компиляция. Linux — это свободное программное обеспечение, а поэтому исходные коды программ доступны всем желающим. Если программы нет в репозитории или вы хотите сделать что-то нестандартное, то вы можете выполнить компиляцию программы.

В этой статье мы рассмотрим, как выполняется компиляция программ Linux, как происходит процесс компиляции, а также рассмотрим насколько гибко вы сможете все настроить.

Подготовка системы

Мы будем компилировать программы, написанные на Си или С++, так как это наиболее используемый язык для программ, которые требуют компиляции. Мы уже немного рассматривали эту тему в статье установка из tar.gz в Linux, но та статья ориентирована больше на новичков, которым нужно не столько разобраться, сколько получить готовую программу.

В этой же статье тема рассмотрена более детально. Как вы понимаете, для превращения исходного кода в команды процессора нужно специальное программное обеспечение. Мы будем использовать компилятор GCC. Для установки его и всех необходимых инструментов в Ubuntu выполните:

sudo apt install build-essential manpages-dev git automake autoconf

Затем вы можете проверить правильность установки и версию компилятора:

Но перед тем как переходить к самой компиляции программ рассмотрим более подробно составляющие этого процесса.

Как выполняется компиляция?

Компиляция программы Linux — это довольно сложный процесс. Все еще сложнее, потому что код программы содержится не в одном файле и даже не во всех файлах ее исходников. Каждая программа использует множество системных библиотек, которые содержат стандартные функции. К тому же один и тот же код должен работать в различных системах, содержащих различные версии библиотек.

На первом этапе, еще до того как начнется непосредственно компиляция, специальный инструмент должен проверить совместима ли ваша система с программой, а также есть ли все необходимые библиотеки. Если чего-либо нет, то будет выдана ошибка и вам придется устранить проблему.

Дальше идет синтаксический анализ и преобразование исходного кода в объектный код, без этого этапа можно было бы и обойтись, но это необходимо, чтобы компилятор мог выполнить различные оптимизации, сделать размер конечной программы меньше, а команды процессора эффективнее.

Затем все объектные файлы собираются в одну программу, связываются с системными библиотеками. После завершения этого этапа программу остается только установить в файловую систему и все. Вот такие основные фазы компиляции программы, а теперь перейдем ближе к практике.

Компиляция программ Linux


Первое что нам понадобиться — это исходники самой программы. В этом примере мы будем собирать самую последнюю версию vim. Это вполне нейтральная программа, достаточно простая и нужная всем, поэтому она отлично подойдет для примера.

Получение исходников

Первое что нам понадобиться, это исходные коды программы, которые можно взять на GitHub. Вы можете найти исходники для большинства программ Linux на GitHub. Кроме того, там же есть инструкции по сборке:

Давайте загрузим сами исходники нашей программы с помощью утилиты git:

git clone https://github.com/vim/vim

Также, можно было скачать архив на сайте, и затем распаковать его в нужную папку, но так будет удобнее. Утилита создаст папку с именем программы, нам нужно сделать ее рабочей:

Настройка configure

Дальше нам нужно запустить скрипт, который проверит нашу программу на совместимость с системой и настроит параметры компиляции. Он называется configure и поставляется разработчиками программы вместе с исходниками. Весь процесс компиляции описан в файле Makefile, его будет создавать эта утилита.

Если configure нет в папке с исходниками, вы можете попытаться выполнить такие скрипты чтобы его создать:

Также для создания этого скрипта можно воспользоваться утилитой automake:

aclocal
$ autoheader
$ automake —gnu —add-missing —copy —foreign
$ autoconf -f -Wall

Утилита automake и другие из ее набора генерируют необходимые файлы на основе файла Mackefile.am. Этот файл обязательно есть в большинстве проектов.

После того как вы получили configure мы можем переходить к настройке. Одним из огромных плюсов ручной сборки программ есть то, что вы можете сами выбрать с какими опциями собирать программу, где она будет размещена и какие дополнительные возможности стоит включить. Все это настраивается с помощью configure. Полный набор опций можно посмотреть, выполнив:

Рассмотрим наиболее часто используемые, стандартные для всех программ опции:

  • —prefix=PREFIX — папка для установки программы, вместо /, например, может быть /usr/local/, тогда все файлы будут распространены не по основной файловой системе, а в /usr/local;
  • —bindir=DIR — папка для размещения исполняемых файлов, должна находится в PREFIX;
  • —libdir=DIR — папка для размещения и поиска библиотек по умолчанию, тоже в PREFIX;
  • —includedir=DIR — папка для размещения man страниц;
  • —disable-возможность — отключить указанную возможность;
  • —enable-возможность — включить возможность;
  • —with-библиотека — подобно enable активирует указанную библиотеку или заголовочный файл;
  • —without-библиотека — подобное disable отключает использование библиотеки.

Вы можете выполнить configure без опций, чтобы использовать значения по умолчанию, но также можете вручную указать нужные пути. В нашем случае ./configure есть, и мы можем его использовать:

Во время настройки утилита будет проверять, есть ли все необходимые библиотеки в системе, и если нет, вам придется их установить или отключить эту функцию, если это возможно. Например, может возникнуть такая ошибка: no terminal library found checking for tgetent(). configure: error: NOT FOUND!

В таком случае нам необходимо установить требуемую библиотеку. Например, программа предлагает ncurses, поэтому ставим:

sudo apt install libncurces-dev

Приставка lib всегда добавляется перед библиотеками, а -dev — означает, что нам нужна библиотека со всеми заголовочными файлами. После удовлетворения всех зависимостей настройка пройдет успешно.


Сборка программы

Когда настройка будет завершена и Makefile будет готов, вы сможете перейти непосредственно к сборке программы. На этом этапе выполняется непосредственно преобразование исходного кода в машинный. Утилита make на основе Makefile сделает все необходимые действия:

Дальше осталось установить саму программу, если вы использовали опцию prefix, чтобы не устанавливать программу в основную файловую систему, то можно применить стандартную опцию make:

После этого программа будет установлена в указанную вами папку, и вы сможете ее использовать. Но более правильный путь — создавать пакет для установки программы, это делается с помощью утилиты checkinstall, она позволяет создавать как deb, так и rpm пакеты, поэтому может использоваться не только в Ubuntu. Вместо make install выполните:

Затем просто установите получившийся пакет с помощью dpkg:

sudo dpkg install vim.deb

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

Если вы устанавливали программу с помощью make install, то удалить ее можно выполнив в той же папке обратную команду:

sudo make uninstall

Команда удалит все файлы, которые были скопированы в файловую систему.

Выводы

В этой статье мы рассмотрели, как выполняется компиляция программы Linux. Этот процесс может быть сложным для новичков, но в целом, все возможно, если потратить на решение задачи несколько часов. Если у вас остались вопросы, спрашивайте в комментариях!

На завершение видео о том, что такое компилятор и интерпретатор:

Собрать Google — это всё равно что скомпилировать Windows 40 раз

Этот материал не претендует на абсолютную истину, может быть, что-то можно сделать проще и быстрее. Автор как знает, так и делает. Кроме того он не является большим экспертом в области nix-систем. Всё, что написано ниже, найдено на просторах интернета, в большинстве своём на не русскоязычных форумах, систематизировано и изложено на родном для автора языке — русском.

Коллеги, не задавайте мне вопросы по данной теме в личку, уже несколько лет как я забросил Android и не интересуюсь развитием ядер, как впрочем и самого Android-a.

Сообщение отредактировал PaWill — 08.03.16, 14:54

Часть 1. Необходимые инструменты и исходники

Для компиляции ядра нам потребуется nix-подобная операционная система. Я использовал Ubuntu 10.04 LTS — Long-term support 32-bit, которую установил на виртуальную машину VMware Workstation. Где всё это добро скачать/купить, как установить мы здесь обсуждать не будем. Если вы это не смогли сделать самостоятельно или с помощью гугла, то читать эту статью для вас ещё рано (или уже поздно). 🙂
И так, у нас всё установлено и работает. Теперь проверим все ли необходимые компоненты присутствуют в системе, возможно какие то пакеты придётся доустановить.
Запускаем терминал:


У вас, вероятней всего, не будет важного пакета — sun-java6-jdk on Ubuntu 10.04 (Lucid). Для его автоматической загрузки нужно в адреса репозитория добавить дополнительные ссылки. Введите в терминале:

После того как всё скачается и установится опять команда [1] пока не будет ошибок. Будем считать что с Ubuntu покончили.

Теперь нам потребуются собственно сами исходники ядра. Их можно найти на http://opensource.samsung.com/. В строке поиска вводим «I9000» и получаем:

Ещё нам потребуется кросс-компилятор, которым будем собирать ядро:
http://www.codesourcery.com/sgpp/lite/arm/. nux-gnu.tar.bz2 (80 МБ)

Кто компилирует компилятор и можно ли доверять открытому коду?

Xakep #246. Учиться, учиться, учиться!

В далеком 1984 году легендарный Кен Томпсон, создатель языка программирования C и операционной системы UNIX (вместе с Деннисом Ритчи), опубликовал классическую лекцию «Размышления о доверии к доверию» (Reflections on Trusting Trust), в которой наглядно показал, как можно внедрить троян в бинарный файл с помощью «бага» в компиляторе. Триггер для внедрения трояна в бинарный файл содержится в исходном коде компилируемой программы и может выглядеть как тривиальная функция. Если вы не знаете, как работает «жучок» в компиляторе, то даже самое тщательное изучение исходного кода программы не выявит в ней никаких опасностей. Но скомпилированный файл будет уже заражен.

Кен Томпсон продемонстрировал атаку подобного типа через компилятор C и программу, написанную на C. Но то же самое можно сделать и через любую другую систему интерпретации: ассемблер, загрузчик, даже аппаратный микрокод. И чем глубже сидит «жучок», тем сложнее его обнаружить, а баг, например, в аппаратном микрокоде обнаружить почти невозможно.

Главный вывод, который делает гуру компьютерной науки — никакое количество верификации исходных кодов или контроля не защитит вас от угрозы. Вы не можете доверять никакому коду, если вы только не написали его сами, особенно нельзя доверять «коду от компаний, которые берут на работу таких как я», писал Томпсон 29 лет назад (что интересно, сейчас он работает в компании Google).

Вероятно, именно классическая статья Томпсона подтолкнула голландского программиста Йоса ван ден Увера (Jos van den Oever) провести проверку популярных дистрибутивов Linux. Программист просто захотел проверить, можно ли самостоятельно из предоставленных исходных кодов скомпилировать бинарный файл, который побитно совпадает с бинарным файлом, распространяемым официально.

Ван ден Увер ни разу так и не смог скомпилировать двоичный файл, совпадающий с аутентичным. Это и не удивительно. Например, компилятор GCC из одних и тех же исходников выдает всегда разные версии бинарного файла, из-за разных меток времени. В этом смысле Clang/LLVM понадежнее: он хотя бы позволяет получить одинаковые бинарные файлы из одних и тех же исходников, даже если компилировать их на разных машинах.

Таким образом, проверить соответствие исходных кодов Linux и распространяемого бинарного файла не представляется возможным.

Компилятор компилирует все включенные файлы заголовков вместе с основной программой каждый раз, когда мы скомпилируем эту программу?

Согласно Википедии, это то, что делает препроцессор C:

«Препроцессор заменяет строку #include текстом файла ‘ stdio.h ‘, который, помимо прочего, объявляет функцию printf() .


Итак, если это правда, программа, которая содержит больше файлов заголовков, потребуется больше времени для компиляции?

Итак, если это правда, программа, которая содержит больше заголовков файлов потребуется больше времени для компиляции?

Конечно. Строго говоря, чем больше кода, на который должен смотреть компилятор, тем больше времени требуется для его обработки. Для некоторых действительно больших проектов время, необходимое для просмотра всех файлов, становится проблемой. Это особенно справедливо для необычно большого и/или сложного кода шаблона, который по практическим соображениям должен находиться в файлах заголовков. Организация самих файлов заголовков также влияет на время компиляции.

Однако, это не так просто, как вы думаете. Он в значительной степени зависит от качества реализации (QOI) компилятора, а современные компиляторы в настоящее время на самом деле неплохо обрабатывают файлы заголовков в большинстве случаев.

Например, GCC специально распознает включение охранников, чтобы сократить время обработки. И теперь компиляторы становятся намного лучше при обработке сложного кода шаблона, например. большая часть стандартной библиотеки. В компиляторах VС++, включая windows.h (который имеет прототипы функций почти для всего Windows API), в моем опыте заметно не увеличивается время компиляции. И если все остальное не удается, многие, если не все компиляторы, имеют прекомпилированные заголовки», которые вы можете использовать.

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

Как правило, да, «программа, которая содержит больше файлов заголовков, занимает больше времени для компиляции».

К сожалению, предварительно обработанное содержимое заголовка может меняться в зависимости от того, какие макрокоманды определены и как. И особенно заголовки Microsoft, как правило, предназначены для получения разных результатов в зависимости от таких символов (в стандартном С++ это в основном только символ NDEBUG , что влияет на расширение assert ). Поэтому компиляторы являются консервативными и делают повторную сборку и сборку заголовков снова и снова для каждой единицы перевода.

Один из распространенных способов избежать этого — так называемые предварительно скомпилированные заголовки.

Один, насколько я знаю необычную технику, возможно, не реализован каким-либо компилятором, заключается в том, чтобы позволить программисту сказать, что «для этой партии компиляций вы можете предположить, что все заголовки будут расширяться до одного и того же», и, возможно, даже что по умолчанию (даже если они могут давать разные результаты из стандартного С++, если предположение не выполняется).

Я бы предпочел последний подход, так как он ускорил бы большую часть любой сборки, но прекомпилированные заголовки — это то, что мы имеем на практике.

Дэвид Вандевоорде работал над предложением для С++.

Примеры языков с модулями: Modula-2, Ada, UCSD Pascal.

К сожалению, он не был готов для С++ 11, но, возможно, мы получим модули позже.

Теоретически да — чем больше кода, тем больше время компилятора. И все, что вы включаете, — это места для предварительного процессора вместо include-statement, как вы уже упоминали.

Практически это зависит от того, что вы включаете и как. Если вы включите надлежащим образом, влияние на скорость можно пренебречь. Включение слишком большого количества стандартных заголовков создает скорее загрязнение пространства имен, чем компиляцию. Весь код стандартных библиотек уже скомпилирован и будет только связан. В Qt вы можете включать каждый класс отдельно (например, #include ) или — возможность для ленивых программистов — включать все классы из модуля (например, #include ), который включает в себя тысячи заголовков. Поэтому я никогда не замечаю значительную разницу во времени компиляции между двумя методами.

Некоторые мысли и факты формируют мой опыт:

В силиконе упоминаются защитники заголовка. Они в первую очередь не предназначены для оптимизации времени компиляции, а для предотвращения круговых включений. Так если вы включите заголовок в 10 местах, он будет анализироваться только один раз.

В С++ включить в заголовки только в том случае, если вы выходите из класса в этом заголовок. В противном случае используйте форвардную декларацию.

Используйте личную идиотскую реализацию — поэтому ваши заголовки будут содержать только одна/пара указателей.

Не включайте заголовки кода, которые вам не нужны. с /CPP файл. Хорошая система сборки анализирует зависимости заголовка от основы включения заявлений. Ваш код будет излишне перекомпилировали каждый раз, когда изменился любой из обязательно включенных заголовков.

Помимо времени компиляции, время соединения также может быть значительным. Делать конечно, приложение состоит из DLL (DLL/так файлов). Таким образом, вы могли бы избегайте связывания всех вместе для каждой компиляции. В одном проекте я время соединения составляет около 10 минут. Клиент отказался используйте DLL из-за некоторых эзотерических причин.

Если время компилятора действительно является проблемой, стоит посмотреть под капюшон системы сборки. Некоторые нетривиальные проекты должны запускаться сценарии post-pre-build. Убедитесь, что выполнение этих сценариев только если это необходимо.

В одном проекте было сокращено время полной сборки от 4 часов до 40 минут после внесения некоторых изменений в инструмент. Если вы на Linux проверяете с помощью strace, как работает make. Ты будешь удивительно, сколько ненужных файлов доступа он делает.

Мастер Йода рекомендует:  Потенциальная уязвимость php-скриптов PHP
Добавить комментарий