Поискал нужные ключи для компилятора по своим проектам, запискам и в интернете, и нашёл их.
Но при компиляции с ними возникли странные ошибки.
Я уже успел забыть про них, и когда-то уже с ними сталкивался, но не сразу вспомнил, как их можно исправить.
Поиск в google похожей проблемы ничего не дал.
Не помню, было ли такое же поведение на более старых версиях gcc + mingw, но при сборке на gcc 14.2.0 и mingw 12.0.0 оно есть, и мне кажется, это баг или недоработка.
Хотя, возможно, так было и раньше, но я мог собирать код без
-ffreestanding, поэтому проблема себя не проявляла.А если компилятор из-за оптимизаций или по другим причинам генерировал вызов любой функции из стандартной библиотеки или crt, то я просто получал ошибку компоновки.
Например, побайтовое копирование циклом
for компилятор спокойно может оптимизировать в вызов функции memcpy.Минимальный воспроизводимый пример состоит лишь из включения заголовочного файла
windows.h и ключа компилятора -ffreestanding.// g++ -ffreestanding -o winapi.exe winapi.cpp
#include <windows.h>
int main()
{
MessageBoxA(nullptr, "Hello world", "message", 0);
return 0;
};
При такой комбинации компилятор выдаёт такой текст ошибки.
Посмотрел в текст заголовочных файлов, на которые указал компилятор, и понял, что из-за ключа
-ffreestanding макрос __STDC_HOSTED__ устанавливается в значение 0, поэтому hosted код исключается из сборки.Беглым поиском я нашёл ещё несколько мест с такими же проверками, но почему-то их не оказалось в
x86intrin.h, immintrin.h и xmmintrin.h (возможно, есть ещё такие), которые вне зависимости от значения __STDC_HOSTED__ используют функционал hosted окружения, который отсутствует в freestanding окружении.Я не знаю для чего нужны эти заголовочные файлы и какое будет наиболее правильное решение, поэтому я сделал максимально простое и тупое решение.
Так как в этих заголовочных файлах вместо директивы препроцессора
#pragma once используются header guards через #ifndef #def, я просто перед включением windows.h определил два нужных макроса, чтобы препроцессор не включал эти проблемные заголовочные файлы:// g++ -ffreestanding -o winapi.exe winapi.cpp
#define _X86INTRIN_H_INCLUDED
#define _EMMINTRIN_H_INCLUDED
#include <windows.h>
int main()
{
MessageBoxA(nullptr, "Hello world", "message", 0);
return 0;
};
Получается, первый способ это не использовать ключ
-ffreestanding и получать ошибки на этапе компоновки, а второй это использовать ключ -ffreestanding и получать ошибки на этапе компиляции, но решать некоторые из них придётся костылями или редактированием заголовочных файлов стандартной библиотеки компилятора.Вне зависимости от использованного способа, конкретно с этим MRE (Minimal Reproducible Example), размер исполняемого файла получается одинаковым.
Интересно даже, действительно ли это баг или недоработка.
Я не знаю, куда писать, но оставлять это как есть не хочется, поэтому буду рад ссылкам и советам, куда мне написать об этой проблеме.
ссылка на канал | ссылка на группу


