commit -m "better"
В батле "статическая vs. динамическая линковка" есть один фактор, про который особо никто не рассказывает, ну или мне просто не встречалось раньше. Это эстетика! Причем не простая эстетика, что, дескать, в случае статической линковки по всей fs не валяются…
#gold
Обещал пример разделения статических библиотек, которое никогда бы не смогло случиться во внешнем мире с .so
Как я уже рассказывал, у меня есть реализация функций backtrace(), на самом деле, их там ажно три штуки:
https://github.com/pg83/ix/tree/main/pkgs/lib/execinfo - у меня лежит 4 их реализации:
1) https://github.com/pg83/ix/tree/main/pkgs/lib/execinfo/fake
Это просто реализация, которая ничего не делает(имеет право!), с которой как раз и сломался eternal terminal #et
2) https://github.com/pg83/ix/tree/main/pkgs/lib/execinfo/fp
Это реализация, цельнотянутая из BSD мира, https://www.freshports.org/devel/libexecinfo, широко известна в узких кругах non-glibc linux.
Она содержит фатальный недостаток - если ее позвать из кода, который на x86_64 скомпилен с флагами компилятора по умолчанию(без -fno-omit-frame-pointer), она приводит к падению программы, потому что она падает без frame pointer.
3) https://github.com/pg83/ix/tree/main/pkgs/lib/execinfo/itanium
Эту реализацию наговнокодил я сам, поверх itanium abi для раскрутки стека. Он всегда доступен в программах на C++, а у меня используется #tcmalloc, поэтому по коду это для меня бесплатно. Собственно, она у меня стоит по умолчанию, с возможностью переопределения - https://github.com/pg83/ix/blob/main/pkgs/lib/execinfo/ix.sh Это полезно в цепочке bootstrap, чтобы для первого компилятора собирать поменьше кода - https://github.com/pg83/ix/blob/main/pkgs/bld/boot/8/clang/base/ix.sh
4) https://github.com/pg83/ix/tree/main/pkgs/lib/execinfo/unwind
И реализация поверх библиотеки libunwind от HP. Это старая, известная, библиотека, одна из трех более-менее известных реализаций itanium abi(наряду с stdc++ от gnu, и libunwind от проекта llvm)
Тут очень важно отметить, что, в двух последних случаях я реализовал только функцию backtrace(), одну из трех нужных. Потому что я ленивая жопа, да.
Что бы я сделал, если бы делал .so для внешнего мира? Я бы скопировал две оставшиеся функции из пункта 2) к себе в проект, и был бы счастлив.
Но, в случае статической линковки я могу себе позволить иметь сколько угодно артефактов любой степени всратости, лишь бы конечный продукт работал.
Поэтому я делаю финт ушами - https://github.com/pg83/ix/blob/main/pkgs/lib/execinfo/format/ix.sh
Я пересобираю библиотеку из пункта 2, но с указанием, что в .a файле нужно переименовать функцию backtrace(). На выходе я имею библиотеку, в которой есть функции xxx_backtrace(), backtrace_symbols(), и backtrace_symbols_fd()
Если ее скомпоновать с библиотекой 3), или библиотекой 4), то я получу на выходе годный артефакт. Линкер же выкинет при линковке ненужную функцию xxx_backtrace(), и все будет по красоте!
https://github.com/pg83/ix/blob/main/pkgs/lib/execinfo/itanium/ix.sh#L6
https://github.com/pg83/ix/blob/main/pkgs/lib/execinfo/unwind/ix.sh#L6
Собственно, я так и делаю.
В мире динамической линковки это было бы весьма странно.
В случае же статической сборки, если не особенно сильно принюхиваться, то норм, ну и я, заодно, сэкономил себе кучу времени и усилий.
Обещал пример разделения статических библиотек, которое никогда бы не смогло случиться во внешнем мире с .so
Как я уже рассказывал, у меня есть реализация функций backtrace(), на самом деле, их там ажно три штуки:
#include <execinfo.h>
int backtrace(void **buffer, int size);
char **backtrace_symbols(void *const *
buffer, int size);
void backtrace_symbols_fd(void *const *
buffer, int size, int fd);
https://github.com/pg83/ix/tree/main/pkgs/lib/execinfo - у меня лежит 4 их реализации:
1) https://github.com/pg83/ix/tree/main/pkgs/lib/execinfo/fake
Это просто реализация, которая ничего не делает(имеет право!), с которой как раз и сломался eternal terminal #et
2) https://github.com/pg83/ix/tree/main/pkgs/lib/execinfo/fp
Это реализация, цельнотянутая из BSD мира, https://www.freshports.org/devel/libexecinfo, широко известна в узких кругах non-glibc linux.
Она содержит фатальный недостаток - если ее позвать из кода, который на x86_64 скомпилен с флагами компилятора по умолчанию(без -fno-omit-frame-pointer), она приводит к падению программы, потому что она падает без frame pointer.
3) https://github.com/pg83/ix/tree/main/pkgs/lib/execinfo/itanium
Эту реализацию наговнокодил я сам, поверх itanium abi для раскрутки стека. Он всегда доступен в программах на C++, а у меня используется #tcmalloc, поэтому по коду это для меня бесплатно. Собственно, она у меня стоит по умолчанию, с возможностью переопределения - https://github.com/pg83/ix/blob/main/pkgs/lib/execinfo/ix.sh Это полезно в цепочке bootstrap, чтобы для первого компилятора собирать поменьше кода - https://github.com/pg83/ix/blob/main/pkgs/bld/boot/8/clang/base/ix.sh
4) https://github.com/pg83/ix/tree/main/pkgs/lib/execinfo/unwind
И реализация поверх библиотеки libunwind от HP. Это старая, известная, библиотека, одна из трех более-менее известных реализаций itanium abi(наряду с stdc++ от gnu, и libunwind от проекта llvm)
Тут очень важно отметить, что, в двух последних случаях я реализовал только функцию backtrace(), одну из трех нужных. Потому что я ленивая жопа, да.
Что бы я сделал, если бы делал .so для внешнего мира? Я бы скопировал две оставшиеся функции из пункта 2) к себе в проект, и был бы счастлив.
Но, в случае статической линковки я могу себе позволить иметь сколько угодно артефактов любой степени всратости, лишь бы конечный продукт работал.
Поэтому я делаю финт ушами - https://github.com/pg83/ix/blob/main/pkgs/lib/execinfo/format/ix.sh
Я пересобираю библиотеку из пункта 2, но с указанием, что в .a файле нужно переименовать функцию backtrace(). На выходе я имею библиотеку, в которой есть функции xxx_backtrace(), backtrace_symbols(), и backtrace_symbols_fd()
Если ее скомпоновать с библиотекой 3), или библиотекой 4), то я получу на выходе годный артефакт. Линкер же выкинет при линковке ненужную функцию xxx_backtrace(), и все будет по красоте!
https://github.com/pg83/ix/blob/main/pkgs/lib/execinfo/itanium/ix.sh#L6
https://github.com/pg83/ix/blob/main/pkgs/lib/execinfo/unwind/ix.sh#L6
Собственно, я так и делаю.
В мире динамической линковки это было бы весьма странно.
В случае же статической сборки, если не особенно сильно принюхиваться, то норм, ну и я, заодно, сэкономил себе кучу времени и усилий.
GitHub
ix/pkgs/lib/execinfo at main · pg83/ix
ix package manager. Contribute to pg83/ix development by creating an account on GitHub.
👍8🤔4🔥3