LINUX.ORG.RU

plibsys — кросс-платформенная системная библиотека на C

 , , ,


10

7

Недавно ко мне обратились с вопросом, не хочу ли я написать новость об одной из разрабатываемых библиотек (plibsys). В принципе, я не против, поэтому эксклюзивно для LOR.

Что такое plibsys?

plibsys — это кросс-платформенная системная библиотека, написанная на чистом C. Основной упор был изначально сделан на портируемость и поддержку широкого спектра компиляторов. Для достижения этих целей у библиотеки отсутствуют (небольшим исключением является SCO OpenServer 5 ввиду отсутствия на ней потоков) какие-либо зависимости — используются только те вызовы, которые доступны в целевой ОС. Также никакого ассемблера и использования прочих недокументированных возможностей. Для сборки нужен только рабочий компилятор и CMake.

Изначально библиотека писалась для запуска потоков и работы с сокетами, но постепенно функционал расширялся по мере необходимости. На данный момент есть следующий функционал:

  • Платформо-независимые типы данных
  • Потоки и средства синхронизации: мьютексы, условные переменные, блокировки чтения-записи, спинлоки, атомарные операции
  • Межпроцессное взаимодействие: семафоры, разделяемая память, кольцевой буфер
  • Сокеты (UDP, TCP) с поддержкой IPv4 и IPv6
  • Хэш-функции: MD5, SHA-1, SHA-2, SHA-3, GOST (R 34.11-94)
  • Бинарные деревья: несбалансированное, красно-черное, АВЛ
  • Загрузка разделяемых библиотек
  • Работа с памятью: mmap, установка собственного аллокатора
  • Замер времени исполнения (по возможности — в высоком разрешении)
  • Базовая работа с файлами и директориями
  • Парсер файлов INI
  • Макросы для определения архитектуры ЦПУ, ОС и компилятора
  • Различные вспомогательные структуры данных типа связанного списка, хэш-таблицы, обработка строк

На все есть документация.

Поддерживаемые платформы и компиляторы

Абсолютно все модули покрыты Unit-тестами. Есть интеграция с CI (Travis, AppVeyor), где прогоняется большое число разнообразных конфигураций. Также для улучшения качества кода и снижения числа ошибок используется сервис статического анализа кода Coverity. Для оценки покрытия тестами используется Codecov.

На данный момент поддерживаются следующие платформы:

  • GNU/Linux
  • macOS
  • Windows, Cygwin, MSYS
  • FreeBSD, NetBSD, OpenBSD, DragonFlyBSD
  • Solaris
  • AIX
  • HP-UX
  • Tru64
  • OpenVMS
  • OS/2
  • IRIX
  • QNX Neutrino, BlackBerry 10
  • UnixWare 7
  • SCO OpenServer 5
  • Haiku
  • Syllable
  • BeOS

Также работоспособность библиотеки проверена на следующих компиляторах и архитектурах:

  • MSVC (x86, x64) 2003 и выше
  • MinGW (x86, x64)
  • Open Watcom (x86)
  • Borland (x86)
  • GCC (x86, x64, PPC32be, PPC64be/le, IA-64/32, IA-64, Alpha, HPPA2.0-32, MIPS32, AArch32, SPARCv9)
  • Clang (x86, x64, PPC32be)
  • Intel (x86, x64)
  • QCC (x86, AArch32)
  • Oracle Solaris Studio (x86, x64, SPARCv9)
  • MIPSpro (MIPS32)
  • XL C (PPC64le)
  • DEC C (Alpha)
  • PGI (x86, x64)
  • Cray (x64)

Особенности работы библиотеки, сборки и тестирования на разных платформах с разными компиляторами подробно рассмотрены в Wiki.

Что дальше?

Библиотека по-тихоньку продолжает развиваться, хотя, к сожалению, свободного времени не так много. Например, недавно была добавлена поддержка для систем Cray.

Планирую сделать родной пакет для Debian. В общем-то, он готов, надо только протестировать. В связи с этим, если кто-то сможет выступить в качестве поручителя (он же sponsor в терминологии Debian) для проверки и заливки пакета — буду рад.

Если у кого-то есть доступ к каким-то машинам и компиляторам, которых нету в списке, и есть возможность организовать удаленный доступ для портирования — буду рад. В данный момент было бы интересно проверить под HP-UX с компилятором HP C/aC++. Или на машинах уровня BlueGene с компилятором IBM XL. Или на AmigaOS.

Пожелания, комментарии (конструктивные и не очень) и поток сознания (в меру) по библиотеке приветствуются :)

>>> Подробности

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

ибо в жизни не поверю, что у тебя есть ВСЕ ОС, заявленные в совместимости

У меня лично физически - нет, но доступ есть на все.

но при этом ты НЕ ДЕЛАЕШЬ что-то для основных платформ

Я делал ровно тот функционал, который был нужен.

Не понимаю, почему вы считаете, что у людей нет проблем с портируемостью софта. Если их нет у вас - то не значит, что нету у других. Не стоит судить только по своим потребностям.

HardCode ()
Ответ на: комментарий от waker

использовать автотулсы на windows ничем не лучше, чем cmake на линуксах

Что лучше использовать и там, и там? Я начинающий разработчик, студент, у меня нет свободного времени поддерживать >1 системы сборки в проекте. Дайте одну, самую лучшую. Заодно krotozer подскажете.

половина софта не собирается через предоставленные cmakelists на линуксе

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

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

Видишь - код лажает на основной же платформе, но зато IRIX поддерживается! :) Глупо и смешно.

Код работает. То, что у разработчиков glibc зачесалась левая пятка и они объявили это устаревшим - ну, пусть будет так. От этого код не перестает работать.

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

PShm гарантирует, что в разных процессах p_shm_get_address вернёт один и тот же указатель? Если структура данных хранит абсолютные указатели, а не ptrdiff_t, процесс, который не создавал структуру, а получил её через SHM, упадёт.

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

нет, я имел ввиду что это давно исправили.

Исправили тогда, когда уже было поздно. Ложка к обеду нужна.

HardCode ()
Ответ на: комментарий от kirk_johnson

man queue

Читал, пользовался, как и linux/list.h. На контейнеры не тянет, максимум - заготовки для контейнеров. Избыточность в интерфейсе, формальное UB в реализации. Но лучшее что есть, да.

На контейнеры тянут всякие GList, но с ними наверно понятно что не так.

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

Мне, в общем-то, похрен, хотя... Что за торкнутые хипстеры такие, что компилят из под юзера? Где таких разводят?

Собирал проект из под CMake, писал под него правила сборки. Всё осиливалось вполне корректно. Ну не нравится CMake и всё тут. Не вижу смысла им пользоваться.

krotozer ()
Ответ на: комментарий от Deleted

Указатель ret выделяется на стеке, затем под структуру выделяется память. Другие поля инициализируют строками выше, func - нет. В зависимости от поведения p_malloc0, вызов функции - либо разыменование NULL, либо переход по адресу из stack garbage.

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

Читаю уже третий абзац, так и не понял для чего библиотека

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

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

Можно не изобретать велосипеды, и не летать в магазин на вертолёте, а освоить Automake и Configure.

Именно поэтому уже даже разработчики GLib и того же Gnome от этого отказываются?

Так, пойдём тогда по порядку с самого начала. Есть архив plibsys-master.zip . Распаковываем, заходим внутрь, делаем cmake ./src, видим это:

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

mkdir plibsys-build
cd ./plibsys-build
cmake ../plibsys
make
Директория plibsys-build в данном случае на одном уровне с директорией plibsys.

p.S. Дальше портянки не читал, так как вы изначально сделали неправильно, а потом пытались это починить то, что не ломалось.

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

Пробежался по man cmake — ничего не увидел про то, в каком каталоге собирать правильно, а в каком — нет.

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

Мне почему-то кажется, что base.func здесь не инициализирован. Что я пропустил?

Это внутренняя реализация, посмотрите внешнюю, там должно быть.

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

Читал, пользовался, как и linux/list.h. На контейнеры не тянет, максимум - заготовки для контейнеров.

Generic typesafe list? Да. Что тебе ещё нужно, чтобы назвать это «контейнером»?

Избыточность в интерфейсе

Ты можешь сделать проще на C?

формальное UB в реализации

Какое?

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

plibsys vs другие реализации стандартной библиотеки.

Честно говоря, даже не думал это делать. Это не реализация стандартной библиотеки, все-таки.

HardCode ()
Ответ на: комментарий от kirk_johnson

Когда в автолулзах достаточно сказать
[code=bash]$ ./configure --help[/code]
чтобы получить полный help по всем опциям сборки, в cmake нужно творить какой-то фееричный трешак с gui/tui интерфейсами.

+50! Иногда проще наваять help.

Кстати, доводилось делать сборку через SFX-архив на виндах. Он распаковывал первичную структуру, спрашивал, каким компилятором собирать, если находил хоть один: VC и MinGW в двух вариантах разрядности (MinGW x86_64 существует, если что), далее разворачивал окружение для сборки при помощи всё тех же Automake-скриптов, что применяются для Posix-совместимых ОС. Далее дело техники. Но на то она и «винда», чтобы применять принцип «всё своё ношу с собой». А когда там было иначе?

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

Что можно хотеть делать с ipc памятью без структур данных? Адреса указателей разные.

Причем тут разные адреса в виртуальном пространстве процесса? Содержимое одинаковым будет, то есть данные между процессами расшариваются. Отсюда и название.

HardCode ()
Ответ на: комментарий от kirk_johnson

apr

dpdk

Они вообще где-то используются помимо проектов их же организаций? Ну и по существу - апачевыми продуктами пользуются либо по инерциии, либо в пределах своей религии. Вторая штука кажется комбайном, но там чёткая цель и предел поддержжки (серверное и сетевое обборудование).

boost (плюсы страдают от той же проблемы)

И node_modules тоже много места занимает, чего теперь? Это другой язык. У крестов много своих проблем, отличающиихся от данного и если ты пытаешься щеголятть тут знаниями, то такое надо бы пониматть.

glib

Тут спорить не буду, на самом деле.

libc (да-да, в стандартной библиотеке языка очень много мусора, которому там не место)

В __ЛЮБОМ__ популярном языке общего назначения будет куча всего в его стандарной библиотеке. И что ты этим хотел сказать?

openssl (помимо собственно SSL содержит огромную кучу кода, вроде собственных реализаций md5, crc32 и тех же многострадальных хеш-таблиц)

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

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

PShm гарантирует, что в разных процессах p_shm_get_address вернёт один и тот же указатель? Если структура данных хранит абсолютные указатели, а не ptrdiff_t, процесс, который не создавал структуру, а получил её через SHM, упадёт.

Это весьма странный способ использования shared memory. А если один из процессов уже использовал то виртуальное пространство, по которому другой процесс открыл память?

HardCode ()
Ответ на: комментарий от Softwayer

Пробежался по man cmake — ничего не увидел про то, в каком каталоге собирать правильно, а в каком — нет.

В любом. Но правило хорошего тона нынче - out-of-source сборки. Смысл засорять исходники?

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

Я думаю что все сводится к тому что просто написали портируемый код и регулярно гоняют юнит-тесты в QEMU. Не думаю что кто-то сильно напрягается

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

Они вообще где-то используются помимо проектов их же организаций? Ну и по существу - апачевыми продуктами пользуются либо по инерциии, либо в пределах своей религии. Вторая штука кажется комбайном, но там чёткая цель и предел поддержжки (серверное и сетевое обборудование).

Это отменяет наличие ini парсеров в библиотеке или что?

И node_modules тоже много места занимает, чего теперь? Это другой язык. У крестов много своих проблем, отличающиихся от данного и если ты пытаешься щеголятть тут знаниями, то такое надо бы пониматть.

Каких проблем? Какие проблемы пытались решить авторы boost, сделав адовый комбайн?

В __ЛЮБОМ__ популярном языке общего назначения будет куча всего в его стандарной библиотеке. И что ты этим хотел сказать?

Например?

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

В том, что хеширование можно реализовать модулем из нескольких строк кода. И включить в свой проект. Но в C нет модулей, поэтому все, кому нужны хеши, либо делают их сами, либо тащат за собой какой-нибудь gcrypt / openssl.

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

По том что ваши структуры данных построены на указателях. Т.е. Не пригодны для использования в shared мемори вашей-же библиотеки. Т.е толку от них мало учитывая что есть posix реализации или c++ контейнеры (которые еще и шустрее).

Библиотека лично ваш костыль. Как и костыли других разработчиков. Я лично предпочту зоопарк библиотек с обертками каждую из которых можно заменить/перепилить

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

Мне почему-то кажется, что base.func здесь не инициализирован. Что я пропустил?

Хотя, возможно, да. Это, честно говоря, затычка на случай отсутствия потоков в системе, но пока таких случаев не было. Спасибо, поправлю!

HardCode ()

Тут многие боятся musl и Alpine linux, чего уж говорить о других не гнушных либах...

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

По том что ваши структуры данных построены на указателях. Т.е. Не пригодны для использования в shared мемори вашей-же библиотеки. Т.е толку от них мало учитывая что есть posix реализации или c++ контейнеры (которые еще и шустрее).

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

Библиотека лично ваш костыль. Как и костыли других разработчиков. Я лично предпочту зоопарк библиотек с обертками каждую из которых можно заменить/перепилить

Да все вокруг одни костыли и мир жесток :)

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

У вас проблемы со сборкой потому, что вы неверно используете CMake.

Охотно верю.

Попробуйте следующую последовательность

Попробовал. Чтоб не цитировать портянку, даю сжатый вывод:

== Build configuration ==

Platfrom:               linux
Compiler:               gcc
Address model:          64 bit

Thread model:           posix
RW lock model:          posix
IPC model:              posix
DIR model:              posix
Library loader model:   posix
Time profiler model:    posix
Atomic model:           c11

Platform defines:       -D_REENTRANT
Platform CFLAGS:        -fvisibility=hidden
Platform LDFLAGS:
Platform libraries:     -pthread;rt;dl

Build static library:   ON
Coverage support:       OFF
Visibility:             ON


-- The CXX compiler identification is GNU 4.8.0
-- Boost version: 1.59.0

CMake Error at tests/CMakeLists.txt:57 (target_compile_definitions):
  target_compile_definitions called with incorrect number of arguments
Call Stack (most recent call first):
  tests/CMakeLists.txt:[NUMBER] (plibsys_add_test_executable)

== Tests configuration ==

Build static tests:     OFF
Boost directory:

-- Configuring incomplete, errors occurred!

Ошибка циклична, где NUMBER были подряд от 69 до 95.

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

Что лучше использовать и там, и там?

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

я даже под линукс 2 отдельные системы сборки параллельно использую, одну для разработки/отладки (premake5), другую для конечных юзеров (autotools).

если взять что-то одно - придется чем-то жертвовать.

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

Мне, в общем-то, похрен, хотя... Что за торкнутые хипстеры такие, что компилят из под юзера? Где таких разводят?

да практически все.. зачем компилять от рута?

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

если взять что-то одно - придется чем-то жертвовать.

Порядок без жертв? Это — утопия.

krotozer ()
Ответ на: комментарий от HardCode

А если один из процессов уже использовал то виртуальное пространство, по которому другой процесс открыл память?

Вот именно!

Теперь процесс (2) берёт из shared memory PList * whatever = p_shm_get_address(something), который не равен исходному указателю в процессе (1), вызывает p_list_last(whatever), а тот делает:

cur = list; // всё хорошо
cur->next != NULL; // всё равно всё хорошо
cur = cur->next; // адрес из первого процесса неверен во втором
cur->next != NULL; // segmentation fault либо дальшейшее повреждение памяти через возвращённый cur

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

Например?

С++, Java, C#, все их производные.

Каких проблем? Какие проблемы пытались решить авторы boost, сделав адовый комбайн?

Не уверен, проблема недостатка комбайнов? Я избегаю использования его в разработка и приложений на нём.

В том, что хеширование можно реализовать модулем из нескольких строк кода. И включить в свой проект. Но в C нет модулей, поэтому всем, кому нужны хеши, либо делают их сами, либо тащат за собой какой-нибудь gcrypt / openssl.

Ну так пусть используют только либы с хешами. Они наверняка есть.

Это отменяет наличие ini парсеров в библиотеке или что?

Это уменьшает ценность приведённого примера, потому что если это наколенное ненужно, которым никто не пользуется, то и на экосистему оно никак не влияет.

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

Как минимум затем, чтобы не писать по жизни все фразы с префиксом «sudo ». Сборка работает в закрытом окружении, которое в любой момент можно «дропнуть» и накатить по-новой. Можно, конечно, принимать душ в одежде, завёрнутой в целофан, но предпочитаю удобство)

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

Как минимум затем, чтобы не писать по жизни все фразы с префиксом «sudo ».

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

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

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

HardCode ()
Ответ на: комментарий от waker

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

Когда система безопасности ОС устанавливает т.н. «мандатные метки», из под которых действует ограничение на запуск категорий ПО. Это — оборонка, тут не бывает просто... Так-то да, можно и просто из под юзера собрать, но тогда это нельзя будет даже запустить. И смена прав не поможет.

krotozer ()
Ответ на: комментарий от waker

Я бы тоже хотел работать под «нормальным» GNU/Linux, но что имеем, то имеем. Куда проще всё делать из под root-а, чтоб не мешало работе.

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

а, ну у тебя там особая ситуация. это не значит что все из под рута должны собирать :D

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

Расскажите лучше где разводят хипстеров компилирующих под рутом...

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

оборонка
система безопасности
нужно использовать sudo

От оно как бывает...

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

«ХардКод», у меня рабочий день уже пол часа как закончился. Так что исследования с библиотекой если и продолжать, то скорее завтра. Увы, пока достать «Эльбрус» в личное пользование не представляется возможным (не продаётся физлицам).

Проект у нас большой. Сводим разные версии (под разные ОС) в один набор исходников. Естественно, все системные функции выносятся в отдельную кроссплатформенную библиотеку. Решено писать обёртку операторов C++11/14 для C++98 на базе Boost-а. Она просто не компилируется при поддержке стандартов.

Тут что-то подобное САБЖ-у бы пригодилось, чтоб не цеплять «буст». Тем более, что «весит» всего три «метра» в «сорцах». Да и итоговая поддержка Эльбрус ОС была бы плюсом проекту.

krotozer ()
Ответ на: комментарий от waker

а, ну у тебя там особая ситуация. это не значит что все из под рута должны собирать :D

Не обязаны, хотя то же можно сказать и об обратной ситуации)

krotozer ()
Ответ на: комментарий от HardCode

А какая версия CMake используется?

2.8.11 — должна подходить.

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

Если удобнее, то можете открыть тикет на гитхабе или отправить информацию на почту. Очень редко, но бывает, что поведение CMake чуть отличается на разных платформах, приходится огораживаться. Поддержка Эльбруса, конечно, была бы интересна.

HardCode ()

Надеюсь API такое же годное как и описание. Порой именно такие вещи ой как нужны.

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

Что за жесть у вас там? Работал долго в оборонке, рута все как огня боялись, собиралось все юзером, даже системные вещи.

Бинарникам CC что ли присваивается?

anonymous ()

сборка с musl и gcc 6.3.0 под Linux 64 bit прошла успешно. тесты вроде все выполняются.

ну да, и CMake напрягает. проект невелик, автотулзы в нём не помешают.

Iron_Bug ★★★★ ()
Последнее исправление: Iron_Bug (всего исправлений: 1)

Основной упор был изначально сделан на портируемость
Для сборки нужен только рабочий компилятор и CMake.
портируемость
Cmake

O_O

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

Куда проще всё делать из под root-а, чтоб не мешало работе.

от рута на «нормальном GNU/Linux» лучше вообще ничего не делать, по возможности. ибо рут - это чисто административная категория и в целях безопасности сборка и запуск подавляющего большинства софта производится от не-рутовых юзеров.

Iron_Bug ★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.