1.5. При настройке кросс-компилятора, каковы конфигурации пути поиска?
При создании кросс-компилятора необходимо обратить внимание на конфигурацию четырех связанных путей: путь файла библиотеки, связанный во время компиляции, путь файла заголовка, используемого во время компиляции, путь двоичного инструмента, используемого во время компиляции, и имя динамического загрузчика, указанного во время компиляции путь. (1) Путь к файлу библиотеки, связанному во время компиляции:
(1) Путь к файлу библиотеки, связанному во время компиляции:
Если не указан, это должен быть путь по умолчанию, связанный с путем установки. Если вы хотите указать, вы можете использовать опцию «LIB_PATH» при компиляции ld в binutils:
- (2) Путь к заголовочному файлу, используемому во время компиляции:
- (3) Бинарный путь инструмента, используемый во время компиляции:
Путь двоичного инструмента по умолчанию можно просмотреть с помощью следующей команды:
Используя указанный двоичный инструмент, вы можете использовать опцию «gcc -B»:
(4) Путь и имя динамического загрузчика, указанного во время компиляции:
Путь и имя динамического загрузчика, жестко запрограммированного в elf, указанного в файле спецификации gcc:
Включение поддержки длинных путей через реестр
Данный метод ни чуть не сложнее предыдущего и делает все то же самое, включает поддержку длинных путей свыше 256 символов для приложений Windows. Когда вы что-то меняете через редактор политик, по сути меняются настройки в реестре, это нужно помнить и знать. Сейчас я вам покажу какой ключ меняется. Откройте редактор реестра Windows. Перейдите в раздел:
HKLM\System\CurrentControlSet\Control\FileSystem
тут вам необходимо найти параметр LongPathEnabled, которому для активации поддержки длинных путей и изменения ограничений в MAX_PATH, нужно задать значение «1». Тут потребуется перезагрузка.
СКАЧАТЬ ГОТОВЫЕ КЛЮЧИ ДЛЯ АКТИВАЦИИ ОПЦИИ ПОДДЕРЖКИ ДЛИННЫХ ПУТЕЙ
Все что вам нужно, это распаковать zip-архив и запустить нужный файл активации, потом так же перезагрузиться, так как у вас будет создан нужный ключ реестра, без необходимости лезть в реестр самостоятельно.
Еще вы можете сделать такую поддержку и для конкретного пользователя по пути:
HKEY_CURRENT_USER\SOFTWARE\Microsoft\Windows\ CurrentVersion\Group Policy Objects\ {48981759-12F2-42A6-A048-028B3973495F} Machine\System\CurrentControlSet\Policies
Если там нет ключа LongPathsEnabled, то создайте его, тип DWORD (32 бита) и значение 1.
rules files based on standard debhelper or hand-written rules files
If your build file uses the standard debhelper format, the way of injecting the flags depends on your build system. If it’s based on the autotools, passing the exported form of dpkg-buildflags to the configure script is usually needed, e.g.
../configure --prefix=/usr $(shell dpkg-buildflags --export=configure)
If your build system reads the values from standard environment variables like CFLAGS, CXXFLAGS, CPPFLAGS or LDFLAGS, you often need to export these values at the beginning of your rules files. The simplest way to achieve this is to include the following snippet from dpkg at the beginning of your rules file to export all needed flags:
DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/buildflags.mk
Таргетирование переменных субпакета
В последнем разделе вы внесли изменения в переменную в пакете верхнего уровня приложения. Однако ситуация не всегда такая простая. Очень часто наиболее практичным способом будет поместить эти переменные в другой пакет, поскольку пакет не является импортируемым. Чтобы смоделировать это в образце приложения вы создадите новый субпакет , в котором будет храниться информация о времени сборки двоичного файла и имени пользователя, отправившего команду сборки.
Чтобы добавить новый субпакет, добавьте в проект новый каталог с именем :
Затем создайте новый файл с именем для хранения новых переменных:
Добавьте в текстовом редакторе новые переменные и :
app/build/build.go
Переменная хранит время сборки двоичного файла в форме строки. Переменная хранит имя пользователя, который выполнил сборку двоичного файла. Поскольку эти две переменные всегда имеют значения, их не нужно инициализировать с помощью значений по умолчанию, как вы это делали для переменной .
Сохраните и закройте файл.
Затем откройте файл для добавления этих переменных в ваше приложение:
Добавьте в файл следующие выделенные строки:
main.go
В этих строках вы вначале импортируете пакет , а затем выполняете печать и точно так же, как и при печати переменной .
Сохраните файл и закройте текстовый редактор.
Чтобы сделать эти переменные целью опции , вы можете использовать путь импорта с символом в конце User или , поскольку вам уже известен путь импорта. Для моделирования более сложной ситуации, когда путь к переменной не очевиден, мы используем команду в цепочке инструментов Go.
Команда выводит символы из заданного исполняемого файла, объектного файла или архива. В данном случае символ относится к объекту в коде, например, к определенной или импортированной переменной или функции. Генерирование таблицы символов с помощью команды и использование для поиска переменной позволяет быстро найти информацию о пути.
Примечание: команда не поможет найти путь к переменной, если имя пакета содержит любые символы, кроме символов ASCII, или содержит символ или , поскольку это ограничение относится к самому инструменту.
Для использования этой команды выполните сборку двоичного файла для :
После сборки укажите на него инструменту и выполните поиск в результатах:
Инструмент выводит большое количество данных. В связи с этим в предыдущей команде использовался оператор для передачи результатов в команду , которая выполняет поиск терминов с верхнего уровня в заголовке.
Результат должен выглядеть примерно так:
В данном случае первые две строки набора результатов содержат пути к двум переменным, которые вы ищете: и .
Теперь вам известны пути, и вы можете снова выполнить сборку приложения с изменением переменных , и во время сборки. Для этого нужно передать несколько флагов в :
Вы передали команду Bash для вывода текущего пользователя и команду для вывода текущей даты.
После сборки исполняемого файла запустите программу:
В системе Unix эта команда выводит примерно следующие результаты:
Теперь у вас имеется двоичный файл с информацией о версии и сборке, который будет полезен при решении возможных проблем в производственной среде.
buildsystems using cmake
cmake doesn’t follow CPPFLAGS. A fix was briefly available in sid, but had been revoked since upstream rejected the patch. See bug 653916 for details. As a workaround appending CPPFLAGS to CFLAGS and CXXFLAGS should work in most cases. Debhelper (since 0.9.20120417, only with compat=9 and dh_auto* commands!) and cdbs (since 0.4.110) handle this automatically so the workaround is no longer necessary if they are used.
Testing your packages after conversion
Previously, «hardening-check» from the «hardening-includes» package allowed testing a binary to see whether hardening options have been properly enabled, but «hardening-includes» has now been removed from unstable so this too is no longer available there, As for a replacement, lintian implements the hardening-no-* tags, which were based on the code from hardening-check.
Here’s the old information about hardening-check, in case you still have it available:
If you’re using only the default flags emitted by dpkg-buildflags, you should see «Stack protected», «Fortify Source functions» and «Read-only relocations» marked as «Yes», e.g.
jmm@pisco:~$ hardening-check /usr/bin/emacs23 /usr/bin/emacs23: Position Independent Executable: no, normal executable! Stack protected: yes Fortify Source functions: yes (some protected functions found) Read-only relocations: yes Immediate binding: no not found!
In some cases, «Stack protected» and «Fortify Source functions» emit false positives, see these notes from hardening-check’s manpage:
- Stack Protected: When an executable was built without any character arrays being allocated on the stack, this check will lead to false alarms (since there is no use of stack_chk_fail, even though it was compiled with the correct options.
- Fortify Source functions: When an executable was built such that the fortified versions of the glibc functions are not useful (e.g. use is verified as safe at compile time, or use cannot be verified at runtime), this check will lead to false alarms. In an effort to mitigate this, the check will pass if any fortified function is found, and will fail if only unfortified functions are found. Uncheckable conditions also pass (e.g. no functions that could be fortified are found, or not linked against glibc).
If a package has enabled all flags, the output should look like this:
jmm@pisco:~$ hardening-check /usr/sbin/sshd /usr/sbin/sshd: Position Independent Executable: yes Stack protected: yes Fortify Source functions: yes (some protected functions found) Read-only relocations: yes Immediate binding: yes
hardening-check can only check the resulting binaries and thus might not catch missing hardening flags if they are only missing in a few places. blhc is a small parser written in Perl which checks the build logs for missing hardening flags. It can be used on build logs created by dpkg-buildpackage or buildd.
Example usage:
$ blhc /path/to/log/file
Описание проблемы длинных путей
Раньше имена файлов в Windows ограничивались форматом 8.3 — всего восемь символов для имени файла и три для расширения. С появлением Windows 95 Microsoft сняла этот предел и позволила использовать гораздо более длинные имена.
Тем не менее, файловая система Windows по-прежнему накладывает некоторые ограничения, например, какие символы могут использоваться в именах файлов и общую длину путей. Некоторое время максимальная длина пути составляла 260 символов, но с появлением Windows 10, часть ограничений начала потихоньку уходить, например для приложений и появилась возможность отключить проверку MAX_PATH и использовать длинные пути без префикса \\?\.
Что интересно, значение в 260 символов обусловлено значением MAX_PATH Win32 API. У файловой системы NTFS максимальная длина пути ″немного″ больше и составляет 32767 символа. Для обхода ограничений Win32 API некоторые приложения используют формат UNC, указывая абсолютный путь с префиксом \\?\, например так:
\\?\C:\директория\поддиректория\имя файла
Хочу отметить, что на период ноября 2020 года и последней версий Windows 10 1909, в ПРОВОДНИКЕ Windows до сих пор есть ограничения в 260 символов, и мы все слышим обещания, что их исправят
Большинство людей может и не столкнуться с ней, а вот почти каждый системный администратор обязательно это увидит. Тут все дело в том, что в большинстве организаций есть свои сетевые файловые ресурсы, через которые пользователи производят обмен и работу с документами. В какой-то момент люди могут создать такой путь, который будет 258 или 260 символов, попытаются туда скопировать файл, а им выдастся ошибка:
Слишком длинный целевой путь: Имена файлов слишком длинны для помещения в эту целевую папку. Попробуйте использовать более короткое имя имя файла или расположение с более коротким путем
Тоже самое при копировании в папку, так же выскакивает «Слишком длинный целевой путь».
Вот ошибка при извлечении архива в сетевую папку:
Не удается завершить извлечение. Слишком длинный конечный путь. Переименуйте сжатую ZIP-папку и повторите попытку
rules files based on cdbs
cdbs already exports all dpkg-buildflags. If your package uses cdbs you will usually only need to verify, whether your upstream buildsystem properly follows these flags. (The cdbs bug bug 651964 about missing CPPFLAGS and LDFLAGS was fixed.)
cdbs supports DEB_*_MAINT_APPEND and DEB_BUILD_MAINT_OPTIONS directly (since cdbs 0.4.127) — just make sure to declare them before including CDBS snippets.
Handling dpkg-buildflags in your upstream build system
To fully support all hardened build flags in your upstream buildsystem, please ensure that the following flags are supported:
- CFLAGS, CPPFLAGS and LDFLAGS for code written in C
- CXXFLAGS, CPPFLAGS and LDFLAGS for code written in C++
Компилируем мини-программу с анализом Coverage
Создайте файл и скопируйте или перепишите в него код:
Теперь откройте терминал в каталоге, где находится , и скомпилируйте программу одной командой:
Если компиляция не удалась, прочитайте текст ошибки и исправьте ошибку. Если всё в порядке, то в каталоге появится ещё два файла: исполняемый файл и файл , содержащий базовую информацию для запуска Code Coverage.
Теперь надо запустить программу, чтобы в процессе работы она записала информацию о фактическом покрытии кода на данном запуске. В UNIX и в Windows запуск выглядит по-разному:
После завершения работы программы вы увидите в каталоге файл , который и содержит информацию о фактическом покрытии кода.
Инструменты стандартной библиотеки
Кроме самого компилятора, есть ещё стандартная библиотека C/C++. Она тоже позволяет задать параметры, которые помогают при отладке программ.
-D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC — эти параметры включают специальный отладочный режим стандартной библиотеки GNU C++. В этом режиме стандартные контейнеры и алгоритмы делают всевозможные проверки. Например, такой код:
в этом режиме выдаёт
/usr/include/c++/4.9.2/debug/vector:357:error: attempt to subscript container with out-of-bounds index 7, but container only holds 3 elements.
А такой код:
выдаёт
/usr/include/c++/4.9.2/bits/stl_algo.h:2267:error: elements in iterator range [__first, __last) are not partitioned by the value __val.
-D_FORTIFY_SOURCE=2 (только Linux/glibc) — этот параметр вставляет в программу разные проверки с уклоном в безопасность (переполнения буфера и т.д.). Например, с этим параметром такая программа:
выдаёт
*** buffer overflow detected ***: ./a.out terminated
Что такое библиотеки
Библиотеки в Linux содержат наборы функций или если сказать проще алгоритмов или действий для решения определенных задач. Например, если программе нужно вывести строку на экран она не начинает сама закрашивать нужные пиксели, а просто обращается к отвечающей за это функции из библиотеки, то же самое если программе нужно прочитать содержимое файла, она не работает с секторами жесткого диска, ей достаточно вызвать функцию из стандартной библиотеки с (libc.so) и передать ей в параметрах имя нужного файла, а библиотека уже вернет ей запрашиваемые данные.
На самом деле, такая структура реализации программного обеспечения очень выгодна, поскольку достаточно написать алгоритм лишь один раз и его смогут использовать все программы просто загружая библиотеку.
Не нужно думать что библиотеки есть только в Linux, в Windows они тоже есть, только имеют другой формат и расширение dll. В Linux же все библиотеки находятся в папах /lib/, /usr/lib, /usr/local/lib или для 64 битных систем также появляется папка lib64 во всех этих подкаталогах, для библиотек специфичных для этой архитектуры. Библиотека имеет расширение .so и ее название начинается со слова lib. Например, libfuse.so, libc.so.
Дальше, после расширения файла .so идет номер версии библиотеки. Номер версии меняется всякий раз, когда разработчики вносят в нее изменения ломающие совместимость со всеми рассчитанными на нее программами. В таком случае в системе будут уже две библиотеки и каждая программа будет использовать правильную версию. Например, glibc.so.6 и glibc.so.5.
Если интересно можно даже посмотреть какие библиотеки и каких версий, использует та или иная программа, например:
Также эта информация может быть полезна при создании портативных версий программ. А теперь давайте рассмотрим как устанавливаются библиотеки в Ubuntu.
Составляем отчёт о Code Coverage с помощью lcov
После предыдущего шага у нас есть всё, что надо для lcov, и теперь стало намного проще! Введите в терминале команду lcov с несколькими опциями:
Пояснения по поводу опций:
- устанавливает имя отчёта, при измерении покрытия кода тестами можно указать имя теста или набора тестов
- устанавливает имя выходного файла с промежуточной информацией
- указывает, что lcov должен использовать существующие данные о coverage
- устанавливает каталог, в котором надо искать данные о coverage, и мы передаём текущий каталог “.”
Теперь можно сгенерировать отчёт в виде HTML-страницы с помощью утилиты , входящей в состав пакета программ lcov:
Теперь вы можете перейти в каталог , открыть файл в браузере и посмотреть отчёт. Вы увидите страницу, на которой показан статичный отчёт о покрытии различных каталогов, и можно перейти по ссылкам для просмотра отдельных каталогов:
Вы можете перейти к конкретному файлу и посмотреть покрытие этого файла:
Как обойти ограничение длинных путей через символьную ссылку
Такой трюк мы с вами уже проделывали, когда нужно было переносить IMAP профиль у Outlook. Смысл в том, что создается файл в нужном вам месте, и этот файл это просто ярлык ссылающийся на нужный вам файл или папку, после этого путь сокращается и вы можете удалять или создавать все что вам нужно. Откройте командную строку, далее вам нужно иметь два составляющих:
- Путь где будет лежать файл символической ссылки — в моем примере C:\короткий путь
- Длинный путь — C:\Share\WINDOW~1\C73D~1\C6BF~1 \D915~1\5C04~1\B4E5~1\260MIC~1
Нам поможет команда mklink, где ключ /D создает ссылку на каталог
mklink /D «C:\короткий путь» «C:\Share\WINDOW~1\ C73D~1\C6BF~1\D915~1\5C04~1\B4E5~1\260MIC~1»
Символическая ссылка успешно создана, можно проверять.
Откройте каталог с укороченным путем и попробуйте создать просто папку, в итоге она будет создана именно по тому длинному пути, как видите легко можно обходить ограничение в 260 символов.
Параметры символов для компилятора
Если при выполнении сборки проекта из интегрированной среды разработки Visual Studio используется стандартная конфигурация сборки Отладка, компилятор C++ и управляемые компиляторы создают соответствующие файлы символов для кода. Параметры компилятора также можно задать в коде.
Параметры .NET
Выполните сборку с использованием параметра /debug, чтобы создать PDB-файл. Можно строить приложения с ключом /debug: full или /debug: pdbonly. При построении с ключом /debug:full создается отлаживаемый код. При сборке с ключом /debug:pdbonly создаются PDB-файлы, но не создается , сообщающий JIT-компилятору о доступности отладочной информации. Ключ /debug:pdbonly следует использовать при создании PDB-файла для сборки выпуска, которая не подлежит отладке. Дополнительные сведения см. в разделе /debug (параметры компилятора C#) или /debug (Visual Basic).
Параметры C/C++
-
Файлы VC<x>.pdb и <project>.pdb
PDB-файл для C/C++ создается при сборке с параметрами /ZI или /Zi. В Visual C++ параметр /Fd присваивает имя PDB-файлу, который создается компилятором. При создании проекта в Visual Studio с использованием интегрированной среды разработки используется параметр /Fd с целью создания PDB-файла с именем <project>.pdb.
При сборке приложения, написанного на C/C++, с использованием файла makefile и указанием параметра /ZI или /Zi без /Fd компилятор создает два описанных ниже PDB-файла:
-
VC<x>.pdb, где <x> представляет версию компилятора Microsoft C++, например VC11.pdb.
Файл VC<x>.pdb хранит все отладочные данные для отдельных объектных файлов и располагается в том же каталоге, что и файл makefile проекта. Каждый раз, создавая объектный файл, компилятор C/C++ добавляет отладочную информацию в файл VC<x>.pdb. Поэтому, даже если исходный файл включает общие файлы заголовков, такие как <windows.h> , определения типов (typedef) из этих заголовков сохраняются только один раз, а не включаются в каждый объектный файл. Вставляемая информация включает информацию о типах, но не включает символьную информацию, такую как определения функций.
-
<project>.pdb
Файл <project>.pdb содержит все отладочные данные из EXE-файла проекта и располагается в подкаталоге \debug. Файл <project>.pdb содержит полные отладочные данные, включая прототипы функций, а не только сведения о типах, содержащиеся в файле <x>.pdb.
Файлы VC<x>.pdb и <project>.pdb поддерживают добавочные обновления. Компоновщик также включает путь к PDB-файлам в EXE-файл или DLL-файл, которые он создает.
-
-
Таблицы экспорта библиотеки DLL
Чтобы посмотреть, какие символы доступны в таблице экспорта для библиотеки DLL, воспользуйтесь командой . Символьные данные из таблиц экспорта библиотеки DLL могут быть полезны при работе с сообщениями Windows, процедурами Windows (WindowProcs), объектами COM, при маршалинге или при работе с любой библиотекой DLL, для которой нет символов. Символы доступны для любой 32-разрядной системной библиотеки DLL. Вызовы функций перечисляются в том порядке, в котором эти функции вызываются, при этом текущая функция (наиболее глубоко вложенная) располагается наверху.
В выходных данных команды можно увидеть точное имя функции, включая символы, отличные от буквенно-цифровых. Просмотр точных имен функций полезен для задания точки останова в функции, поскольку в отладчике имена функций могут быть усечены в других местах. Дополнительные сведения см. в разделе dumpbin /exports.
Веб-приложения
Задайте для файла web.config вашего приложения ASP.NET режим отладки. В режиме отладки ASP.NET создает символы для динамически созданных файлов и включает присоединение отладчика к приложению ASP.NET. Если проект создан на основе шаблона веб-проектов, Visual Studio устанавливает этот режим автоматически при запуске отладки.
How can I use this and keep my packages backportable to Squeeze?
squeeze-backports includes a backport of 1.16.1.1, so all should be fine.
Additionally, dpkg-buildflags already existed in plain Squeeze (emitting only flags w/o hardening:
$ dpkg-buildflags --get CFLAGS -g -O2 $ dpkg-buildflags --get CPPFLAGS $ dpkg-buildflags --get LDFLAGS $ dpkg-buildflags --get CXXFLAGS -g -O2
Most of the convenience functions (/usr/share/dpkg/buildflags.mk and dpkg-buildflags —export=configure) don’t exist yet, though. As such, you need to export your flags like this:
CFLAGS:=$(shell dpkg-buildflags --get CFLAGS) CPPFLAGS:=$(shell dpkg-buildflags --get CPPFLAGS) LDFLAGS:=$(shell dpkg-buildflags --get LDFLAGS)
Инструменты GCC
Сам компилятор GCC тоже содержит инструменты, которые помогают находить ошибки в программах.
-fsanitize=address (только в GCC 4.8+ и Clang) — этот параметр встраивает в программу проверки доступов к памяти и ловит многие выходы за границы массивов. Например:
выдаёт
================================================================= ==15496==ERROR: AddressSanitizer: global-buffer-overflow on address 0x00000060152c at pc 0x400ad4 bp 0x7fffbac43e00 sp 0x7fffbac43df0 WRITE of size 4 at 0x00000060152c thread T0 . . .
-fsanitize=undefined -fno-sanitize-recover (только в GCC 4.9+ и Clang) — похожий параметр, которая ловит неопределённое поведение (undefined behavior), например, доступ по нулевому указателю. Такой код:
выдаёт
x.cpp:12:14: runtime error: load of null pointer of type 'int'
Ещё может находить деление на ноль, неправильные битовые сдвиги, целочисленные переполнения и выход из функции без возврата значения.
Эти два параметра описаны в https://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html. Есть ещё .
9 ответов
Лучший ответ
Ответ здесь: ,
Нажмите на лампочку и отредактируйте открываемый файл JSON. Выберите правильный блок, соответствующий вашей платформе (есть , , — версия ms-vscode.cpptools: 3). Обновите пути в (имеет значение, если вы компилируете с VS Code) или (имеет значение, если вы перемещаетесь с VS Code) или в обоих.
Благодаря @Francesco Borzì я добавлю его ответ здесь:
Вы также можете нажать кнопку мыши Right 🖰 на подчеркнутом коде.
27
banan3’14
9 Янв 2019 в 19:20
Я пробовал программу «Здравствуй, мир», и эта строка:
Было подчеркнуто зеленым. Я старался:
- Удаление строки
- Переписать строку
- Нажав на желтую лампочку и выбрав обновить
Исправлено предупреждение об ошибке. я не знаю, если это решило актуальную проблему. Но потом я собираю через Linux Linux на Windows 10
4
Zach Smith
20 Сен 2017 в 12:14
- Кликните левой кнопкой мыши по лампочке линии ошибки
- Нажмите
- Тогда это окно всплывающее
Просто установите Compiler path
1
akash
31 Май 2020 в 06:51
Сообщение об ошибке «Пожалуйста, обновите ваш includePath» не обязательно означает, что на самом деле есть проблема с . Проблема может заключаться в том, что VSCode использует неправильный компилятор или неправильный режим IntelliSense. В этом ответе я написал инструкции по устранению неполадок и согласованию конфигурации VSCode C ++ с вашим компилятором и проектом.
2
Scott McPeak
31 Авг 2019 в 23:18
Для Windows:
- Пожалуйста, добавьте этот каталог в вашу переменную среды (путь):
- В поле Включить обнаруженные ошибки укажите путь к вашей папке включения в
, поскольку это путь, откуда компилятор выбирает библиотеку для включения в вашу программу.
Sohail Aslam
4 Апр 2020 в 11:56
Если у кого-то есть такая проблема, возможно, вам просто нужно установить build-essential.
Picki
21 Май 2020 в 00:27
После закрытия и повторного открытия VS, это должно разрешиться.
Patrick
9 Авг 2019 в 20:59
Пробовал эти решения и многие другие за 1 час. Закончилось закрытием VS Code и открытием снова. Это просто
11
Ivy Growing
13 Окт 2018 в 19:38
Использование ldflags с go build
Как указывалось выше, означает флаги linker и используется для передачи флагов в linker через цепочку инструментов Go. При этом используется следующий синтаксис:
В этом примере мы передали в соответствующую команду , которая запускается в рамках . Эта команда заключает в двойные кавычки передаваемое в содержимое, чтобы предотвратить разрыв символов или неправильную интерпретацию передаваемых символов командной строкой. Отсюда вы можете передать много разных флагов . В этом обучающем руководстве мы используем флаг для записи информации в переменную во время связи, а затем указываем путь пакета к переменной и ее новое значение:
Внутри кавычек содержится опция и , соответствующая изменяемой переменной и ее новому значению. Символ разделяет путь пакета и имя переменной, а одинарные кавычки используются для предотвращения разрыва символов в паре ключ-значение.
Чтобы заменить переменную в нашем примере приложения, используйте синтаксис последнего блока команд для передачи нового значения и сборки нового двоичного файла:
В этой команде — это путь пакета переменной , поскольку данная переменная содержится в файле . — это переменная, в которую выполняется запись, а — это новое значение.
Для использования необходимо, чтобы изменяемое значение существовало и относилось к переменной уровня пакета типа . Эта переменная может быть экспортированной или неэкспортированной. Значение не может быть и не может задаваться результатом вызова функции. К счастью, соответствует всем этим требованиям. Она уже декларирована как переменная в файле и ее текущее значение () и желаемое значение () являются строками.
После сборки нового двоичного файла запустите приложение:
Результат будет выглядеть следующим образом:
С помощью вы успешно изменили значение переменной с на .
Теперь вы изменили переменную внутри простого приложения во время сборки. С помощью вы можете вставлять в двоичный файл сведения о версии, информацию о лицензирование и другие данные, используя только командную строку.
В этом примере измененная переменная находилась в программе , и благодаря этому было проще определить имя пути. Однако иногда путь к таким переменным бывает сложнее найти. На следующем шаге вы запишете значения в переменные в субпакетах, используя наилучший способ определения более сложных путей пакетов.
Использование редактора Linux gcc / g ++
2. Как gcc завершает компиляцию
Здесь задействована важная концепция: библиотека функций
Библиотеки функций обычно делятся на статические библиотеки и динамические библиотеки.
- Статическая библиотека относится кСсылка на компиляциюКогда поставить код файла библиотекиДобавить все в исполняемый файлПоэтому сгенерированный файл относительно велик, но файл библиотеки больше не нужен во время выполнения. егоИмя суффикса обычно «.a»
- В отличие от динамической библиотеки, код файла библиотеки не добавляется в исполняемый файл при компиляции и компоновке, а при выполнении программы.Ссылка на библиотеку загрузки файла во время выполнения, Это может снизить накладные расходы системы. Общие динамические библиотекиСуффикс «.so», Как упоминалось ранее, libc.so.6 — это динамическая библиотека. gcc по умолчанию использует динамические библиотеки при компиляции. После установки ссылки gcc может сгенерировать исполняемый файл, как показано ниже. gcchello.o –o привет
- gccБинарная программа, созданная по умолчанию, динамически связана, Это можно проверить с помощью команды file.
- Преимущество динамической компоновки: исполняемая программа имеет небольшой размер. Недостатки: низкая эффективность, сильная зависимость от библиотеки, если библиотека отсутствует, ее невозможно скомпилировать.
- Преимущества статической компоновки: не полагается на библиотеки и имеет хорошую переносимость. Недостатки: исполняемая программа имеет большой размер.
E Активируйте только предварительную обработку, это не создает файл, вам нужно перенаправить его в выходной файл
Установка библиотек в Ubuntu
Обычно, если вы используете менеджер пакетов вашего дистрибутива для установки новых программ, то библиотеки устанавливаются автоматически. Но если вы хотите собрать программу из исходников или запустить 32 битную программу на 64 битной системе могут начаться проблемы. Например, при запуске или компиляции программы вы получаете ошибку:
Обычно, в Ubuntu имена пакетов библиотек соответствуют имени нужной библиотеки. Поэтому чтобы определить точное имя в большинстве случаев достаточно воспользоваться поиском по базе пакетов:
Как видите, найдено два варианта библиотеки, libfuse2 и libfuse-dev.
Если библиотека нужна обычной программе и ее не нужно собирать из исходников, то будет достаточно установить библиотеку ubuntu без префикса dev. Например:
Если же вам нужно собрать приложение из исходников, то кроме обычной библиотеки понадобятся заголовочные файлы, в которых содержится описание реализованных в библиотеке функций. Такие пакеты имеют приставку dev, например, libfuse-dev, тогда нужно устанавливать этот пакет, а он уже в зависимостях потянет и обычную библиотеку, если она еще не установлена:
Много проблем может вызвать ситуация, когда вам нужно запустить 32 битную программу в 64 битной системе. Например, если вы установили 64 битную версию библиотеки, а программа все равно говорит о том, что не может ее найти, возможно это 32 битная программа и ей необходима именно 32 библиотека. Если программа не устанавливается с помощью пакетного менеджера, вам тоже придется устанавливать библиотеки вручную.
Посмотреть разрядность бинарника можно с помощью утилиты file:
На скриншоте показаны два варианта вывода программы, для 32 бит, в нашем случае Skype и для 64 — mount.
Для того чтобы установить библиотеку Ubuntu с архитектурой i386 сначала необходимо добавить поддержку архитектуры i386 в dpkg:
Затем обновляем наши репозитории:
А во время установки нужной вам библиотеки теперь необходимо указать архитектуру через двоеточие после имени пакета:
Если вы уверенны, что библиотека установлена, но программа все равно говорит, что такой библиотеки нет, то возможно, ей просто нужна другая версия библиотеки. Например, в системе есть libudev.so.0, а программе нужна libudev.so.0.1. Такое случается, если вы попытаетесь установить пакет для другого дистрибутива, особенно в Red Hat системах. Если в репозиториях нет нужной версии библиотеки, то скорее всего, они одинаковы, и можно просто создать символическую ссылку:
Затем программа найдет нужную библиотеку.
Управление библиотеками в Linux
Установка библиотек ubuntu уже рассмотрена, но хотелось бы упомянуть еще пару моментов. Как я сказал, библиотеки ubuntu размещаются в определенных каталогах, но расположение библиотек можно настроить.
Перед тем как библиотека будет подключена к программе, ее должна найти в системе специальная программа — менеджер библиотек. Он берет адреса библиотек из файла /etc/ld.cache, а этот файл формируется утилитой ldconfig, на основе файлов конфигурации /etc/ld.so.conf.
В этом файле перечислены все пути к библиотекам. Если вы хотите добавить свою папку для библиотек просто добавьте ее в этот файл:
Затем обновите кэш просто выполнив:
Теперь ваша библиотека может быть загружена программой, например, вы можете добавить путь /opt/lib или даже /home/user/lib. И система будет нормально грузить оттуда библиотеки.
Посмотреть какие библиотеки находятся в кеше ld.cache можно командой:
Также мы можем проверить находится ли там определенная библиотека:
Еще один способ указать программе где нужно искать библиотеки — это переменная LD_LIBRARY_PATH. Например:
Теперь программы, запускаемые в этом терминале, кроме стандартных путей поиска библиотек, будут использовать и указанную папку.