Ясно, что ему что-то не то передаётся, но я со своими скудными знаниями никак не разберусь (rpath несколько раз пытался по разному указывать, безрезультатно).
Поломался тулчайн GCC (от serge). По крайней мере под Win32
1. На SVN в LIB нет библиотек Libc для статической линковки.
2. Пересобрать newlib не получается - не компилируется crt\setjmp.s
Я в гнусном ассемблере никак.
3. При динамической линковке недостача объектника __main
$(LD) $(LDFLAGS) $(LIBPATH) -o hello $(OBJECTS) -lc.dll -lapp -lgcc_eh
Так и не понял, кто функцию требует, тем не менее при созданной заглушке helloworld работает
4. Нет собранной stdlib++. Она собирается, но при линковке с ней не хватает уже прилично функций
__main - аналогичная проблема,
getc - сделан макросом а библиотека хочет функцию,
__umoddi3 и __udivdi3 - это генерируется при операциях с long long но реализации нет,
strxfrm - не реализована
Хотя эти функции и не вызываются, но cout << "helloworld" не работает
libgcc.a я не нашел ни в каком виде, ни в исходниках, ни в lib. Посчитал, что -lgcc_eh - ее замена с поддержкой исключений
пишет что то про формат
Spoiler:as -o crt/setjmp.o crt/setjmp.s
crt/setjmp.S: Assembler messages:
crt/setjmp.S:27: Error: junk at end of line, first unrecognized character is `('
crt/setjmp.S:28: Error: junk at end of line, first unrecognized character is `('
crt/setjmp.S:29: Error: invalid character '(' in mnemonic
crt/setjmp.S:30: Error: invalid character '(' in mnemonic
crt/setjmp.S:34: Error: no such instruction: `sym (setjmp):'
crt/setjmp.S:37: Error: too many memory references for `mov'
crt/setjmp.S:40: Error: junk `(ebp)' after expression
crt/setjmp.S:40: Error: too many memory references for `mov'
crt/setjmp.S:42: Error: too many memory references for `mov'
crt/setjmp.S:43: Error: too many memory references for `mov'
crt/setjmp.S:44: Error: too many memory references for `mov'
crt/setjmp.S:45: Error: too many memory references for `mov'
crt/setjmp.S:46: Error: too many memory references for `mov'
crt/setjmp.S:48: Error: junk `(ebp)' after expression
crt/setjmp.S:48: Error: too many memory references for `mov'
crt/setjmp.S:49: Error: too many memory references for `mov'
crt/setjmp.S:51: Error: junk `(ebp)' after expression
crt/setjmp.S:51: Error: too many memory references for `mov'
Не удивительно, потому, что файл должен компилироваться gcc.
Вечером гляну поправить makefile
Единственное, я ручками с соурфорджа докачивал недостающие dll для тулчейна Spoiler:libcharset-1.dll
libgcc_s_dw2-1.dll
libgmp-10.dll
libiconv-2.dll
libintl-8.dll
libmpc-3.dll
libmpfr-4.dll
zlib1.dll
mingw32-make.exe тоже приблудный
D:\VSProjects\msys-kos32-4.8.2\win32>mingw32-make.exe --version
GNU Make 3.82
1. libgcc.a действительно, нашелся - валялся внутри каталога компилятора, только не в путях поиска библиотек
Пришлось скопировать ручками
2. Правка makefile для компиляции .S с помощью gcc помогла собраться Libc
Итого С-программы работают, причем получаются компактными.
Правда, на чуть более сложной программке обнаружилось пару мелких багов в CRT
Spoiler:-fopen не знает про текущий каталог запуска программы - нужно указать полный путь
-clock()/CLOCKS_PER_SEC выдает несоответствующие значения
После догрузки необходимых unixtools даже удалось собрать и stdlibc++
Для __main, getc, strxfrm - поставлены заглушки.
__main раньше существовала как пустышка в crt3.c, но почему то была удалена. Она вызывается компилятором при старте main().
Остальные пока не вызываются.
Тем не менее, на обычной
cout << "Hello C++ world!" << endl;
вылетает.
Отладчик показал, что внутри ostream-inst.cc передается нулевой указатель.
Нужно смотреть с отладочной версией библиотеки. Позже гляну, возможно требуется явно инициализировать cout,
1. libgcc.a действительно, нашелся - валялся внутри каталога компилятора, только не в путях поиска библиотек
У остальных таких проблем не возникает. Это намекает на то, что сперва тулчейн надо корректно установить.
-fopen не знает про текущий каталог запуска программы - нужно указать полный путь
Это проблема не fopen, а файловых менеджеров Kolibri. Рекомендую запускать из Shell.
__main находится в libgcc. Эта функция вызывает конструкторы статических объектов. Ставить на ней заглушку facepalm
Необходимо перед запускам сменить рабочую директорию на директорию с которой запускается программа?
Нет, процессы наследуют рабочий каталог родителя. Только разработчики файловых менеджеров об этом забыли. А файловые функции используют рабочий каталог, если не указан полный путь. В результате если запустить shell и выполнить
cd /kolibrios
test
то рабочим каталогом test будет /kolibrios, а точнее примонтированная директория.
А если запустить test в kfar рабочим каталогом скорее всего будет /rd/1
Подтверждаю. Проблема была в замещенном __main().
Также подтверждаю, что из командной строки текущий каталог в fopen корректный.
Со статически слинкованной libc запускается. Но бинарник получился больше ~118Кб после KPack и 375k неупакованный
Попробовал для уменьшения, чтобы сошлось размером с serge, слинковать с динамической clib.dll - не запускается.
$(LD) $(LDFLAGS) $(LIBPATH) -o hellocpp $(OBJECTS) -lstdc++ -lsupc++ -lgcc_eh -lc.dll -lapp -lgcc
clib.dll Положил рядом с программой.
Или я не так собрал или clib.dll должен быть именно в системном rd/1/lib?
Надо повспоминать и задокументировать ньюансы тулчейна с mingw. Их снаружи не всегда видно, но системщики должны знать:
-он загадочным образом ищет свои (дефолтные) хидеры и библиотеки внутри своего подкаталога
-своеобразно генерирует код - 64-int операции, инициализация статических [только ли?] объектов, исключения
-важен порядок указания библиотек при линковке
-линкер не предупреждает о дублирующихся символах
-не всегда корректно обрабатываются перенаправление ввода-вывода у утилит
-в newlib stderr выводит сообщения не на консоль, а на системную доску отладки. perror() тоже
-часть функций clib реализованы как intrinsic
-чтобы не создавался еще один процесс с консольным окном для граф проги нужно добавить линкеру: LDFLAGS+= --subsystem windows