Нет установленных приложений для файлов типа общая библиотека
Обновлено: 21.11.2024
Библиотеки — незаменимый инструмент любого программиста. Это уже существующий код, который скомпилирован и готов к использованию. Они часто предоставляют общие функции, такие как связанные списки или двоичные деревья, которые могут содержать любые данные, или специальные функции, такие как интерфейс к серверу базы данных, такому как MySQL.
Большинство крупных программных проектов содержат несколько компонентов, некоторые из которых вы можете использовать позже в каком-либо другом проекте или которые вы просто хотите отделить в организационных целях. Когда у вас есть повторно используемый или логически отдельный набор функций, полезно создать из него библиотеку, чтобы вам не приходилось копировать исходный код в ваш текущий проект и постоянно перекомпилировать его — и чтобы вы могли хранить разные модули. вашей программы не пересекаются и изменяют одно, не затрагивая другие. После того, как он будет написан и протестирован, вы можете безопасно использовать его снова и снова, каждый раз экономя время и хлопоты, связанные с его встраиванием в свой проект.
Создание статических библиотек довольно просто, и, поскольку мы редко получаем вопросы по ним, я не буду их освещать. Я буду придерживаться общих библиотек, которые кажутся более запутанными для большинства людей.
Прежде чем мы начнем, может быть полезно получить краткое изложение всего, что происходит от исходного кода до работающей программы:
На шагах 3 и 4 происходит волшебство (и путаница) с общими библиотеками.
Теперь вернемся к нашему (очень простому) примеру.
foo.h определяет интерфейс нашей библиотеки, единственную функцию foo(). foo.c содержит реализацию этой функции, а main.c — это программа-драйвер, использующая нашу библиотеку.
Для целей этого примера все будет происходить в /home/username/foo
Шаг 1. Компиляция с независимым от позиции кодом
Нам нужно скомпилировать исходный код нашей библиотеки в позиционно-независимый код (PIC): 1
Шаг 2. Создание общей библиотеки из объектного файла
Теперь нам нужно превратить этот объектный файл в общую библиотеку. Мы назовем его libfoo.so:
Шаг 3. Связывание с общей библиотекой
Как видите, на самом деле это было довольно просто. У нас есть общая библиотека. Давайте скомпилируем наш main.c и свяжем его с libfoo. Мы назовем нашу последнюю программу test. Обратите внимание, что опция -lfoo ищет не foo.o, а libfoo.so. GCC предполагает, что все библиотеки начинаются с lib и заканчиваются на .so или .a (.so для общих объектов или общих библиотек, а .a для архивных или статически связанных библиотек).
Указание GCC, где найти общую библиотеку
Ой-ой! Компоновщик не знает, где найти libfoo. У GCC есть список мест, куда он смотрит по умолчанию, но нашего каталога нет в этом списке. 2 Нам нужно указать GCC, где найти libfoo.so. Мы сделаем это с опцией -L. В этом примере мы будем использовать текущий каталог /home/username/foo:
Шаг 4. Сделайте библиотеку доступной во время выполнения
Хорошо, ошибок нет. Теперь давайте запустим нашу программу:
О нет! Загрузчик не может найти разделяемую библиотеку. 3 Мы не устанавливали его в стандартное место, поэтому нам нужно немного помочь загрузчику. У нас есть пара вариантов: мы можем использовать для этого переменную окружения LD_LIBRARY_PATH или rpath. Давайте сначала посмотрим на LD_LIBRARY_PATH:
Использование LD_LIBRARY_PATH
Там ничего нет. Давайте исправим это, добавив наш рабочий каталог к существующему LD_LIBRARY_PATH:
Что случилось? Наш каталог находится в LD_LIBRARY_PATH, но мы его не экспортировали. В Linux, если вы не экспортируете изменения в переменную среды, они не будут унаследованы дочерними процессами. Загрузчик и наша тестовая программа не унаследовали сделанные нами изменения. К счастью, это легко исправить:
Хорошо, сработало! LD_LIBRARY_PATH отлично подходит для быстрых тестов и для систем, в которых у вас нет прав администратора. Однако недостатком является то, что экспорт переменной LD_LIBRARY_PATH означает, что это может вызвать проблемы с другими запускаемыми вами программами, которые также полагаются на LD_LIBRARY_PATH, если вы не сбросите ее в предыдущее состояние, когда закончите.
Использование rpath
Теперь давайте попробуем rpath (сначала мы очистим LD_LIBRARY_PATH, чтобы убедиться, что нашу библиотеку находит именно rpath). Rpath или путь выполнения — это способ встраивания расположения общих библиотек в сам исполняемый файл, вместо того, чтобы полагаться на расположения по умолчанию или переменные среды. Мы делаем это на этапе связывания. Обратите внимание на длинную опцию «-Wl,-rpath=/home/username/foo». Часть -Wl отправляет компоновщику параметры, разделенные запятыми, поэтому мы говорим ему отправить параметр -rpath компоновщику с нашим рабочим каталогом.
Отлично, сработало. Метод rpath великолепен, потому что каждая программа получает список своих разделяемых библиотек независимо друг от друга, поэтому нет проблем с поиском разными программами неправильных путей, как это было для LD_LIBRARY_PATH.
rpath и LD_LIBRARY_PATH
Однако у rpath есть несколько недостатков. Во-первых, требуется, чтобы общие библиотеки были установлены в фиксированном месте, чтобы все пользователи вашей программы имели доступ к этим библиотекам в этих местах. Это означает меньшую гибкость в конфигурации системы. Во-вторых, если эта библиотека ссылается на монтирование NFS или другой сетевой диск, вы можете столкнуться с нежелательными задержками или, что еще хуже, при запуске программы.
Использование ldconfig для изменения ld.so
Что, если мы захотим установить нашу библиотеку, чтобы ею могли пользоваться все пользователи системы? Для этого вам потребуются права администратора. Вам это понадобится по двум причинам: во-первых, чтобы поместить библиотеку в стандартное место, возможно, /usr/lib или /usr/local/lib, к которым обычные пользователи не имеют доступа для записи. Во-вторых, вам нужно будет изменить файл конфигурации ld.so и кеш. Как root, сделайте следующее:
Теперь файл находится в стандартном месте, с правильными разрешениями и доступен для чтения всем. Нам нужно сообщить загрузчику, что он доступен для использования, поэтому давайте обновим кеш:
Это должно создать ссылку на нашу общую библиотеку и обновить кеш, чтобы он был доступен для немедленного использования. Давайте еще раз проверим:
Теперь наша библиотека установлена. Прежде чем мы проверим это, мы должны очистить несколько вещей:
На всякий случай еще раз очистите LD_LIBRARY_PATH:
Повторно свяжите наш исполняемый файл. Обратите внимание, что нам не нужна опция -L, так как наша библиотека хранится в папке по умолчанию, и мы не используем опцию rpath:
Убедимся, что мы используем экземпляр /usr/lib нашей библиотеки с помощью ldd:
Хорошо, теперь давайте запустим его:
На этом все заканчивается. Мы рассмотрели, как создать общую библиотеку, как связать ее и как решить наиболее распространенные проблемы с загрузчиком общих библиотек, а также плюсы и минусы различных подходов.
- Просматривается в разделе DT_RPATH исполняемого файла, если нет раздела DT_RUNPATH.
- Он ищет в LD_LIBRARY_PATH. Это пропускается, если исполняемый файл имеет setuid/setgid из соображений безопасности.
- Он просматривает раздел DT_RUNPATH исполняемого файла, если не установлены биты setuid/setgid (по соображениям безопасности).
- Он просматривает файл кеша /etc/ld/so/cache (отключается с помощью параметра компоновщика -z nodeflib).
- Он просматривает каталоги по умолчанию /lib, а затем /usr/lib (отключено с помощью параметра компоновщика -z nodeflib).
Что такое позиционно-независимый код? PIC — это код, который работает независимо от того, где в памяти он находится. Поскольку несколько разных программ могут использовать один экземпляр вашей общей библиотеки, библиотека не может хранить вещи по фиксированным адресам, поскольку расположение этой библиотеки в памяти будет варьироваться от программы к программе. ↩
GCC сначала ищет библиотеки в /usr/local/lib, а затем в /usr/lib. После этого он ищет библиотеки в каталогах, указанных параметром -L, в порядке, указанном в командной строке. ↩
Загрузчик GNU по умолчанию, ld.so, ищет библиотеки в следующем порядке: ↩
Как описано здесь, исполняемые файлы ELF, независимые от позиции, не распознаются должным образом файлом и, в свою очередь, иногда nautilus, что делает невозможным их запуск (выдает ошибку «Для файлов «общая библиотека» не установлено приложение».):
Обходные пути могут оказаться сложными для новых пользователей и привести к тому, что они будут делать небезопасные действия, для которых они не предназначены (например, путаница с правами доступа к файлам или установка файлов .desktop в неправильном месте, . ). Поэтому я предлагаю это исправить.
Похоже, предпринимались попытки исправить это в файловом инструменте: https://bugs.launchpad.net/ubuntu/+source/file/+bug/1747711 Однако похоже, что это не так. на самом деле так легко отличить библиотеку от исполняемого файла, один из участников обсуждения предположил, что: «Это указывает на то, что четкой границы между разделяемыми библиотеками и исполняемыми файлами PIC просто не существует».
Я предлагаю команде Nautilus переоценить ситуацию и рассмотреть возможность повторного запуска исполняемых файлов пользователями, если это возможно. Вот идеи, которые я мог бы придумать, чтобы двигаться дальше:
Одним из решений может быть, если действительно не невозможно отличить библиотеки от исполняемых файлов, сделать наилучшее предположение, которое ошибается при обнаружении его как исполняемого, если неясно (что не является стороной, какой бы инструмент Nautilus в настоящее время не использовал для определения типа падает) и разрешите попытку запустить его, если сомневаетесь.
Еще один способ: поскольку Nautilus уже позволяет запускать файл .desktop по щелчку (по крайней мере, если запуск текстовых файлов разрешен или приводит к запросу), расширить спецификацию файла .desktop. разрешить относительные пути и научить сопутствующие инструменты, такие как gtk-run, извлекать файлы .desktop из абсолютных путей, чтобы эту проблему можно было решить, имея возможность сопровождать файл .desktop без необходимости что-либо устанавливать. р>
Одним из дополнительных подходов может быть установка расширения файла или другого дополнительного маркера, который четко идентифицирует файл как исполняемый. Непреднамеренно или нет, .sh, кажется, делает эту работу прямо сейчас для Nautilus, но очевидно, что имя не-скриптового ELF, который на самом деле не может быть запущен с любой оболочкой с окончанием .sh, является собственной кроличьей норой, потенциальной путаницей пользователей. (Или это обычное дело? Я видел установщики, оканчивающиеся на .sh , но я всегда предполагал, что они на самом деле начнут работать в bash или sh, даже если впоследствии будут содержать упакованный двоичный файл.) Одно окончание, которое может работать для это может быть .bin , так что содержимое ELF или PIE + .bin = исполняемый двоичный файл.
Конечно, есть какой-то способ решить эту проблему, который можно найти, чтобы снова включить простой обмен непосредственно запускаемыми программами в Linux вне менеджеров пакетов. (И, пожалуйста, давайте не будем обсуждать недостатки этого по сравнению с использованием менеджера пакетов и/или сборкой из исходного кода, я знаю, что некоторые люди думают, что это не следует делать в любом случае, но некоторые варианты использования существуют для этого вне чисто проприетарного программного обеспечения.) Приносим свои извинения, если для этого уже есть дубликат билета, но я не смог его найти.
Чтобы загружать дизайны, вам необходимо включить LFS и попросить администратора включить хэшированное хранилище. Подробнее
Существует список распространенных ошибок, которые я часто вижу в Ubuntu. Возникла проблема со списком слияния, затем возникла ошибка BADSIG и ряд распространенных ошибок обновления Ubuntu.
Одной из таких распространенных ошибок, которые я часто вижу при установке программы из исходного кода, является ошибка при загрузке разделяемых библиотек. Полная ошибка обычно выглядит так:
ошибка при загрузке общих библиотек:
не удается открыть общий объектный файл: нет такого файла или каталога
Например, я пытался использовать сервер FreeRADIUS, и он показал мне эту ошибку:
Причина этой ошибки в том, что библиотеки программы были установлены в месте, где динамический компоновщик не может их найти.
Позвольте мне показать вам, как можно решить эту проблему.
Исправление ошибки «не удается открыть общий объектный файл: нет такого файла или каталога»
Одним из быстрых способов исправить эту «ошибку при загрузке общих библиотек» автоматически является использование ldconfig.
Все, что вам нужно сделать, это открыть терминал (Ctrl+Alt+T) и ввести следующую команду:
Один этот вкладыш должен решить проблему в большинстве случаев. Однако, если это не так, я обсудил другой метод обработки этой ошибки. Но перед этим позвольте мне рассказать вам, что делает приведенная выше команда.
Что такое общие объектные файлы? Как указанная выше команда решает проблему?
Видите ли, в C/C++ .so (общий объект) — это файл скомпилированной библиотеки. Он называется общим объектом, потому что этот библиотечный файл может совместно использоваться несколькими программами. Эти сгенерированные библиотеки обычно находятся в каталогах /lib или /usr/lib.
Теперь, если вам интересно, как эта крошечная команда устранила эту проблему, вы должны прочитать справочную страницу ldconfig, в которой говорится:
ldconfig создает необходимые ссылки и кеширует самые последние общие библиотеки, найденные в каталогах, указанных в командной строке, в файле /etc/ld.so.conf и в доверенные каталоги (/lib и /usr/lib). Кэш используется компоновщиком времени выполнения, ld.so или ld-linux.so. ldconfig проверяет заголовки и имена файлов библиотек, с которыми сталкивается, при определении версий, ссылки на которые должны быть обновлены.
Я надеюсь, что это быстрое исправление поможет вам устранить неприятную ошибку при загрузке сообщения общих библиотек в Ubuntu и других Linux.
Если нет, вы можете провести расследование и попытаться решить проблему так, как это описано в следующем разделе.
Альтернативный метод исправления ошибки «не удается открыть общий объектный файл»
Описанный выше метод устраняет проблему, если рассматриваемая библиотека доступна в вашей системе. Но так может быть не всегда.
Если в вашей системе не установлена программа, у вас не будет файла библиотеки. ldconfig ничего не может сделать, если файл библиотеки вообще отсутствует.
Таким образом, альтернативный метод заключается в установке необходимой программы, и она должна автоматически создать библиотеку.
Позвольте мне показать вам это на примере. Допустим, вы видите эту ошибку:
Проблема связана с libgobject версии 2.0. Номер версии важен, потому что некоторые программы зависят от конкретной версии библиотеки и если не находят, то жалуются на это.
Теперь apt предоставляет параметр поиска, который можно использовать для поиска пакета и определения его версии перед его установкой.
Теперь этот пакет librust-gobject-sys-dev может быть тем, что вам нужно, если вы знаете, что пытаетесь запустить программу на Rust. Но что, если это программа на Python, которую вы запускали, которая жаловалась на это?
Вы можете расширить область поиска, удалив библиотеку из имени пакета во время поиска.lib означает, что библиотека и библиотеки могут быть предоставлены универсальным пакетом, который можно назвать gobject-xyz.
Было бы неплохо искать строку в именах пакетов (вместо описания), чтобы получить более точные результаты.
В приведенном выше усеченном выводе вам нужно будет увидеть, связан ли пакет с исходной программой, которую вы пытались запустить. Вы также должны проверить версию предоставленной библиотеки.
Определив правильный пакет, установите его следующим образом:
После установки вы можете снова запустить команду ldconfig, чтобы обновить кеш:
Этот метод требует некоторых усилий с вашей стороны, но именно так обрабатываются зависимости.
Ничего не работает, что теперь?
Если вам не повезло, описанные выше методы могут вам не подойти. Что вы можете сделать?
Во-первых, имейте в виду, что в некоторых случаях общие библиотеки могут использоваться из других пакетов. Если вы пытались запустить программу XYZ, а программа ABC устанавливает правильную версию общей библиотеки, она может работать (или не работать) для вас. Вы можете попробовать его.
Во-вторых, если вы пытаетесь запустить слишком старую или слишком новую программу, для нее может потребоваться версия библиотеки, недоступная для вашего дистрибутива Linux.
Что вы можете сделать, так это проверить, можете ли вы использовать какую-либо другую версию программы. Например, используйте Eclipse версии 3 вместо версии 4. Это может помочь в вашем случае.
Другой способ — проверить веб-сайт разработчиков или форумы и посмотреть, сможете ли вы вручную установить правильную версию библиотеки из ее исходного кода. Это требует больших усилий (в 2020 г.), но у вас не так много вариантов.
Это сработало для вас?
Надеюсь, я немного прояснил для вас ситуацию. Удалось ли вам решить проблему с общими библиотеками в вашей системе? Если у вас есть вопросы, предложения, не стесняйтесь оставлять комментарии. Чао :)
Я новичок в программировании под Linux, я использую cmake и делаю компиляцию образца Urho3d, он генерирует много файлов, таких как 01_Hello World.
но тип файла 01_Hello World - это общий объект ELF 64-bit LSB ,
как я могу сгенерировать 01_Hello World типа ELF 64-битный исполняемый LSB
Что находится в вашем make-файле или входных данных cmake? Похоже, вы скомпилировали, но не связали объектный файл(ы).
В современных компиляторах эти два шага часто сливаются в один, особенно для простых однофайловых проектов:
Это скомпилирует и скомпонует и создаст исполняемый двоичный файл.
Это просто скомпилируется, и в результате получится объектный файл 'a.out', который все еще нужно связать.
«UNIX проста и понятна», — Деннис Ритчи, «GNU — это не UNIX», — Ричард Столлман
test.c
int main()
возврат 0;
>
gcc -0 test test.c
я использую проверку файла, тип говорит: myexecutable: общий объект ELF 64-bit LSB, x86-64, версия 1 (SYSV), динамически связанный, интерпретатор /lib64/ld-linux-x86-64.so.2, для GNU/Linux 3.2.0, BuildID[sha1 ]=7e4301a171f116accd1bdaf1e8391760991af197, без удаления
Да, это нормально. Это исполняемый файл. Если вам нужен статический двоичный файл:
Но если вы действительно не знаете, что делаете и почему, вам не следует пытаться использовать статическое связывание.
Вы можете запустить `file` на любом "настоящем исполняемом файле Linux" в каталоге /usr/bin/ в качестве эталона.
РЕДАКТИРОВАТЬ: хм, я только что обнаружил, что в соответствующем поле вывода `file` иногда указано «общий объект», а иногда «исполняемый файл» для обычных двоичных файлов в /usr/bin. Я не уверен точно, в чем разница, что вызывает другой вывод из файла `file`, но все они одинаково "настоящие" исполняемые файлы.
«UNIX проста и понятна», — Деннис Ритчи, «GNU — это не UNIX», — Ричард Столлман
spwork, обратите внимание, что это строчная буква "о", а не ноль.
Онлайн
Я использую gnome и визуальный файловый менеджер, дважды щелкаю тестовый файл, но он не может выполниться,
и я обнаруживаю, что 64-битный исполняемый файл ELF LSB выполняется при двойном щелчке, поэтому я задайте вопрос
оба типа могут выполняться с помощью ./test , но только 64-битный исполняемый файл ELF LSB может выполняться при двойном щелчке.
Я использую gnome и визуальный файловый менеджер, дважды щелкаю тестовый файл, но он не может выполниться,
и я обнаруживаю, что 64-битный исполняемый файл ELF LSB выполняется при двойном щелчке, поэтому я задайте вопрос
оба типа могут выполняться с помощью ./test , но только 64-битный исполняемый файл ELF LSB может выполняться при двойном щелчке.
Здесь есть две части: во-первых, откуда вы знаете, что ваша тестовая программа не выполняется. Даже если и так, то абсолютно ничего не делает, так что узнать об этом невозможно. Запускается ли он из терминала (то есть без кода ошибки и с нулевым возвращаемым значением)?
Теперь, если ваш файловый менеджер неправильно запускает функциональные двоичные файлы при нажатии на них, это не имеет никакого отношения к двоичным файлам, а является ошибкой в файловом менеджере.
«UNIX проста и понятна», — Деннис Ритчи, «GNU — это не UNIX», — Ричард Столлман
Ваш общий объект объявляет интерпретатор, который виден в выходных данных вашего файла. Это означает, что это динамически подключаемый исполняемый файл, а не общая библиотека. (точнее, это может быть и то, и другое одновременно)
Если вы ожидаете, что окно консоли откроется в стиле Windows, просто вернет ноль и снова исчезнет, вы ожидаете не того, чего хотите. Даже в консоли вам нужно будет провести некоторое тестирование, действительно ли она вернула ноль. Различные способы выражения НЕТ в Баше, возможно.
Утилита `file` неправильно определяет двоичные файлы с поддержкой PIE как двоичные файлы, а не общие объекты. Текущие версии нашей цепочки инструментов gcc включают PIE по умолчанию в рамках повышения безопасности.
Правильно управлять репозиториями AUR – aurpublish (теперь это отдельный инструмент)
Даже в консоли вам нужно провести некоторое тестирование.
Только для того, чтобы узнать, работает ли двоичный файл должным образом, а не для того, чтобы узнать, запускался ли он вообще. Если `./test` немедленно возвращается в командную строку, это означает, что bash нашел двоичный файл и запустил его. Если он возвращает ноль, это хорошо. Если он возвращает ненулевое значение, это очень странно. но его все равно нужно было запустить, чтобы вернуть ненулевое значение. Пока оболочка не выдает ошибку «команда не найдена» или «отказано в доступе», все хорошо с точки зрения исполняемого файла.
EDIT: спасибо, Эшвартс, это отвечает моему любопытству. Однако я не слишком волновался, так как не слишком много читаю в выводе `file`.
«UNIX проста и понятна», — Деннис Ритчи, «GNU — это не UNIX», — Ричард Столлман
как я могу отключить PIE и использовать старый исполняемый файл
Почему вы хотите это сделать? Что вообще для вас значит «файл»? Просто запустите файл в командной строке!
Отключение PIE не улучшит работу программы, но сделает ее менее безопасной.
Но если вы действительно хотите сделать себя менее безопасным, справочная страница gcc описывает, как это сделать. Если вы занимаетесь разработкой на C++, возможно, вам следует хотя бы немного ознакомиться с тем, как работает компилятор.
Я пытался объяснить, почему вы получили результат, которого не ожидали. Я не говорю, что результат плохой.
Правильно управлять репозиториями AUR – aurpublish (теперь это отдельный инструмент)
Почему вы хотите это сделать? Что вообще для вас значит «файл»? Просто запустите файл в командной строке!
Отключение PIE не улучшит работу программы, только сделает ее менее безопасной.
.
Я пытался объясните, почему вы получили результат, которого не ожидали. Я не говорю, что результат плохой.
В настоящее время я делаю старую команду, чтобы ее можно было запускать при двойном щелчке, на этот раз у меня нет хорошего способа решить эту проблему.
Вам неоднократно говорили, что это просто неправда. Ни исполняемые файлы PIE, ни исполняемые файлы, отличные от PIE, ничего не делают при двойном щелчке, или же они оба делают, но вы никогда не узнаете, потому что вы запускали его вне командной строки, и поэтому все сообщения об ошибках и состоянии были удалены.
Если программа *окажется* программой с графическим интерфейсом, то она либо создаст этот графический интерфейс, и все в порядке, либо не создаст графический интерфейс, и вам нужно будет запустить ее из командной строки, чтобы выяснить, почему.
Не разрабатывайте программы из меню двойного щелчка файлового браузера. Это просто сделает вас несчастным.
Правильно управлять репозиториями AUR – aurpublish (теперь это отдельный инструмент)
В настоящее время я делаю старую команду, чтобы ее можно было запускать при двойном щелчке, на этот раз у меня нет хорошего способа решить эту проблему.
Пожалуйста, сначала попробуйте по-настоящему выслушать все, что вам говорят. Отключение PIE не приведет к тому, что ваш двоичный файл будет работать по-другому при щелчке в файловом менеджере.
«UNIX проста и понятна», — Деннис Ритчи, «GNU — это не UNIX», — Ричард Столлман
Вам неоднократно говорили, что это просто неправда. Ни исполняемые файлы PIE, ни исполняемые файлы, отличные от PIE, ничего не делают при двойном щелчке, или же они оба делают, но вы никогда не узнаете, потому что вы запускали его вне командной строки, и поэтому все сообщения об ошибках и состоянии были удалены.
Если программа *окажется* программой с графическим интерфейсом, то она либо создаст этот графический интерфейс, и все в порядке, либо не создаст графический интерфейс, и вам нужно будет запустить ее из командной строки, чтобы выяснить почему.
Не разрабатывайте программы из меню двойного щелчка файлового браузера. Это просто сделает вас несчастным.
Может быть и так, раньше я разрабатывал его в Windows и только начал разрабатывать под Linux. Это старая привычка.
Может быть и так, раньше я разрабатывал его в Windows и только начал разрабатывать под Linux. Это старая привычка.
Если вы ожидаете, что окно консоли откроется в стиле Windows, просто вернет ноль и снова исчезнет, вы ожидаете не того, чего хотите. Даже в консоли вам нужно будет провести некоторое тестирование, действительно ли она вернула ноль. Различные способы выражения НЕТ в Баше, возможно.
Несмотря на то, что точка зрения Эшарца хороша, я думаю, что она несколько не связана с реальной проблемой.Вы *думаете*, что ваш двоичный файл не запускается при нажатии на него, но проблема в том, что нет способа отличить, запускается ли он при нажатии в файловом менеджере: что вы *ожидаете* от него? Нет ничего плохого в опубликованном вами коде test.c - это приведет к совершенно правильному двоичному файлу, который будет запускаться из файлового менеджера: он просто абсолютно ничего не сделает (поэтому вы, кажется, ошибочно интерпретируете это как не выполняющееся). < /p>
«UNIX проста и понятна», — Деннис Ритчи, «GNU — это не UNIX», — Ричард Столлман
В настоящее время я делаю старую команду, чтобы ее можно было запускать при двойном щелчке, на этот раз у меня нет хорошего способа решить эту проблему.
Пожалуйста, сначала попробуйте по-настоящему выслушать все, что вам говорят. Отключение PIE не приведет к тому, что ваш двоичный файл будет работать по-другому при щелчке в файловом менеджере.
test.c — это образец, у меня есть другая программа с графическим интерфейсом. хочу спросить , сам ли метод определения типа файла доведен или реализован через другие программы, можно ли решить эту проблему сменой файлового менеджера
Несмотря на то, что точка зрения Эшарца хороша, я думаю, что она несколько не связана с реальной проблемой. Вы *думаете*, что ваш двоичный файл не запускается при нажатии на него, но проблема в том, что нет способа отличить, запускается ли он при нажатии в файловом менеджере: что вы *ожидаете* от него? Нет ничего плохого в опубликованном вами коде test.c - это приведет к совершенно правильному двоичному файлу, который будет запускаться из файлового менеджера: он просто абсолютно ничего не сделает (поэтому вы, кажется, ошибочно интерпретируете это как не выполняющееся). < /p>
Он действительно не запустился, потому что в нем была подсказка: "Невозможно отобразить "myexecutable", не совсем не отвечает, и у меня были другие программы с графическим интерфейсом, которые действительно не могли быть выполнены.
test.c — это образец, у меня есть другая программа с графическим интерфейсом.
Если вам нужна помощь с этой другой программой, вам придется рассказать нам о ней подробнее, о чем я и спрашивал в своем первом сообщении в этой теме.
Хочу спросить, является ли метод определения типа файла самодельным или реализуется через другие программы, можно ли решить эту проблему сменой файлового менеджера
Извините, я думаю, здесь может быть языковой барьер. Я не могу ничего понять из этого, кроме самого конца: нет, я не думаю, что использование другого файлового менеджера поможет.
Если одна из этих программ с графическим интерфейсом не запускается из файлового менеджера, сначала проверьте, запускаются ли они из терминала. Я подозреваю, что в первую очередь просто проблемы с вашей программой с графическим интерфейсом: если она вообще не запускается, нет смысла пытаться изменить файловый менеджер. При запуске из терминала он может выдавать полезный вывод об ошибке, объясняющий, почему он не может быть запущен — при запуске из файлового менеджера он не может этого сделать.
«UNIX проста и понятна», — Деннис Ритчи, «GNU — это не UNIX», — Ричард Столлман
test.c — это образец, у меня есть другая программа с графическим интерфейсом.
Если вам нужна помощь с этой другой программой, вам придется рассказать нам о ней подробнее, о чем я и спрашивал в своем первом сообщении в этой теме.
Хочу спросить, является ли метод определения типа файла самодельным или реализуется через другие программы, можно ли решить эту проблему сменой файлового менеджера
Извините, я думаю, здесь может быть языковой барьер. Я не могу ничего понять из этого, кроме самого конца: нет, я не думаю, что использование другого файлового менеджера поможет.
Если одна из этих программ с графическим интерфейсом не запускается из файлового менеджера, сначала проверьте, запускаются ли они из терминала. Я подозреваю, что в первую очередь просто проблемы с вашей программой с графическим интерфейсом: если она вообще не запускается, нет смысла пытаться изменить файловый менеджер. При запуске из терминала он может выдавать полезный вывод об ошибке, объясняющий, почему он не может быть запущен — при запуске из файлового менеджера он не может этого сделать.
У меня есть две программы, они называются test.c и 01_Hello World
gcc test.c
./a.out могут работать
но не могут работать в визуальном файловом менеджере, он показывает окно с надписью «не удалось отобразить a.out. Не установлено приложение для файлов« общей библиотеки ».»,
gcc -no-pie test.c
./a.out может работать< br />его также можно запустить в визуальном файловом менеджере, потому что он ничего не показывает.
01_Hello World — это программа с графическим интерфейсом
./01_Hello World может работать и отображать собственный графический интерфейс
он также может работать в визуальном файловом менеджере, потому что он может отображать свой собственный графический интерфейс
вот и все, визуальный файловый менеджер не может выполняться с помощью PIE,
gcc test.c и gcc -no-pie test.c создают два файла с разными значками
Общие библиотеки — это скомпилированный код, предназначенный для совместного использования несколькими различными программами. Они распространяются в виде файлов .so в /usr/lib/ .
Библиотека экспортирует символы, которые являются скомпилированными версиями функций, классов и переменных. Библиотека имеет имя SONAME, которое включает номер версии. Эта версия SONAME не обязательно совпадает с общедоступным номером версии.Программа компилируется с заданной версией библиотеки SONAME. Если какой-либо из символов удален или изменен, то необходимо изменить номер версии, что вынуждает перекомпилировать любые пакеты, использующие эту библиотеку, для новой версии. Номера версий обычно устанавливаются восходящей ветвью, и мы следуем им в именах наших двоичных пакетов, называемых номером ABI, но иногда восходящие потоки не используют разумные номера версий, и упаковщикам приходится хранить отдельные номера версий.
Библиотеки обычно распространяются вышестоящей компанией в виде отдельных выпусков. Иногда они распространяются как часть программы. В этом случае их можно включить в бинарный пакет вместе с программой (это называется бандлингом), если вы не предполагаете, что какие-либо другие программы будут использовать библиотеку, чаще всего их следует разбивать на отдельные бинарные пакеты.
Сами библиотеки помещаются в двоичный пакет с именем libfoo1, где foo — имя библиотеки, а 1 — версия из СОНАМЭ. Файлы разработки из пакета, такие как файлы заголовков, необходимые для компиляции программ с использованием библиотеки, помещаются в пакет с именем libfoo-dev .
8.1. Пример¶
В качестве примера мы будем использовать libnova:
Чтобы найти SONAME библиотеки, выполните:
SONAME — это libnova-0.12.so.2, что соответствует имени файла (обычно это так, но не всегда). Здесь upstream поместил номер версии upstream как часть SONAME и присвоил ему версию ABI 2 . Имена пакетов библиотек должны следовать за SONAME библиотеки, которую они содержат. Бинарный пакет библиотеки называется libnova-0.12-2, где libnova-0.12 — это имя библиотеки, а 2 — наш номер ABI.< /p>
Если вышестоящий поставщик внесет несовместимые изменения в свою библиотеку, им придется изменить версию SONAME, а нам придется переименовать нашу библиотеку. Любые другие пакеты, использующие наш библиотечный пакет, необходимо будет перекомпилировать для новой версии, это называется переходом и может потребовать некоторых усилий. Надеемся, что наш номер ABI продолжит совпадать с SONAME исходной ветки, но иногда они вносят несовместимость, не меняя номер своей версии, и нам нужно будет изменить наш.
Глядя на файл debian/libnova-0.12-2.install, мы видим, что он включает два файла:
Последняя — это фактическая библиотека с дополнительным и дополнительным номером версии. Первый — это символическая ссылка, которая указывает на реальную библиотеку. Символическая ссылка — это то, что будут искать программы, использующие библиотеку, запущенным программам не важен дополнительный номер версии.
libnova-dev.install включает все файлы, необходимые для компиляции программы с помощью этой библиотеки. Заголовочные файлы, двоичный файл конфигурации, файл .la libtool и libnova.so, который является еще одной символической ссылкой, указывающей на библиотеку, программы, компилируемые для библиотеки, не заботятся об основных номер версии (хотя двоичный файл, в который они компилируются, будет).
.la Файлы libtool необходимы в некоторых системах, отличных от Linux, с плохой поддержкой библиотек, но обычно вызывают больше проблем, чем решают в системах Debian. Текущая цель Debian — удалить файлы .la, и мы должны помочь в этом.
8.2. Статические библиотеки¶
Пакет -dev также включает usr/lib/libnova.a . Это статическая библиотека, альтернатива разделяемой библиотеке. Любая программа, скомпилированная со статической библиотекой, будет включать в себя каталог кода. Это избавляет от беспокойства о бинарной совместимости библиотеки. Однако это также означает, что любые ошибки, включая проблемы с безопасностью, не будут обновлены вместе с библиотекой до тех пор, пока программа не будет перекомпилирована. По этой причине программы, использующие статические библиотеки, не рекомендуются.
8.3. Файлы символов¶
Когда пакет собирается для библиотеки, механизм shlibs добавит зависимость пакета от этой библиотеки. Вот почему большинство программ будут иметь Depends: $ в debian/control. Это заменяется зависимостями библиотеки во время сборки. Однако shlibs может сделать его зависимым только от основного номера версии ABI, 2 в нашем примере с libnova, поэтому, если новые символы будут добавлены в libnova 2.1, программа, использующая эти символы, все еще может быть установлена против libnova ABI 2.0, которая затем произойдет сбой.
Чтобы сделать зависимости библиотек более точными, мы храним файлы .symbols, в которых перечислены все символы в библиотеке и версия, в которой они появились.
У libnova нет файла символов, поэтому мы можем его создать. Начните с компиляции пакета:
Команда -nc завершит компиляцию в конце без удаления встроенных файлов. Перейдите к сборке и запустите dpkg-gensymbols для пакета библиотеки:
Это создает файл различий, который вы можете применить самостоятельно:
Что создаст файл с именем, похожим на dpkg-gensymbolsnY_WWI, в котором перечислены все символы. В нем также указана текущая версия пакета.Мы можем удалить версию упаковки из списка в файле символов, потому что новые символы обычно добавляются не новыми версиями упаковки, а разработчиками основной ветки разработки:
Теперь переместите файл на его место, зафиксируйте и выполните тестовую сборку:
Если он успешно компилируется, файл символов правильный. В следующей основной версии libnova вы снова запустите dpkg-gensymbols, и он даст diff для обновления файла символов.
8.4. Файлы символов библиотеки C++¶
C++ имеет еще более строгие стандарты двоичной совместимости, чем C. Команда Debian Qt/KDE поддерживает некоторые сценарии для решения этой проблемы. См. их страницу Работа с файлами символов, чтобы узнать, как их использовать.
8.5. Дополнительная литература¶
Дзюнъити Уэкава в Руководстве по упаковке библиотеки Debian рассматривает эту тему более подробно.
Читайте также: