Мне необходимо несколько сишных модулей скомпилировать с целью дальнейшего использования в Delphi и FreePascal. Набросал скрипт сборки. Но с таргетами беда. Я абсолютно не уверен, что выбрал их правильно. Для Win32, к примеру, не получается задействовать long double (он собирается как обычный double) и используются регистры SSE, а я их вроде не указывал. Таргеты мобильных платформ указал наобум.
set platform=%~1 set target=unknown set flags=-c -O3 if "%platform%"=="win32" ( set target=i386-pc-win32 ) else if "%platform%"=="win64" ( set target=x86_64-windows ) else if "%platform%"=="linux32" ( set target=i386-linux ) else if "%platform%"=="linux64" ( set target=x86_64-linux ) else if "%platform%"=="mac32" ( set target=i386-macos ) else if "%platform%"=="mac64" ( set target=x86_64-macos ) else if "%platform%"=="android32" ( set target=armv7-a-linux-android -march=armv7-a -mthumb ) else if "%platform%"=="android64" ( set target=aarch64-linux-android ) else if "%platform%"=="ios32" ( set target=armv7-a-apple ) else if "%platform%"=="ios64" ( set target=arm64-apple ) else ( echo error: unknown platform "%platform%" goto :done ) ... call clang -target %target% %flags% "%sourcefile%" -o"%targetfile%"
даблдевил ожил О__О
> Для Win32, к примеру, не получается задействовать long double (он собирается как обычный double)
а как по-твоему должно быть?
https://clang.llvm.org/docs/ClangCommandLineReference.html#x86
https://clang.llvm.org/docs/ClangCommandLineReference.html#long-double-flags
Suslik
Я всегда был жив :)
Faceroll
Вопрос то не только по x86.
Но окей
Делаю так:
-target i386-windows -mlong-double-80 -c -O3
clang: error: unknown argument: '-mlong-double-80'
я всё ещё жду ответа, чем тебе не нравится long double размером с double.
Suslik
Тем, что Delphi Extended занимает 10 байт
DevilDevil
> Тем, что Delphi Extended занимает 10 байт
Не используй Extended, используй типы из ctypes.pas (есть во Free Pascal) - специально для прилинкованного С.
DevilDevil
> Тем, что Delphi Extended занимает 10 байт
у меня для тебя плохие новости
rcsim
Я предлагаю построить беседу в другом ключе.
Как настроить Clang?
Suslik
Просьба не засорять тему офтопом
Спасибо
Отключить генерацию SSE-инструкций можно через флаг -mno-sse. Последнее, очевидно, верно только для x86-архитектуры.
Размер long double зависти от операционной системы и может быть равен 8 или 16 байтам. Согласно традиции для C/С++ компиляторов в Windows long double эквивалентен double чуть менее, чем на 100%. Невыровненный на границу слова базовый тип — это очень большая проблема для эффективного выполнения кода. Так размер типов по умолчанию выравнивается в большую или меньшую сторону. И далее следует очевидный вывод: для портабельности и крепкой межъязыковой дружбы никаких Extended-ов не надо. Собственно, о чем уже было сказано выше.
CgReligion
Спасибо. Но...
Как показала практика, таргет i386-windows-gnu вместо i386-windows - решает проблему long double.
Теперь образовываются другие вопросы:
DevilDevil
Таргет задаётся триплетом arch-vendor-sys-abi. Как легко заметить, в триплете четыре элемента, но один — vendor — никогда не используется и всегда опускается. Он принимается равным по умолчанию — обычно pc.
ABI — это двоичный интерфейс. Он, помимо прочего, определяет размер типов и правила передачи
параметров в функцию и возврата результата. Соглашения о вызовах — всякие cdecl, pascal,
stdcall, fastcall и прочие — все они где-то рядом находятся и имеют важно значение для правильного связывания 32-х битного кода. В архитектуре команд x86-64 ABI определяет единое соглашение о передаче параметров в функцию, но самих ABI существует два. Инструкции SSЕ там доступны всегда, а вещественные значения передаются через XMM регистры. MMX и 3DNow — это просто наборы инструкций и они никакого отношения к соглашению о вызовах не имеют. Кроме того, ни один современный компилятор не будет без команды генерировать код с их участием, потому как они относятся к сильному легаси.
В указанном таргете gnu как раз и является одним из возможных вариантов ABI. При этом компиляция с ним, скорее всего, не приведёт к желаемому 10-и байтовому вещественному типу. Потому как типа такого размера у них не может быть по природе вещей.
Проведя ряд опытом, можно установить, что sizeof(long double) иногда равен 12-и байтам.
clang -O3 -target i686-windows main.c sizeof(long double) == 8 clang -O3 -target i686-windows-gnu main.c sizeof(long double) == 12
Тема в архиве.