Дисклеймер

Все действия, описанные автором в статье, сделаны исключительно в исследовательских и образовательных целях. Windows является зарегистрированным товарным знаком Microsoft.

Введение

Привет всем.

В 2020 году мир облетела новость о сливе исходников Windows XP и Windows Server 2003 на 4Chan. После этого код широко разошелся по интернету, включая GitHub, который принадлежит Microsoft. Последняя, естественно, сразу начала принимать меры по блокировке кода, многие сайты и репозитории были удалены из поиска.

Каков же статус ситуации на 2023 год? Как ни парадоксально, исходники все еще можно найти на GitHub и клонировать без особых проблем. Тщательно поискав, можно найти инструкции и видео, как все собрать инструментами, которые идут в комплекте с исходниками системы.

Среди всех ОС от Microsoft, Windows XP является одной из самых моих любимых ОС. Она весьма быстрая, легковесная, но в тоже время интерфейс достаточно удобен для работы. По этим причинам, а также будучи разработчиком C и С++, мне было весьма интересно исследовать код данной ОС.

Доступная версия XP после распаковки занимает около 6 Гбайт. Запустив анализатор количества строк кода cloc, после 10 минут ожидания мы получим следующую картину:

---------------------------------------------------------------------------------------
Language                             files          blank        comment           code
---------------------------------------------------------------------------------------
C++                                  36430        5030975        5385465       17679581
C                                    24034        4511368        4689267       14461873
C/C++ Header                         53285        2603380        2377970        7988097
Text                                  8371         588113              0        6734137
Assembly                              1542         142153         295195         559390
Windows Resource File                 6511          97268          93360         558215
IDL                                   1356          79239            259         448884
HTML                                  4755          76074          82929         376750
XML                                    607           6987           2423         361834
TNSDL                                 1154          54741            101         330732
INI                                    752          59440          22551         249914
DOS Batch                             2380          36429          21852         205067
Windows Message File                   447          33721          23142         166854
Perl                                  1005          55650          83403         144053
Pascal                                 839          28654          74852         139010
make                                  2125          20797          17273          85174
Visual Basic                           644          18993          62445          72880
Visual Basic Script                    630          17735          15022          68423
Windows Module Definition             3356          11995          10384          68263
JavaScript                             348          17176          14149          62117
ASP                                    562          11884           2473          56997
Logos                                   49           7299          10446          51327
C#                                     174           9105          12755          43936
yacc                                    20           3929           3485          23647
MSBuild script                          73             41              0          22607
Gencat NLS                              44            241              0          18130
PHP                                     70           2489            133          16066
JSX                                     13           3340            880           9911
LLVM IR                                  8            642            550           9803
sed                                    196            262             49           9549
m4                                      20           1699              0           8943
CSS                                     76           1357            269           8159
Java                                    92           2200            626           7791
XSLT                                    55           1324            573           7777
SWIG                                    13           1936            384           7606
SQL                                     34           1343           1667           7506
Expect                                  11           1962              1           7432
Forth                                    6            279             44           6086
Qt                                      29           1237              0           5827
Oracle Forms                             7           1252              0           5811
GLSL                                     1              2              0           5728
lex                                     24            999            262           5494
CSV                                     17             23              0           5055
awk                                     92            523            178           4321
Ruby                                     3            276              0           3755
DAL                                      3            278              2           3747
Prolog                                   3            278             46           3714
Verilog-SystemVerilog                    3            282             44           3699
Lisp                                     4            304            216           3650
Visual Basic .NET                       11            399            652           3591
SKILL                                    1            335              0           2850
Mathematica                             36            142              0           2135
DTD                                     22            621            407           2087
Ring                                    14            343            355           1854
ASP.NET                                  4            312             13           1756
Bourne Shell                            10            240            273           1642
Igor Pro                                 3              0              0           1494
Visual Studio Solution                  70              0              0           1415
Markdown                                 1              5              0           1407
D                                       14            320           3649            882
XSD                                      9             76            174            734
Oracle PL/SQL                            2            222            153            656
MATLAB                                   8             66            104            560
ProGuard                                 1             60             87            505
TeX                                     16             44              0            248
WebAssembly                              2             32              0            239
Smalltalk                                5              9              0            211
R                                       10             23             19            192
ReScript                                 1              1              0            184
SAS                                      2             38             89            168
COBOL                                    1             35              2            141
Scheme                                   2              6              0            119
reStructuredText                         4              2              0             40
TypeScript                               1              0              0             33
F#                                       1              5              0             22
DenizenScript                            1              7             13              9
Nemerle                                  1              0              0              5
Oracle Reports                           1              1              0              5
---------------------------------------------------------------------------------------
SUM:                                152527       13551018       13313115       51160506
---------------------------------------------------------------------------------------

Среди языков преобладают C, С++ и assembly, на которые приходится порядка 40.7 млн. строк. Из сторонних источников мы можем выяснить, что доступный код содержит около 70 % кода всей ОС, т.е. итогоговое число строк кода может быть оценено порядка 58 млн. строк.

Очевидно, что разобрать 41 млн. строк кода в рамках одной статьи невозможно, поэтому я решил начать с задачи скомпилировать какое-нибудь простое приложение. Выбор пал на всем известный калькулятор. Почему именно он? Все просто, хотелось собрать калькулятор, который может считать без подключения к интернету :).

В тоже время, собрать его компилятором от Майкрософт было бы слишком просто, поэтому я решил усложнить челлендж и собрать его с помощью GCC x64.

Настройка окружения

Определимся, что нам потребуется:

  1. Хост с установленной Windows. В моем случае Windows 10.

  2. Qt. Я использую как QtCreator, так и порт GCC для Windows MinGW-64. Устанавливал оба с помощью Qt Maintanance Tool. После установки компилятор необходимо добавить в Path.

  3. Собирать будем с помощью Makefile. Для этого надо установить утилиту make.

Собираем калькулятор

Проанализируем количество строк кода калькулятора и его зависимостей с помощью cloc:

-----------------------------------------------------------------------------------
Language                         files          blank        comment           code
-----------------------------------------------------------------------------------
C                                   27           1666           2737           6277
C/C++ Header                        13            213            429           1080
Windows Resource File                1             75             46            494
C++                                  1             11              1             73
XML                                  1              0              0             21
make                                 1              0              5              1
-----------------------------------------------------------------------------------
SUM:                                44           1965           3218           7946
-----------------------------------------------------------------------------------

Для сборки calc.exe нам необходимо скомпилировать порядка 8000 строк кода из 42 файлов. Пролистав код, выясняем, что этот код очень древний, написан в 80-90х годах XX века. Интересно, что это C код, а файлы имеют расширение .c. Но местами он кидает исключения, поэтому его можно собрать только с помощью g++.

Открываем QtCreator и импортируем исходники ОС. На этапе импорта он зависнет из-за большого количества файлов. Надо подождать минут 15-20.

После импорта открываем поиск по проекту и ищем calc. В результате находим пусть исходников калькулятора в:

NT\shell\osshell\accesory\calc

Открыв папку, видим .c и .h файлы, а также папку nt, в которой находим параметры сборки, включая перечень файлов. Создадим в папке calc Makefile, взяв за прототип из моей предыдущей статьи по STM32 (русская версия, английская версия) и адаптировав его под наш случай. Начальные парамерты сборки возьмем из nt/sources. Выглядеть он будет следующим образом.

Calc makefile
TARGET = calc
BUILD_DIR = build
OPT = -O0
CC = g++

C_SOURCES = calc.c      \
            input.c     \
            scicomm.c   \
            scidisp.c   \
            scifunc.c   \
            scikeys.c   \
            scimath.c   \
            scimenu.c   \
            scioper.c   \
            sciproc.c   \
            sciset.c    \
            scistat.c   \
            unifunc.c   \
            wassert.c
		
C_DEFS = -DWIN32 \
         -DW3 \
         -DWINNT \
         -DUNICODE \
         -D_UNICODE \
         -DUSE_MIRRORING

C_INCLUDES = -I..\ratpak \
             -I..\inc \

CFLAGS += $(C_DEFS) $(C_INCLUDES) $(OPT)

LIBS = 
LIBDIR =
LDFLAGS = $(LIBDIR) $(LIBS)

all: $(BUILD_DIR)/$(TARGET)

OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))

$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 
	$(CC) -c $(CFLAGS) -o $@  $<

$(BUILD_DIR)/$(TARGET): $(OBJECTS) Makefile
	$(CC) $(OBJECTS) $(LDFLAGS) -o $@

$(BUILD_DIR):
	mkdir $@
	
clean:
	-rm -fR $(BUILD_DIR)

Попытаемся собрать командой make:

Calc build output - 1
mkdir build
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/calc.o  calc.c
In file included from calc.c:29:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from calc.c:26:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/input.o  input.c
In file included from input.c:14:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from input.c:13:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scicomm.o  scicomm.c
In file included from scicomm.c:15:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scicomm.c:13:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scidisp.o  scidisp.c
In file included from scidisp.c:14:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scidisp.c:13:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scifunc.o  scifunc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scikeys.o  scikeys.c
In file included from scikeys.c:3:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scikeys.c:1:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scimath.o  scimath.c
In file included from scimath.c:4:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scimath.c:1:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scimenu.o  scimenu.c
In file included from scimenu.c:26:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scimenu.c:25:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scioper.o  scioper.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/sciproc.o  sciproc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/sciset.o  sciset.c
In file included from sciset.c:22:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from sciset.c:21:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scistat.o  scistat.c
In file included from scistat.c:35:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scistat.c:33:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/unifunc.o  unifunc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/wassert.o  wassert.c
g++ build/calc.o build/input.o build/scicomm.o build/scidisp.o build/scifunc.o build/scikeys.o build/scimath.o build/scimenu.o build/scioper.o build/sciproc.o build/sciset.o build/scistat.o build/unifunc.o build/wassert.o    -o build/calc
build/calc.o:calc.c:(.text+0xa42): undefined reference to `_destroyrat(_rat*)'
build/calc.o:calc.c:(.text+0xa52): undefined reference to `_createrat()'
build/calc.o:calc.c:(.text+0xa6b): undefined reference to `_destroynum(_number*)'
build/calc.o:calc.c:(.text+0xa97): undefined reference to `_createnum(long)'
build/calc.o:calc.c:(.text+0xaeb): undefined reference to `_destroynum(_number*)'
build/calc.o:calc.c:(.text+0xb19): undefined reference to `_createnum(long)'
build/calc.o:calc.c:(.text+0xb9c): undefined reference to `_destroyrat(_rat*)'
build/calc.o:calc.c:(.text+0xbac): undefined reference to `_createrat()'
build/calc.o:calc.c:(.text+0xbc5): undefined reference to `_destroynum(_number*)'
build/calc.o:calc.c:(.text+0xbf1): undefined reference to `_createnum(long)'
build/calc.o:calc.c:(.text+0xc45): undefined reference to `_destroynum(_number*)'
build/calc.o:calc.c:(.text+0xc73): undefined reference to `_createnum(long)'
build/calc.o:calc.c:(.text+0xcc7): undefined reference to `_destroyrat(_rat*)'
build/calc.o:calc.c:(.text+0xcd7): undefined reference to `_createrat()'
build/calc.o:calc.c:(.text+0xcf0): undefined reference to `_destroynum(_number*)'
build/calc.o:calc.c:(.text+0xd1c): undefined reference to `_createnum(long)'
build/calc.o:calc.c:(.text+0xd70): undefined reference to `_destroynum(_number*)'
build/calc.o:calc.c:(.text+0xd9e): undefined reference to `_createnum(long)'
build/calc.o:calc.c:(.text+0x159b): undefined reference to `zerrat(_rat*)'
build/calc.o:calc.c:(.rdata$.refptr.rat_zero[.refptr.rat_zero]+0x0): undefined reference to `rat_zero'
build/calc.o:calc.c:(.rdata$.refptr.rat_byte[.refptr.rat_byte]+0x0): undefined reference to `rat_byte'
build/calc.o:calc.c:(.rdata$.refptr.rat_word[.refptr.rat_word]+0x0): undefined reference to `rat_word'
build/calc.o:calc.c:(.rdata$.refptr.rat_dword[.refptr.rat_dword]+0x0): undefined reference to `rat_dword'
build/calc.o:calc.c:(.rdata$.refptr.rat_qword[.refptr.rat_qword]+0x0): undefined reference to `rat_qword'
build/input.o:input.c:(.text+0x136): undefined reference to `inrat(int, wchar_t*, int, wchar_t*)'
build/input.o:input.c:(.text+0x149): undefined reference to `_destroyrat(_rat*)'
build/input.o:input.c:(.text+0x159): undefined reference to `_createrat()'
build/input.o:input.c:(.text+0x175): undefined reference to `_destroynum(_number*)'
build/input.o:input.c:(.text+0x19b): undefined reference to `_createnum(long)'
build/input.o:input.c:(.text+0x1e3): undefined reference to `_destroynum(_number*)'
build/input.o:input.c:(.text+0x20b): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x626): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x64e): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x680): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x6ca): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x73c): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x788): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x900): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x913): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x935): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x973): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x9e5): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0xa25): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0xa9c): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0xaaf): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0xad1): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0xb03): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0xb5d): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0xb91): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0xc02): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0xc15): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0xc37): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0xc69): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0xcc3): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0xcf7): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0xd51): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0xd64): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0xd86): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0xdb8): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0xe12): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0xe46): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0xf07): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0xf1a): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0xf3c): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0xf6e): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0xfc8): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0xffc): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x1373): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x1386): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x13a8): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x13da): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x1434): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x1468): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x1556): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x1569): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x158b): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x15bd): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x1617): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x164b): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x17c4): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x17d7): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x17f9): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x182b): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x1885): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x18b9): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x192f): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x193f): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x1958): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x1984): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x19d8): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x1a06): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x1a62): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x1a75): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x1a97): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x1ac6): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x1b1a): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x1b4b): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x1bc3): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x1bd6): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x1bf8): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x1c2a): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x1c84): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x1cb8): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x1db7): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x1dca): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x1dec): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x1e2a): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x1e9c): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x1edc): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x1f53): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x1f66): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x1f88): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x1fba): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x2014): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x2048): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x216e): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x2196): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x21c8): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x2212): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x2284): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x22d0): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x2385): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x2398): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x23ba): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x23ec): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x2446): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x247a): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x257f): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x2592): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x25b4): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x25f2): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x2664): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x26a4): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x271b): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x272e): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x2750): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x2782): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x27dc): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x2810): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x28a8): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x28bb): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x28dd): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x291b): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x298d): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x29cd): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x2df9): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x2e0c): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x2e2e): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x2e60): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x2eba): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x2eee): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x2f59): undefined reference to `addrat(_rat**, _rat*)'
build/scicomm.o:scicomm.c:(.text+0x2f6b): undefined reference to `zerrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x2fbf): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x2fd2): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x2ff4): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x3026): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x3080): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x30b4): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x3113): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x3126): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x3148): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x317a): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x31d4): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x3208): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x3262): undefined reference to `zerrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x32cb): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x32de): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x3300): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x3332): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x338c): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x33c0): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x341f): undefined reference to `_destroyrat(_rat*)'
build/scicomm.o:scicomm.c:(.text+0x3432): undefined reference to `_createrat()'
build/scicomm.o:scicomm.c:(.text+0x3454): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x3486): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.text+0x34e0): undefined reference to `_destroynum(_number*)'
build/scicomm.o:scicomm.c:(.text+0x3514): undefined reference to `_createnum(long)'
build/scicomm.o:scicomm.c:(.rdata$.refptr.pi[.refptr.pi]+0x0): undefined reference to `pi'
build/scicomm.o:scicomm.c:(.rdata$.refptr.two_pi[.refptr.two_pi]+0x0): undefined reference to `two_pi'
build/scidisp.o:scidisp.c:(.text+0x51): undefined reference to `rat_equ(_rat*, _rat*)'
build/scidisp.o:scidisp.c:(.text+0x134): undefined reference to `_destroyrat(_rat*)'
build/scidisp.o:scidisp.c:(.text+0x144): undefined reference to `_createrat()'
build/scidisp.o:scidisp.c:(.text+0x15d): undefined reference to `_destroynum(_number*)'
build/scidisp.o:scidisp.c:(.text+0x189): undefined reference to `_createnum(long)'
build/scidisp.o:scidisp.c:(.text+0x1dd): undefined reference to `_destroynum(_number*)'
build/scidisp.o:scidisp.c:(.text+0x20b): undefined reference to `_createnum(long)'
build/scidisp.o:scidisp.c:(.text+0x352): undefined reference to `intrat(_rat**)'
build/scidisp.o:scidisp.c:(.text+0x36e): undefined reference to `rat_lt(_rat*, _rat*)'
build/scidisp.o:scidisp.c:(.text+0x3b0): undefined reference to `subrat(_rat**, _rat*)'
build/scidisp.o:scidisp.c:(.text+0x3e1): undefined reference to `andrat(_rat**, _rat*)'
build/scidisp.o:scidisp.c:(.rdata$.refptr.fhalt[.refptr.fhalt]+0x0): undefined reference to `fhalt'
build/scidisp.o:scidisp.c:(.rdata$.refptr.rat_one[.refptr.rat_one]+0x0): undefined reference to `rat_one'
build/scifunc.o:scifunc.c:(.text+0x54): undefined reference to `fracrat(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x62): undefined reference to `intrat(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x91): undefined reference to `_destroyrat(_rat*)'
build/scifunc.o:scifunc.c:(.text+0x9e): undefined reference to `_createrat()'
build/scifunc.o:scifunc.c:(.text+0xb1): undefined reference to `_destroynum(_number*)'
build/scifunc.o:scifunc.c:(.text+0xd7): undefined reference to `_createnum(long)'
build/scifunc.o:scifunc.c:(.text+0x125): undefined reference to `_destroynum(_number*)'
build/scifunc.o:scifunc.c:(.text+0x14d): undefined reference to `_createnum(long)'
build/scifunc.o:scifunc.c:(.text+0x1b0): undefined reference to `divrat(_rat**, _rat*)'
build/scifunc.o:scifunc.c:(.text+0x1bc): undefined reference to `_destroyrat(_rat*)'
build/scifunc.o:scifunc.c:(.text+0x1d4): undefined reference to `mulrat(_rat**, _rat*)'
build/scifunc.o:scifunc.c:(.text+0x1e0): undefined reference to `_destroyrat(_rat*)'
build/scifunc.o:scifunc.c:(.text+0x232): undefined reference to `asinhrat(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x24b): undefined reference to `asinanglerat(_rat**, eANGLE_TYPE)'
build/scifunc.o:scifunc.c:(.text+0x266): undefined reference to `sinhrat(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x2bd): undefined reference to `acoshrat(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x2d6): undefined reference to `acosanglerat(_rat**, eANGLE_TYPE)'
build/scifunc.o:scifunc.c:(.text+0x2f1): undefined reference to `coshrat(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x348): undefined reference to `atanhrat(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x361): undefined reference to `atananglerat(_rat**, eANGLE_TYPE)'
build/scifunc.o:scifunc.c:(.text+0x37c): undefined reference to `tanhrat(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x3cd): undefined reference to `rootrat(_rat**, _rat*)'
build/scifunc.o:scifunc.c:(.text+0x3dd): undefined reference to `ratpowlong(_rat**, long)'
build/scifunc.o:scifunc.c:(.text+0x40c): undefined reference to `_destroyrat(_rat*)'
build/scifunc.o:scifunc.c:(.text+0x419): undefined reference to `_createrat()'
build/scifunc.o:scifunc.c:(.text+0x42c): undefined reference to `_destroynum(_number*)'
build/scifunc.o:scifunc.c:(.text+0x452): undefined reference to `_createnum(long)'
build/scifunc.o:scifunc.c:(.text+0x4a0): undefined reference to `_destroynum(_number*)'
build/scifunc.o:scifunc.c:(.text+0x4c8): undefined reference to `_createnum(long)'
build/scifunc.o:scifunc.c:(.text+0x520): undefined reference to `addrat(_rat**, _rat*)'
build/scifunc.o:scifunc.c:(.text+0x530): undefined reference to `rootrat(_rat**, _rat*)'
build/scifunc.o:scifunc.c:(.text+0x53c): undefined reference to `_destroyrat(_rat*)'
build/scifunc.o:scifunc.c:(.text+0x557): undefined reference to `ratpowlong(_rat**, long)'
build/scifunc.o:scifunc.c:(.text+0x586): undefined reference to `exprat(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x59a): undefined reference to `log10rat(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x5a8): undefined reference to `lograt(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x5b6): undefined reference to `factrat(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x625): undefined reference to `_destroyrat(_rat*)'
build/scifunc.o:scifunc.c:(.text+0x632): undefined reference to `_createrat()'
build/scifunc.o:scifunc.c:(.text+0x645): undefined reference to `_destroynum(_number*)'
build/scifunc.o:scifunc.c:(.text+0x668): undefined reference to `_createnum(long)'
build/scifunc.o:scifunc.c:(.text+0x6b0): undefined reference to `_destroynum(_number*)'
build/scifunc.o:scifunc.c:(.text+0x6d5): undefined reference to `_createnum(long)'
build/scifunc.o:scifunc.c:(.text+0x71a): undefined reference to `intrat(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x72d): undefined reference to `subrat(_rat**, _rat*)'
build/scifunc.o:scifunc.c:(.text+0x73d): undefined reference to `mulrat(_rat**, _rat*)'
build/scifunc.o:scifunc.c:(.text+0x749): undefined reference to `_destroyrat(_rat*)'
build/scifunc.o:scifunc.c:(.text+0x756): undefined reference to `_createrat()'
build/scifunc.o:scifunc.c:(.text+0x769): undefined reference to `_destroynum(_number*)'
build/scifunc.o:scifunc.c:(.text+0x789): undefined reference to `_createnum(long)'
build/scifunc.o:scifunc.c:(.text+0x7cb): undefined reference to `_destroynum(_number*)'
build/scifunc.o:scifunc.c:(.text+0x7ed): undefined reference to `_createnum(long)'
build/scifunc.o:scifunc.c:(.text+0x82f): undefined reference to `intrat(_rat**)'
build/scifunc.o:scifunc.c:(.text+0x83f): undefined reference to `subrat(_rat**, _rat*)'
build/scifunc.o:scifunc.c:(.text+0x84f): undefined reference to `mulrat(_rat**, _rat*)'
build/scifunc.o:scifunc.c:(.text+0x884): undefined reference to `divrat(_rat**, _rat*)'
build/scifunc.o:scifunc.c:(.text+0x894): undefined reference to `addrat(_rat**, _rat*)'
build/scifunc.o:scifunc.c:(.text+0x8a4): undefined reference to `divrat(_rat**, _rat*)'
build/scifunc.o:scifunc.c:(.text+0x8b4): undefined reference to `addrat(_rat**, _rat*)'
build/scifunc.o:scifunc.c:(.text+0x8c0): undefined reference to `_destroyrat(_rat*)'
build/scifunc.o:scifunc.c:(.text+0x8d4): undefined reference to `_destroyrat(_rat*)'
build/scifunc.o:scifunc.c:(.text+0x8e8): undefined reference to `_destroyrat(_rat*)'
build/scifunc.o:scifunc.c:(.text+0x925): undefined reference to `_destroyrat(_rat*)'
build/scifunc.o:scifunc.c:(.text+0x942): undefined reference to `_destroyrat(_rat*)'
build/scifunc.o:scifunc.c:(.text+0x9b4): more undefined references to `_destroyrat(_rat*)' follow
build/scifunc.o:scifunc.c:(.rdata$.refptr.rat_two[.refptr.rat_two]+0x0): undefined reference to `rat_two'
build/scimath.o:scimath.c:(.text+0xf7): undefined reference to `ChangeConstants(long, long)'
build/scimath.o:scimath.c:(.text+0x115): undefined reference to `ChangeConstants(long, long)'
build/scimath.o:scimath.c:(.text+0x142): undefined reference to `_destroyrat(_rat*)'
build/scimath.o:scimath.c:(.text+0x14f): undefined reference to `_createrat()'
build/scimath.o:scimath.c:(.text+0x162): undefined reference to `_destroynum(_number*)'
build/scimath.o:scimath.c:(.text+0x188): undefined reference to `_createnum(long)'
build/scimath.o:scimath.c:(.text+0x1d6): undefined reference to `_destroynum(_number*)'
build/scimath.o:scimath.c:(.text+0x1fe): undefined reference to `_createnum(long)'
build/scimath.o:scimath.c:(.text+0x253): undefined reference to `divrat(_rat**, _rat*)'
build/scimath.o:scimath.c:(.text+0x262): undefined reference to `_destroyrat(_rat*)'
build/scimath.o:scimath.c:(.text+0x272): undefined reference to `_createrat()'
build/scimath.o:scimath.c:(.text+0x28e): undefined reference to `_destroynum(_number*)'
build/scimath.o:scimath.c:(.text+0x2b4): undefined reference to `_createnum(long)'
build/scimath.o:scimath.c:(.text+0x2fc): undefined reference to `_destroynum(_number*)'
build/scimath.o:scimath.c:(.text+0x324): undefined reference to `_createnum(long)'
build/scimath.o:scimath.c:(.text+0x369): undefined reference to `_destroyrat(_rat*)'
build/scimath.o:scimath.c:(.text+0x3b7): undefined reference to `powrat(_rat**, _rat*)'
build/scimath.o:scimath.c:(.text+0x3c6): undefined reference to `_destroyrat(_rat*)'
build/scimath.o:scimath.c:(.text+0x3d6): undefined reference to `_createrat()'
build/scimath.o:scimath.c:(.text+0x3f2): undefined reference to `_destroynum(_number*)'
build/scimath.o:scimath.c:(.text+0x418): undefined reference to `_createnum(long)'
build/scimath.o:scimath.c:(.text+0x460): undefined reference to `_destroynum(_number*)'
build/scimath.o:scimath.c:(.text+0x488): undefined reference to `_createnum(long)'
build/scimath.o:scimath.c:(.text+0x4cd): undefined reference to `_destroyrat(_rat*)'
build/scimath.o:scimath.c:(.text+0x500): undefined reference to `intrat(_rat**)'
build/scimath.o:scimath.c:(.text+0x516): undefined reference to `addrat(_rat**, _rat*)'
build/scimath.o:scimath.c:(.text+0x554): undefined reference to `xorrat(_rat**, _rat*)'
build/scimath.o:scimath.c:(.text+0x57b): undefined reference to `sinanglerat(_rat**, eANGLE_TYPE)'
build/scimath.o:scimath.c:(.text+0x5a2): undefined reference to `cosanglerat(_rat**, eANGLE_TYPE)'
build/scimath.o:scimath.c:(.text+0x5c9): undefined reference to `tananglerat(_rat**, eANGLE_TYPE)'
build/scimath.o:scimath.c:(.text+0x5f7): undefined reference to `longtorat(long)'
build/scimath.o:scimath.c:(.text+0x60a): undefined reference to `_destroyrat(_rat*)'
build/scimath.o:scimath.c:(.text+0x61a): undefined reference to `_createrat()'
build/scimath.o:scimath.c:(.text+0x636): undefined reference to `_destroynum(_number*)'
build/scimath.o:scimath.c:(.text+0x65c): undefined reference to `_createnum(long)'
build/scimath.o:scimath.c:(.text+0x6a4): undefined reference to `_destroynum(_number*)'
build/scimath.o:scimath.c:(.text+0x6cc): undefined reference to `_createnum(long)'
build/scimath.o:scimath.c:(.text+0x711): undefined reference to `_destroyrat(_rat*)'
build/scimath.o:scimath.c:(.text+0x74e): undefined reference to `putrat(_rat**, unsigned long, int)'
build/scimenu.o:scimenu.c:(.text+0x822): undefined reference to `HtmlHelpW'
build/scioper.o:scioper.c:(.text+0x5e): undefined reference to `andrat(_rat**, _rat*)'
build/scioper.o:scioper.c:(.text+0x73): undefined reference to `orrat(_rat**, _rat*)'
build/scioper.o:scioper.c:(.text+0x88): undefined reference to `xorrat(_rat**, _rat*)'
build/scioper.o:scioper.c:(.text+0x99): undefined reference to `_destroyrat(_rat*)'
build/scioper.o:scioper.c:(.text+0xa6): undefined reference to `_createrat()'
build/scioper.o:scioper.c:(.text+0xb9): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0xdc): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x124): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x149): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x194): undefined reference to `_destroyrat(_rat*)'
build/scioper.o:scioper.c:(.text+0x1a4): undefined reference to `_createrat()'
build/scioper.o:scioper.c:(.text+0x1c0): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x1e6): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x22e): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x256): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x29f): undefined reference to `rshrat(_rat**, _rat*)'
build/scioper.o:scioper.c:(.text+0x2b0): undefined reference to `_destroyrat(_rat*)'
build/scioper.o:scioper.c:(.text+0x2bd): undefined reference to `_createrat()'
build/scioper.o:scioper.c:(.text+0x2d0): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x2f3): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x33b): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x360): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x3ab): undefined reference to `_destroyrat(_rat*)'
build/scioper.o:scioper.c:(.text+0x3bb): undefined reference to `_createrat()'
build/scioper.o:scioper.c:(.text+0x3d7): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x3fd): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x445): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x46d): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x4b6): undefined reference to `lshrat(_rat**, _rat*)'
build/scioper.o:scioper.c:(.text+0x4cb): undefined reference to `addrat(_rat**, _rat*)'
build/scioper.o:scioper.c:(.text+0x4e0): undefined reference to `subrat(_rat**, _rat*)'
build/scioper.o:scioper.c:(.text+0x50f): undefined reference to `mulrat(_rat**, _rat*)'
build/scioper.o:scioper.c:(.text+0x520): undefined reference to `_destroyrat(_rat*)'
build/scioper.o:scioper.c:(.text+0x52d): undefined reference to `_createrat()'
build/scioper.o:scioper.c:(.text+0x540): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x563): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x5ab): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x5d0): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x61b): undefined reference to `_destroyrat(_rat*)'
build/scioper.o:scioper.c:(.text+0x62b): undefined reference to `_createrat()'
build/scioper.o:scioper.c:(.text+0x647): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x66d): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x6b5): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x6dd): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x72c): undefined reference to `divrat(_rat**, _rat*)'
build/scioper.o:scioper.c:(.text+0x741): undefined reference to `modrat(_rat**, _rat*)'
build/scioper.o:scioper.c:(.text+0x752): undefined reference to `_destroyrat(_rat*)'
build/scioper.o:scioper.c:(.text+0x75f): undefined reference to `_createrat()'
build/scioper.o:scioper.c:(.text+0x772): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x795): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x7dd): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x802): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x84d): undefined reference to `_destroyrat(_rat*)'
build/scioper.o:scioper.c:(.text+0x85d): undefined reference to `_createrat()'
build/scioper.o:scioper.c:(.text+0x879): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x89f): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x8e7): undefined reference to `_destroynum(_number*)'
build/scioper.o:scioper.c:(.text+0x90f): undefined reference to `_createnum(long)'
build/scioper.o:scioper.c:(.text+0x987): undefined reference to `rootrat(_rat**, _rat*)'
build/scioper.o:scioper.c:(.text+0x999): undefined reference to `powrat(_rat**, _rat*)'
build/scioper.o:scioper.c:(.text+0x9b4): undefined reference to `_destroyrat(_rat*)'
build/scioper.o:scioper.c:(.text+0x9f4): undefined reference to `_destroyrat(_rat*)'
build/sciproc.o:sciproc.c:(.text+0x33b): undefined reference to `HtmlHelpW'
build/sciproc.o:sciproc.c:(.text+0x581): undefined reference to `__imp_SetBkMode'
build/sciproc.o:sciproc.c:(.text+0x5db): undefined reference to `__imp_SetTextColor'
build/sciproc.o:sciproc.c:(.text+0x623): undefined reference to `__imp_SetBkMode'
build/sciproc.o:sciproc.c:(.text+0x67b): undefined reference to `__imp_SetBkColor'
build/sciproc.o:sciproc.c:(.text+0x69b): undefined reference to `__imp_SetTextColor'
build/scistat.o:scistat.c:(.text+0x148): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x3d3): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x3e6): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0x408): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x449): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x4c1): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x504): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x74a): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x77d): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0x7a1): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x7fc): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x88e): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x8eb): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0xaa8): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0xcc6): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0xcff): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0xd26): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0xd77): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0xdef): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0xe42): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0xf0d): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0xf20): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0xf42): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0xf74): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0xfce): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1002): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x106c): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x1079): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0x108c): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x10be): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1124): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1158): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x11d7): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x11e4): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0x11f7): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1217): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1259): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x127b): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x12c1): undefined reference to `mulrat(_rat**, _rat*)'
build/scistat.o:scistat.c:(.text+0x12d4): undefined reference to `addrat(_rat**, _rat*)'
build/scistat.o:scistat.c:(.text+0x12e0): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x12fd): undefined reference to `addrat(_rat**, _rat*)'
build/scistat.o:scistat.c:(.text+0x1353): undefined reference to `divrat(_rat**, _rat*)'
build/scistat.o:scistat.c:(.text+0x135f): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x1373): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x13ba): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x13cd): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0x13ef): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1421): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x147b): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x14af): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1528): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x153b): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0x155d): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x158f): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x15e9): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x161d): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1671): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x167e): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0x1691): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x16b7): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1705): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x172d): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1791): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x179e): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0x17b1): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x17e3): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1849): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x187d): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x18e7): undefined reference to `addrat(_rat**, _rat*)'
build/scistat.o:scistat.c:(.text+0x18f3): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x1900): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0x1913): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1933): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1975): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1997): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x19dd): undefined reference to `mulrat(_rat**, _rat*)'
build/scistat.o:scistat.c:(.text+0x19f0): undefined reference to `addrat(_rat**, _rat*)'
build/scistat.o:scistat.c:(.text+0x1a17): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x1a24): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0x1a37): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1a57): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1a99): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1abb): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1b01): undefined reference to `mulrat(_rat**, _rat*)'
build/scistat.o:scistat.c:(.text+0x1b11): undefined reference to `divrat(_rat**, _rat*)'
build/scistat.o:scistat.c:(.text+0x1b1d): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x1b2a): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0x1b3d): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1b63): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1bb1): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1bd9): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1c2b): undefined reference to `subrat(_rat**, _rat*)'
build/scistat.o:scistat.c:(.text+0x1c37): undefined reference to `zerrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x1c56): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x1c69): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0x1c8b): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1cbd): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1d17): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1d4b): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1dbb): undefined reference to `subrat(_rat**, _rat*)'
build/scistat.o:scistat.c:(.text+0x1dcb): undefined reference to `divrat(_rat**, _rat*)'
build/scistat.o:scistat.c:(.text+0x1de1): undefined reference to `rootrat(_rat**, _rat*)'
build/scistat.o:scistat.c:(.text+0x1df3): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x1e06): undefined reference to `_createrat()'
build/scistat.o:scistat.c:(.text+0x1e28): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1e54): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1ea2): undefined reference to `_destroynum(_number*)'
build/scistat.o:scistat.c:(.text+0x1ed0): undefined reference to `_createnum(long)'
build/scistat.o:scistat.c:(.text+0x1f18): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x1f2c): undefined reference to `_destroyrat(_rat*)'
build/scistat.o:scistat.c:(.text+0x1f40): undefined reference to `_destroyrat(_rat*)'
collect2.exe: error: ld returned 1 exit status
make: *** [build/calc] Error 1

Видим большой аутпут, часть варнингов говорит о переопределении макросов в современных заголовочниках Windows. В конце видим ошибку линковки, предположительно связанной с библиотекой ratpak. Из конфиг файла nt/source находим, что исходники ratpak находятся уровне выше:

NT\shell\osshell\accesory\ratpak

Попробуем ее собрать. Идем в ее директорию и создаем Makefile следующего содержания, взяв конфиг из аналогичного nt/source:

Ratpak makefile
TARGET = ratpak.lib
BUILD_DIR = build
OPT = -Os

C_SOURCES = rat.c \
			num.c \
			conv.c \
			debug.c \
			itrans.c \
			trans.c \
			transh.c \
			itransh.c \
			logic.c \
			fact.c \
			basex.c \
			exp.c \
			support.c \

CC = g++

C_DEFS = -DWIN32 \
		 -DW3 \
		 -DWINNT \
		 -DUNICODE \
		 -D_UNICODE \
		 -DNOMINMAX

C_INCLUDES = -I.

CFLAGS += $(C_DEFS) $(C_INCLUDES) $(OPT)

all: $(BUILD_DIR)/$(TARGET)

OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))

$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 
	$(CC) -c $(CFLAGS) -o $@  $<

$(BUILD_DIR)/$(TARGET): $(OBJECTS)
	ar ru $@ $^
	ranlib $@

$(BUILD_DIR):
	mkdir $@		

clean:
	-rm -fR $(BUILD_DIR)

Тут главная разница, что мы собираем ratpak в виде статической библиотеки, поэтому собирается она через команду:

$(BUILD_DIR)/$(TARGET): $(OBJECTS)
    ar ru $@ $^
    ranlib $@

Собираем make:

Ratpak build output - 1
mkdir build
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DNOMINMAX -I. -Os -o build/rat.o  rat.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DNOMINMAX -I. -Os -o build/num.o  num.c
num.c: In function 'void _addnum(_number**, PNUMBER, long unsigned int)':
num.c:88:15: error: 'max' was not declared in this scope
     cdigits = max( a->cdigit+a->exp, b->cdigit+b->exp ) -
               ^~~
num.c:89:13: error: 'min' was not declared in this scope
             min( a->exp, b->exp );
             ^~~
num.c: In function 'BOOL equnum(PNUMBER, PNUMBER)':
num.c:546:23: error: 'max' was not declared in this scope
             cdigits = max( a->cdigit, b->cdigit );
                       ^~~
num.c: In function 'BOOL lessnum(PNUMBER, PNUMBER)':
num.c:613:23: error: 'max' was not declared in this scope
             cdigits = max( a->cdigit, b->cdigit );
                       ^~~
make: *** [build/num.o] Error 1

Видим ошибку, связанную с макросами min и max. В отличии от современной Windows, в XP они были включены в файл windows.h. Мы можем попытаться подключить родной файл XP, однако получим конфликт файлов. Поэтому мы возьмем и добавим эти функции из STL. Для этого создадим файл custom.h и добавим следующее содержание:

#pragma once

#include <algorithm>

using std::min;
using std::max;

Далее включим этот хедер в num.c, logic.c и support.c. Пересобираем:

Ratpak build output - 2
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DNOMINMAX -I. -Os -o build/support.o  support.c
support.c:64:8: error: 'cbitsofprecision' does not name a type; did you mean 'changePrecision'?
 static cbitsofprecision = RATIO_FOR_DECIMAL * DECIMAL *
        ^~~~~~~~~~~~~~~~
        changePrecision
In file included from support.c:67:
./ratconst.h:7:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:14:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:21:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:28:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:35:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:42:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:48:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:55:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:61:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:68:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:74:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:81:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:87:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:94:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:100:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:107:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:113:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:120:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:126:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:133:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:139:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:146:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:152:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:159:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:165:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:172:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:178:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:185:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:191:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:198:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:204:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:211:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:217:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:224:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:230:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:237:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:243:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:250:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:256:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:263:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:269:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:276:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:282:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:289:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:295:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:302:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:308:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:315:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:321:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:328:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:334:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:341:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:347:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:354:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:360:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:367:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:373:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:380:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:386:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:393:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:399:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:406:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:412:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:419:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:425:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:432:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
./ratconst.h:438:1: error: too many initializers for 'MANTTYPE [0]' {aka 'long unsigned int [0]'}
 };
 ^
support.c: In function 'void ChangeConstants(long int, long int)':
support.c:198:10: error: 'cbitsofprecision' was not declared in this scope
     if ( cbitsofprecision < ( ratio * nRadix * nPrecision ) )
          ^~~~~~~~~~~~~~~~
support.c:198:10: note: suggested alternative: 'changePrecision'
     if ( cbitsofprecision < ( ratio * nRadix * nPrecision ) )
          ^~~~~~~~~~~~~~~~
          changePrecision
make: *** [build/support.o] Error 1

Видим 2 типа ошибок. В первом случае пропущен тип (!) в support.c на строках 41 и 64. Добавляем туда int:

static int cbitsofprecision

Во втором случае пытаемся инициализировать массив с размером 0 (!) в структуре NUMBER из ratpak.h несколькими элементами. Удаляем 0 из массива [0], оставив пустые скобки []. Собираем и видим, что ошибок больше нет, а в папке build лежит ratpak.lib.

Ratpak build output - 3
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DNOMINMAX -I. -Os -o build/support.o  support.c
ar ru build/ratpak.lib build/rat.o build/num.o build/conv.o build/debug.o build/itrans.o build/trans.o build/transh.o build/itransh.o build/logic.o build/fact.o build/basex.o build/exp.o build/support.o
ar: creating build/ratpak.lib
ranlib build/ratpak.lib

Теперь вернемся к calc и попробуем сликоваться с этой либой, добавив в Makefile к ней путь и линковку.

LIBS = -lratpak
LIBDIR = -L..\ratpak\build
Calc build output - 2
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/calc.o  calc.c
In file included from calc.c:29:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from calc.c:26:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/input.o  input.c
In file included from input.c:14:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from input.c:13:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scicomm.o  scicomm.c
In file included from scicomm.c:15:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scicomm.c:13:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scidisp.o  scidisp.c
In file included from scidisp.c:14:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scidisp.c:13:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scifunc.o  scifunc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scikeys.o  scikeys.c
In file included from scikeys.c:3:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scikeys.c:1:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scimath.o  scimath.c
In file included from scimath.c:4:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scimath.c:1:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scimenu.o  scimenu.c
In file included from scimenu.c:26:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scimenu.c:25:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scioper.o  scioper.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/sciproc.o  sciproc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/sciset.o  sciset.c
In file included from sciset.c:22:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from sciset.c:21:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scistat.o  scistat.c
In file included from scistat.c:35:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scistat.c:33:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/unifunc.o  unifunc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/wassert.o  wassert.c
g++ build/calc.o build/input.o build/scicomm.o build/scidisp.o build/scifunc.o build/scikeys.o build/scimath.o build/scimenu.o build/scioper.o build/sciproc.o build/sciset.o build/scistat.o build/unifunc.o build/wassert.o  -L..\ratpak\build -lratpak -o build/calc
build/scimenu.o:scimenu.c:(.text+0x822): undefined reference to `HtmlHelpW'
build/sciproc.o:sciproc.c:(.text+0x33b): undefined reference to `HtmlHelpW'
build/sciproc.o:sciproc.c:(.text+0x581): undefined reference to `__imp_SetBkMode'
build/sciproc.o:sciproc.c:(.text+0x5db): undefined reference to `__imp_SetTextColor'
build/sciproc.o:sciproc.c:(.text+0x623): undefined reference to `__imp_SetBkMode'
build/sciproc.o:sciproc.c:(.text+0x67b): undefined reference to `__imp_SetBkColor'
build/sciproc.o:sciproc.c:(.text+0x69b): undefined reference to `__imp_SetTextColor'
..\ratpak\build/ratpak.lib(rat.o):rat.c:(.text+0x2f): undefined reference to `divnumx(_number**, _number*)'
..\ratpak\build/ratpak.lib(rat.o):rat.c:(.text+0x3b): undefined reference to `divnumx(_number**, _number*)'
..\ratpak\build/ratpak.lib(conv.o):conv.c:(.text+0x494): undefined reference to `divnumx(_number**, _number*)'
..\ratpak\build/ratpak.lib(conv.o):conv.c:(.text+0xcaf): undefined reference to `divnum(_number**, _number*, unsigned long)'
..\ratpak\build/ratpak.lib(conv.o):conv.c:(.text+0x10d4): undefined reference to `mulnum(_number**, _number*, unsigned long)'
..\ratpak\build/ratpak.lib(conv.o):conv.c:(.text+0x1141): undefined reference to `mulnum(_number**, _number*, unsigned long)'
..\ratpak\build/ratpak.lib(conv.o):conv.c:(.text+0x11a7): undefined reference to `mulnum(_number**, _number*, unsigned long)'
..\ratpak\build/ratpak.lib(conv.o):conv.c:(.text+0x11b5): undefined reference to `mulnum(_number**, _number*, unsigned long)'
..\ratpak\build/ratpak.lib(conv.o):conv.c:(.text+0x12f5): undefined reference to `mulnum(_number**, _number*, unsigned long)'
..\ratpak\build/ratpak.lib(conv.o):conv.c:(.text+0x138d): undefined reference to `divnum(_number**, _number*, unsigned long)'
collect2.exe: error: ld returned 1 exit status
make: *** [build/calc] Error 1

Видим, что остаются неслинковаными ряд функций. HtmlHelpW – это функция libhtmlhelp (вызов справки), __imp_SetBkMode и т.п. – функции библиотеки gdi32, оставшиеся функции не слинковались из библиотеки ratpak. В первых 2 случаях добавляем линковку в `Makefile`:

LIBS = -lratpak -lgdi32 –lhtmlhelp

Библиотека htmlhelp входит в состав Windows SDK. Одинако поскольку GCC не поддерживает пробелы в пути, то просто скопируем эту библиотеку в папку lib и укажем путь к ней.

LIBDIR = -L..\ratpak\build -Llib

В третьем случае проблема в модификаторе inline функций mulnum, divnum в num.c и mulnumx, divnumx в basex.c. Для GCC его нужно удалить.

Пробуем собрать:

Calc build output - 3
g++ build/calc.o build/input.o build/scicomm.o build/scidisp.o build/scifunc.o build/scikeys.o build/scimath.o build/scimenu.o build/scioper.o build/sciproc.o build/sciset.o build/scistat.o build/unifunc.o build/wassert.o  -L..\ratpak\build -Llib -lratpak -lgdi32 -lhtmlhelp -o build/calc
lib/htmlhelp.lib(o:/w8rtm.obj.amd64fre/enduser/helpengines/htmlhelp/src/htmlhelp/objfre/amd64/init.obj):(.text[HtmlHelpW]+0xe0): undefined reference to `__security_check_cookie'
lib/htmlhelp.lib(o:/w8rtm.obj.amd64fre/enduser/helpengines/htmlhelp/src/htmlhelp/objfre/amd64/init.obj):(.text[HtmlHelpA]+0xe0): undefined reference to `__security_check_cookie'
lib/htmlhelp.lib(o:/w8rtm.obj.amd64fre/enduser/helpengines/htmlhelp/src/htmlhelp/objfre/amd64/init.obj):(.text[?GetRegisteredLocation@@YAHPEAD@Z]+0x111): undefined reference to `__security_check_cookie'
lib/htmlhelp.lib(o:/w8rtm.obj.amd64fre/enduser/helpengines/htmlhelp/src/htmlhelp/objfre/amd64/init.obj):(.xdata[$unwind$HtmlHelpW]+0x10): undefined reference to `__GSHandlerCheck'
lib/htmlhelp.lib(o:/w8rtm.obj.amd64fre/enduser/helpengines/htmlhelp/src/htmlhelp/objfre/amd64/init.obj):(.xdata[$unwind$HtmlHelpA]+0x10): undefined reference to `__GSHandlerCheck'
lib/htmlhelp.lib(o:/w8rtm.obj.amd64fre/enduser/helpengines/htmlhelp/src/htmlhelp/objfre/amd64/init.obj):(.xdata[$unwind$?GetRegisteredLocation@@YAHPEAD@Z]+0x18): undefined reference to `__GSHandlerCheck'
collect2.exe: error: ld returned 1 exit status
make: *** [build/calc] Error 1

Видим, что еще нет библиотеки c __security_check_cookie и __GSHandler_Check. Выяснилось, что это связано с флагом /GS компилятора Visual Studio, поскольку я изначально взял htmlhelp из Windows SDK 8.0. /GS флаг является аналогом  -fstack-protector-strong для GCC. Соотвественно, для корректной линковки __security_check_cookie нужно добавить – -lbufferoverflowu (из SDK), а для __GSHandler_Check-lruntmchk, которую я не нашел, или можно слинковаться с gshandler.obj, этот вариант работает. Однако в целом htmlhelp скомпилирован в статическую библиотеку виндовсовским компилятором, что не очень хорошо.

Поэтому я решил поискать и попробовать собрать htmlhelp из исходников. Поиск меня привел к следующей директории:

NT\enduser\stuff\hhctrl\

В которой содержатся куча файлов и хедер htmlhelp.h. Осознав, что работы предстоит много, решил все это отложить на потом, но, cлучайно перейдя на уровень выше, увидел папку htmlhelp.

NT\enduser\stuff\htmlhelp\

Заглянув во внутрь, увидел только один файл init.cpp. Решил попробовать собрать, адаптировав Makefile от ratpak и, к моему удивлению, она собралась без проблем!

Htmlhelp build output - 1
mkdir build
g++ -c  -I..\hhctrl -Os -o build/init.o  init.cpp
ar ru build/htmlhelp.lib build/init.o
ar: creating build/htmlhelp.lib
ranlib build/htmlhelp.lib

Быстренько прописав путь к этой либе в Makefile калькулятора, убеждаемся, что все собралось и слинковалось успешно.

LIBDIR = -L..\ratpak\build -L..\..\..\..\enduser\stuff\htmlhelp\build
Calc build output - 4
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/calc.o  calc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/input.o  input.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scicomm.o  scicomm.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scidisp.o  scidisp.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scifunc.o  scifunc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scikeys.o  scikeys.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scimath.o  scimath.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scimenu.o  scimenu.c
In file included from calc.c:29:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from calc.c:26:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

In file included from input.c:14:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from input.c:13:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

In file included from scicomm.c:15:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69scidisp.c:14,
                 from :
scicalc.h:29unifunc.h:6:,
                 from  scicomm.c:13warning: :
"ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scidisp.c:13:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

In file included from scikeys.c:3:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scikeys.c:1:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

In file included from scimath.c:4:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scimath.c:1
scimenu.c:26C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668::
 unifunc.h:6: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scimenu.c:25:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scioper.o  scioper.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/sciproc.o  sciproc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/sciset.o  sciset.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/scistat.o  scistat.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/unifunc.o  unifunc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -O0 -o build/wassert.o  wassert.c
In file included from sciset.c:22:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from sciset.c:21:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

In file included from scistat.c:35:
unifunc.h:6: warning: "ARRAYSIZE" redefined
 #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x))

In file included from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/minwindef.h:163,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windef.h:8,
                 from C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/windows.h:69,
                 from scicalc.h:29,
                 from scistat.c:33:
C:/Qt/Tools/mingw810_64/x86_64-w64-mingw32/include/winnt.h:668: note: this is the location of the previous definition
 #define ARRAYSIZE(A) RTL_NUMBER_OF_V2(A)

g++ build/calc.o build/input.o build/scicomm.o build/scidisp.o build/scifunc.o build/scikeys.o build/scimath.o build/scimenu.o build/scioper.o build/sciproc.o build/sciset.o build/scistat.o build/unifunc.o build/wassert.o  -L..\ratpak\build -L..\..\..\..\enduser\stuff\htmlhelp\build -lratpak -lgdi32 -lhtmlhelp -o build/calc

Итого мы имеем билд нашего калькулятора. Сделаем пару косметических фиксов. Чтобы убрать варнинги, удалим #define ARRAYSIZE(x)   (sizeof(x) / sizeof(*x)) из unifunc.h.

И включим Os оптимизацию. В этом случае мы получим следующую картину:

OPT = -Os
Calc build output - 5
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/calc.o  calc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/input.o  input.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scicomm.o  scicomm.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scidisp.o  scidisp.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scifunc.o  scifunc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scikeys.o  scikeys.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scimath.o  scimath.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scimenu.o  scimenu.c
calc.c: In function 'int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)':
calc.c:232:48: warning: iteration 84 invokes undefined behavior [-Waggressive-loop-optimizations]
             rgpsz[nx] = psz + (INT_PTR)rgpsz[nx];
                                        ~~~~~~~~^
calc.c:231:26: note: within this loop
         for (nx = 0 ; nx <= CSTRINGS ; nx++)
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scioper.o  scioper.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/sciproc.o  sciproc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/sciset.o  sciset.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scistat.o  scistat.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/unifunc.o  unifunc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/wassert.o  wassert.c
sciset.c: In function 'void ActivateButtons()':
sciset.c:51:29: warning: iteration 7 invokes undefined behavior [-Waggressive-loop-optimizations]
                 EnableWindow( GetDlgItem(g_hwndDlg, aDecOnlyKeys[i]),
                 ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                               bDecMode );
                               ~~~~~~~~~~
sciset.c:49:28: note: within this loop
             for ( i = 0; i <= ARRAYSIZE(aDecOnlyKeys) ; i++ )
                            ^
g++ build/calc.o build/input.o build/scicomm.o build/scidisp.o build/scifunc.o build/scikeys.o build/scimath.o build/scimenu.o build/scioper.o build/sciproc.o build/sciset.o build/scistat.o build/unifunc.o build/wassert.o build/calc.rc.o -L..\ratpak\build -L..\..\..\..\enduser\stuff\htmlhelp\build -lratpak -lgdi32 -lhtmlhelp -o build/calc

Чтобы это поправить, добавим флаг -fno-aggressive-loop-optimizations.

Итого имеем чистый вывод компиляции:

Calc build output - 6
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/calc.o  calc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/input.o  input.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scicomm.o  scicomm.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scidisp.o  scidisp.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scifunc.o  scifunc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scikeys.o  scikeys.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scimath.o  scimath.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scimenu.o  scimenu.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scioper.o  scioper.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/sciproc.o  sciproc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/sciset.o  sciset.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/scistat.o  scistat.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/unifunc.o  unifunc.c
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -o build/wassert.o  wassert.c
g++ build/calc.o build/input.o build/scicomm.o build/scidisp.o build/scifunc.o build/scikeys.o build/scimath.o build/scimenu.o build/scioper.o build/sciproc.o build/sciset.o build/scistat.o build/unifunc.o build/wassert.o build/calc.rc.o -L..\ratpak\build -L..\..\..\..\enduser\stuff\htmlhelp\build -lratpak -lgdi32 -lhtmlhelp -o build/calc

Запуск калькулятора

Попытавшись запустить калькулятор, увидим следующую картину:

Это означает, что линкеру нужно указать линковку графического приложения вместо консольного. Для GCC это -mwindows.

LDFLAGS = $(LIBDIR) $(LIBS) -fno-aggressive-loop-optimizations -mwindows

Собираем, запускаем, но не видим никаких окон. Запустив менеджер задач видим, что в calc есть в списках процессов

Т.е. наше приложение запустилось, но скорее всего не хватает описания графического интерфейса. Для ОС Windows данная информация находится в файлах ресурсов с расширением .rc. Чтобы подключить calc.rc файл, его нужно скомпилировать в объектный файл calc.rc.o, а затем слинковать вместе с бинарником. В пакете MinGW-64 есть компилятор ресурсов windres, его и будем использовать.

Попробуем скомпилировать calc.rc в объектный файл командой:

windres calc.rc -o build/calc.rc.o

Видим следующую ошибку:

calc.rc:12:10: fatal error: winres.h: No such file or directory
 #include "winres.h"
          ^~~~~~~~~~
compilation terminated.
windres: preprocessing failed.

Чтобы это поправить заменим winres.h на windows.h и пробуем скомпилировать заново. В этом случае вывода нет, и в build появляется необходимый объектный файл calc.rc.o.

1) Добавим в Makefile следующий код для линковки .rc.o:

RC = windres
RES_SOURCES = calc.rc

RES_OBJ = $(addprefix $(BUILD_DIR)/,$(notdir $(RES_SOURCES:.rc=.rc.o)))

$(BUILD_DIR)/%.o: %.rc Makefile | $(BUILD_DIR) 
            $(RC) $^ -o $@

$(BUILD_DIR)/$(TARGET): $(OBJECTS) Makefile
            $(CC) $(OBJECTS) $(RES_OBJ) $(LDFLAGS) -o $@

Я пробовал добавить билд .rc файла в Makefile, но компиляция этого файла не получалась через Makefile (его билд просто игнорировался). Поэтому приходится делать это вручную через windres. Если кто-нибудь знает, как это поправить, буду рад узнать в комментариях.

В итоге все слинковалось, а в папке build мы имеем готовый бинарник calc.exe. Запустив ее, мы увидим наше старое знакомое приложение:

Наконец, добавим флаг –Wall, чтобы увидеть все предупреждения, и скомпилируем:

Last calc build output
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/calc.o  calc.c
In file included from scimath.h:22,
                 from scicalc.h:31,
                 from calc.c:26:
..\ratpak\ratpak.h:1: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning( disable : 4200 )

calc.c: In function 'void EverythingResettingNumberSetup()':
calc.c:496:19: warning: comparison of integer expressions of different signedness: 'int' and 'long long unsigned int' [-Wsign-compare]
     for( i = 0; i < ARRAYSIZE(ghnoParNum); i++ )
                   ^
calc.c:500:19: warning: comparison of integer expressions of different signedness: 'int' and 'long long unsigned int' [-Wsign-compare]
     for( i = 0; i < ARRAYSIZE(ghnoPrecNum); i++ )
                   ^
calc.c: In function 'void InitSciCalc(BOOL)':
calc.c:676:23: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
         if (hDispEdit = GetDlgItem(g_hwndDlg, IDC_DISPLAY))
             ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
calc.c:519:13: warning: unused variable 'nLastSepLen' [-Wunused-variable]
     int     nLastSepLen;
             ^~~~~~~~~~~
calc.c:521:13: warning: unused variable 'hMenu' [-Wunused-variable]
     HMENU   hMenu;
             ^~~~~
calc.c: In function 'int WinMain(HINSTANCE, HINSTANCE, LPSTR, int)':
calc.c:237:22: warning: 'psz' may be used uninitialized in this function [-Wmaybe-uninitialized]
             LocalFree(psz);
             ~~~~~~~~~^~~~~
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/input.o  input.c
In file included from scimath.h:22,
                 from scicalc.h:31,
                 from input.c:13:
..\ratpak\ratpak.h:1: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning( disable : 4200 )

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/scicomm.o  scicomm.c
In file included from scimath.h:22,
                 from scicalc.h:31,
                 from scicomm.c:13:
..\ratpak\ratpak.h:1: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning( disable : 4200 )

scicomm.c: In function 'void RealProcessCommands(WPARAM)':
scicomm.c:295:12: warning: suggest explicit braces to avoid ambiguous 'else' [-Wdangling-else]
         if (nLastCom >= IDC_AND && nLastCom <= IDC_PWR)
            ^
scicomm.c:421:20: warning: suggest explicit braces to avoid ambiguous 'else' [-Wdangling-else]
                 if ((nLastCom >= IDC_AND) && (nLastCom <= IDC_PWR))
                    ^
scicomm.c:502:32: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
                 while (nOpCode = nPrecOp[--nPrecNum])
                        ~~~~~~~~^~~~~~~~~~~~~~~~~~~~~
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/scidisp.o  scidisp.c
In file included from scimath.h:22,
                 from scicalc.h:31,
                 from scidisp.c:13:
..\ratpak\ratpak.h:1: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning( disable : 4200 )

scidisp.c: In function 'void DisplayNum()':
scidisp.c:90:12: warning: suggest explicit braces to avoid ambiguous 'else' [-Wdangling-else]
         if ( ghnoNum )
            ^
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/scifunc.o  scifunc.c
In file included from scimath.h:22,
                 from scicalc.h:31,
                 from scifunc.c:36:
..\ratpak\ratpak.h:1: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning( disable : 4200 )

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/scikeys.o  scikeys.c
In file included from scimath.h:22,
                 from scicalc.h:31,
                 from scikeys.c:1:
..\ratpak\ratpak.h:1: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning( disable : 4200 )

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/scimath.o  scimath.c
In file included from scimath.h:22,
                 from scicalc.h:31,
                 from scimath.c:3:
..\ratpak\ratpak.h:1: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning( disable : 4200 )

scimath.c: In function 'int QuickLog2(int)':
scimath.c:61:15: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
     if ( iNum = iNum >> 1 )
          ~~~~~^~~~~~~~~~~
scimath.c:64:22: warning: suggest parentheses around assignment used as truth value [-Wparentheses]
         while ( iNum = iNum >> 1 )
                 ~~~~~^~~~~~~~~~~
scimath.c: In function 'void UpdateMaxIntDigits()':
scimath.c:90:9: warning: variable 'iRemainderBits' set but not used [-Wunused-but-set-variable]
     int iRemainderBits;
         ^~~~~~~~~~~~~~
scimath.c: In function 'void BaseOrPrecisionChanged()':
scimath.c:112:17: warning: unused variable 'dwWordBitWidth' [-Wunused-variable]
     extern LONG dwWordBitWidth;
                 ^~~~~~~~~~~~~~
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/scimenu.o  scimenu.c
In file included from scimath.h:22,
                 from scicalc.h:31,
                 from scimenu.c:25:
..\ratpak\ratpak.h:1: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning( disable : 4200 )

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/scioper.o  scioper.c
In file included from scimath.h:22,
                 from scicalc.h:31,
                 from scioper.c:17:
..\ratpak\ratpak.h:1: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning( disable : 4200 )

scioper.c:26:53: warning: "/*" within comment [-Wcomment]
 * Routines to perform standard operations &|^~<<>>+-/*% and pwr.

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/sciproc.o  sciproc.c
In file included from scimath.h:22,
                 from scicalc.h:31,
                 from sciproc.c:25:
..\ratpak\ratpak.h:1: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning( disable : 4200 )

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/sciset.o  sciset.c
In file included from scimath.h:22,
                 from scicalc.h:31,
                 from sciset.c:21:
..\ratpak\ratpak.h:1: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning( disable : 4200 )

sciset.c: In function 'void ActivateButtons()':
sciset.c:49:28: warning: comparison of integer expressions of different signedness: 'int' and 'long long unsigned int' [-Wsign-compare]
             for ( i = 0; i <= ARRAYSIZE(aDecOnlyKeys) ; i++ )
                            ^
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/scistat.o  scistat.c
In file included from scimath.h:22,
                 from scicalc.h:31,
                 from scistat.c:33:
..\ratpak\ratpak.h:1: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning( disable : 4200 )

scistat.c: In function 'void SetStat(BOOL)':
scistat.c:100:17: warning: comparison of integer expressions of different signedness: 'int' and 'long long unsigned int' [-Wsign-compare]
     for ( i=0; i<ARRAYSIZE(aStatOnlyKeys); i++)
                 ^
g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/unifunc.o  unifunc.c
In file included from scimath.h:22,
                 from scicalc.h:31,
                 from unifunc.c:13:
..\ratpak\ratpak.h:1: warning: ignoring #pragma warning  [-Wunknown-pragmas]
 #pragma warning( disable : 4200 )

g++ -c -DWIN32 -DW3 -DWINNT -DUNICODE -D_UNICODE -DUSE_MIRRORING -I..\ratpak -I..\inc  -Os -fno-aggressive-loop-optimizations -Wall -o build/wassert.o  wassert.c
g++ build/calc.o build/input.o build/scicomm.o build/scidisp.o build/scifunc.o build/scikeys.o build/scimath.o build/scimenu.o build/scioper.o build/sciproc.o build/sciset.o build/scistat.o build/unifunc.o build/wassert.o build/calc.rc.o -L..\ratpak\build -L..\..\..\..\enduser\stuff\htmlhelp\build -lratpak -lgdi32 -lhtmlhelp -mwindows -o build/calc

Тут видим ощутимое количество предупреждений, среди них:

  1. unknown-pragmas (#pragma warning)

  2. sign-compare

  3. parentheses

  4. unused-variable

  5. maybe-uninitialized

  6. dangling-else

  7. unused-but-set-variable

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

В конце приведу финальный код файлов Makefile.

Сalc final Makefile
TARGET = calc
BUILD_DIR = build
OPT = -Os
CC = g++
RC = windres

C_SOURCES = calc.c      \
            input.c     \
            scicomm.c   \
            scidisp.c   \
            scifunc.c   \
            scikeys.c   \
            scimath.c   \
            scimenu.c   \
            scioper.c   \
            sciproc.c   \
            sciset.c    \
            scistat.c   \
            unifunc.c   \
            wassert.c

RES_SOURCES = calc.rc
		
C_DEFS = -DWIN32 \
         -DW3 \
         -DWINNT \
         -DUNICODE \
         -D_UNICODE \
         -DUSE_MIRRORING

C_INCLUDES = -I..\ratpak \
             -I..\inc \

CFLAGS += $(C_DEFS) $(C_INCLUDES) $(OPT) -fno-aggressive-loop-optimizations -Wall

LIBS = -lratpak -lgdi32 -lhtmlhelp
LIBDIR = -L..\ratpak\build -L..\..\..\..\enduser\stuff\htmlhelp\build
LDFLAGS = $(LIBDIR) $(LIBS) -mwindows

OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
RES_OBJ = $(addprefix $(BUILD_DIR)/,$(notdir $(RES_SOURCES:.rc=.rc.o)))

$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 
	$(CC) -c $(CFLAGS) -o $@  $<

$(BUILD_DIR)/%.o: %.rc Makefile | $(BUILD_DIR) 
	$(RC) $^ -o $@

$(BUILD_DIR)/$(TARGET): $(OBJECTS) Makefile
	$(CC) $(OBJECTS) $(RES_OBJ) $(LDFLAGS) -o $@

$(BUILD_DIR):
	mkdir $@
	
all: 
	$(TARGET)
	
clean:
	-rm -fR $(BUILD_DIR)

Ratpak final Makefile
TARGET = ratpak.lib
BUILD_DIR = build
OPT = -Os

C_SOURCES = rat.c \
			num.c \
			conv.c \
			debug.c \
			itrans.c \
			trans.c \
			transh.c \
			itransh.c \
			logic.c \
			fact.c \
			basex.c \
			exp.c \
			support.c \

CC = g++

C_DEFS = -DWIN32 \
		 -DW3 \
		 -DWINNT \
		 -DUNICODE \
		 -D_UNICODE \
		 -DNOMINMAX

C_INCLUDES = -I.

CFLAGS += $(C_DEFS) $(C_INCLUDES) $(OPT)

all: $(BUILD_DIR)/$(TARGET)

OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.c=.o)))
vpath %.c $(sort $(dir $(C_SOURCES)))

$(BUILD_DIR)/%.o: %.c Makefile | $(BUILD_DIR) 
	$(CC) -c $(CFLAGS) -o $@  $<

$(BUILD_DIR)/$(TARGET): $(OBJECTS)
	ar ru $@ $^
	ranlib $@

$(BUILD_DIR):
	mkdir $@

clean:
	-rm -fR $(BUILD_DIR)

Htmlhelp final Makefile
TARGET = htmlhelp.lib
BUILD_DIR = build
OPT = -Os

C_SOURCES = init.cpp

CC = g++

C_DEFS =

C_INCLUDES = -I..\hhctrl

CFLAGS += $(C_DEFS) $(C_INCLUDES) $(OPT)

all: $(BUILD_DIR)/$(TARGET)

OBJECTS = $(addprefix $(BUILD_DIR)/,$(notdir $(C_SOURCES:.cpp=.o)))

$(BUILD_DIR)/%.o: %.cpp Makefile | $(BUILD_DIR) 
	$(CC) -c $(CFLAGS) -o $@  $<

$(BUILD_DIR)/$(TARGET): $(OBJECTS)
	ar ru $@ $^
	ranlib $@

$(BUILD_DIR):
	mkdir $@		

clean:
	-rm -fR $(BUILD_DIR)

Заключение

В итоге имеем скомилированную версию калькулятора версии Windows XP с помощью GCC x64, который запускается на современных версиях Windows. В отличие от современной версии калькулятора, потребляющего 18.7 МБайта памяти, он потребляет всего 1.0 МБайт.

Собранное приложение работает за исключением меню help, которое не появляется. Вероятно, что это связано это с библиотекой hhctrl, но ее собирать будем уже как-нибудь в другой раз. Если есть идеи, что стоило бы еще запустить из Windows XP, пишите в комментариях.

Надеюсь, статья была интересной и полезной. Всем спасибо за внимание!

Комментарии (45)


  1. dlinyj
    04.09.2023 12:00
    +7

    Очень хабратортно! Спасибо за статью!


  1. AndreyDmitriev
    04.09.2023 12:00
    +6

    Если есть идеи, что стоило бы еще запустить из Windows XP, пишите в комментариях.

    А соберите, пожалуйста, старенький Task Manager, если не лень.

    Я, кстати, именно из этих утёкших исходников почерпнул, что если там зажать клавишу Control, и удерживая её, вызвать меню File->Run new task, то вместо окна запуска новой задачи выскочит консоль, запущенная с правами администратора, чем и пользуюсь иногда.


    1. Schokn-Itrch
      04.09.2023 12:00
      +3

      На https://win7games.com есть Task Manager из Windows 7, который практически идентичен wxp/w2k3, и не только он, но и калькулятор и игры и paint.


      1. Bizonozubr
        04.09.2023 12:00

        А исходники есть?


    1. ZhksB Автор
      04.09.2023 12:00
      +1

      Я хотел начать c Task Manager. Сравнив объем работы, который нужно было сдалать, в итоге решил начать с чего-либо попроще и с меньшим количеством зависимостей. Последние имеют свойство накапливаться, и их всех нужно тоже собирать. А это куча времени. Сама подготовка материала для статьи (не сам билд) заняла несколько недель.


    1. ZhksB Автор
      04.09.2023 12:00
      +4

      В целом я считаю, что тема до конца не раскрыта. В планах есть сбилдить и запустить этот же калькулятор под Linux. Если он собирается gcc под виндовс, то и под линуксом тоже должно получиться. Единственное, что нужны библиотеки-конвертеры системных вызовов windows-linux. Но это тема для отдельной статьи :)


      1. skyazimuth
        04.09.2023 12:00

        А как .rc прикручивать к Линуксу?


        1. ZhksB Автор
          04.09.2023 12:00

          Пока не разбирался. Но думаю, что есть варианты.


  1. avbochagov
    04.09.2023 12:00
    +18

    Голосую за Сапера!


    1. ZhksB Автор
      04.09.2023 12:00

      К сожалению, не нашел его исходники. Есть только разные виды солитера.


  1. NeoCode
    04.09.2023 12:00
    +4

    А интересно, за это время появились какие-нибудь большие хакерские проекты с этими исходниками? Самое очевидное - попытаться дописать недостающие функции ядра из win7/10 с сохранением старого доброго GUI.


    1. boris768
      04.09.2023 12:00
      +2

      были всякие попытки, собственно автор и указал на одну из самых известных, содержит множество фиксов, в основном необходимые для успешной сборки на свежих системах, но есть и обновления корневых сертификатов, добавление EncodePointer и DecodePointer.

      Может кто-то кроме меня знает какой-либо проект, который до сих пор не заглох, ибо все что я видел - уже так или иначе заброшены.


    1. Blaukovitch
      04.09.2023 12:00
      +5

      попытаться дописать недостающие функции ядра из win7/10 с сохранением старого доброго GUI.

      После успешного портирования Chrome 114 под Windows 7, скажу так что ядро в 7/10 - это реферанс в сторону "контенеризации" и изоляции процессов, что негативно сказывается на производительности. Хотя часть низкоуровневых функций прекрасно перепишется и "встанет" нормально в работу, при успешной реализации всего остального даже Windows XP (лучше 2k3) заметно просядет в производительности.

      Наиболее целесообразно попробовать:

      1. Скомпилить XP/2k3 x86 с поддержкой SSE2;

      2. Пофиксить явные вырвиглазные вещи GUI типа невозможности замены уже существующего файла в папке;

      3. В идеале нужен DirectX11/10/DXGI, чтобы современный Chrome браузер запустить & в игрушки поиграть. С другой стороны - кто-то должен переписать видеодрайвера. Или прокидывать это через OpenGL 4.5 а-ля Linux;

        -Так навскидку.


      1. ZhksB Автор
        04.09.2023 12:00

        Много чего можно придумать. Например, прикрутить графический интерфейс Luna к линуксовому ядру. Это позволит использовать последние версии софта и драйверов. Причем версии ядра можно регулировать в зависимости от степени старости железа.


      1. nagayev
        04.09.2023 12:00
        +1

        Возможно Вам будет интересен reactos.

        Это попытка сделать open source Windows XP, точнее Server 2003.

        Совместимость с приложениями под Windows XP там очень даже достойная.


    1. ZhksB Автор
      04.09.2023 12:00
      +2

      Я думаю, что самая большая проблема - это лицензирование. Официально с кодом ничего не получится сделать, разве что можно использовать в образовательно-исследовательских целях для энтузиастов. Если бы Майкрософт разрешила использовать эти исходники, я думаю, что всякие проекты на базе XP росли бы как грибы после дождя.
      А так можно потратить огромное количество времени, а результате Майкрософт прихлопнет репу :(.


  1. Bartez
    04.09.2023 12:00
    +5

    В WindowsXP был очень лёгкий и удобный просмотрщик изображений. С удовольствием бы им пользовался в 10-ке.


    1. rafaelpro
      04.09.2023 12:00
      +1

      qView ( https://github.com/jurplel/qView ) можно использовать, схожий open-source просмотрщик, можно еще поднастроить, чтобы был более удобным.



  1. mini_nightingale
    04.09.2023 12:00
    +8

    Это было интересно.

    В итоге все слинковалось, а в папке build мы имеет готовую аппликацию calc.exe.

    О времена, о нравы. Тогда уж не в папке а в фолдере...


    1. FreeNickname
      04.09.2023 12:00
      +7

      Аппликация "Калькулятор"
      Аппликация "Калькулятор"
      Аппликация "Калькулятор"

      Источник


    1. ZhksB Автор
      04.09.2023 12:00
      +3

      Исправил


      1. FreeNickname
        04.09.2023 12:00

        Вы лучше всех :) Спасибо!


  1. Veratam
    04.09.2023 12:00

    Все просто, хотелось собрать калькулятор, который может считать без подключения к интернету.

    Что интересно, gnome-calculator тоже не умеет считать без подключения к интернету, уже 3 года как минимум.


    1. voldemar_d
      04.09.2023 12:00

      А зачем калькулятору интернет?

      Он через запросы к гуглу считает?


  1. ZhksB Автор
    04.09.2023 12:00
    +1

    Мне интерсен вопрос в части про статистику количества кода в архиве. Я запускал cloc на свежеразархивированной версии исходников. Но при этом есть файлы Qt. Любопытно, это реальные файлы Qt или просто анализатор некорректно приписывает файлы Qt? В любом случае интересно нету ли в этих файлах конфликта лицензий.


  1. XenRE
    04.09.2023 12:00

    В итоге имеем скомилированную версию калькулятора версии Windows XP с помощью GCC x64, который запускается на современных версиях Windows.

    А обычный калькулятор из XP разве не запускается на десятке?
    А этот новоскомпиленный калькулятор запуститься на XP?


    1. ZhksB Автор
      04.09.2023 12:00

      Новоскомпиленый на чистом XP без библиотек из MinGW точно нет. И обычно XP 32-битная, а эта версия калькулятора 64 бит. Билд 32 битного калькулятора сделать сложнее с помощью GCC, поскольку там много asm вставок, заточенных на майкрософтовский компилятор.
      Касательно готового калькулятора с XP на 10-ке, то должно работать.


    1. skyazimuth
      04.09.2023 12:00
      +3

      Обычный калькулятор XP запускается на Десятке. Его как раз и использую :)


  1. forthuse
    04.09.2023 12:00
    +1

    O_o Cloc даже Forth код нашёл в исходниках XP. :)


    1. vadimk91
      04.09.2023 12:00

      Я тоже удивился, а ещё некий язык (?) Igor Pro


      1. ZhksB Автор
        04.09.2023 12:00

        Igor Pro реально существует, используется для анализа научных данных.


  1. KanuTaH
    04.09.2023 12:00
    -1

    В первом случае пропущен тип (!) в support.c на строках 41 и 64.

    Implicit int rule, в C89 вполне легальная штука. В C99 и далее компилятор обязан выдавать как минимум предупреждение (которое, конечно, можно при желании заглушить), но не обязан считать это ошибкой: "after issuing the diagnostic, an implementation may choose to assume an implicit int and continue to translate the program in order to support existing source code that exploits this feature".


  1. alan008
    04.09.2023 12:00
    +1

    Пинбол "Звездный кадет". Но его исходников скорее всего нет ) И с ним была интересная история

    https://habr.com/ru/articles/163105/

    и еще

    https://habr.com/ru/articles/579100/


    1. boris768
      04.09.2023 12:00
      +1

      и эта история имеет неожиданный, но очень счастливый финал


      1. alan008
        04.09.2023 12:00

        Действительно неожиданный!
        Комментарий на гитхабе:


        On 64-bit bug that killed the game


        I did not find it, decompiled game worked in x64 mode on the first try.
        It was either lost in decompilation or introduced in x64 port/not present in x86 build.
        Based on public description of the bug (no ball collision), I guess that the bug was in TEdgeManager::TestGridBox


      1. ZhksB Автор
        04.09.2023 12:00

        Если его собрать GCC x64 в связке с анализаторами и санитайзерами, есть шанс, что баг бы тоже исчез. Ведь проект собирался майкрософтовским компилятором по умолчанию...


    1. ZhksB Автор
      04.09.2023 12:00

      Посмотрел, его исходников действительно нет в играх:
      NT\shell\osshell\games\
      Хотя упоминание в корневом файле dirs присутствует. Странно, учитывая что эта версия исходников очень старая (SP1). Может их куда переместили в другое место проекта


  1. stanukih
    04.09.2023 12:00

    Здесь интересно сравнить, скомпилированный бинарник gcc, clang, vs. Вес, потребление памяти


  1. sergio_nsk
    04.09.2023 12:00
    +1

    Отлично! Где бы его скачать ещё. А то задолбался переключать новый калькулятор между программерским и научным режимами.


    1. ZhksB Автор
      04.09.2023 12:00

      Можно скачать из установленной XP. Или собирать самому из исходников. Думал сделать патч, но в итоге пока отказался, все же лицензия не позволяет распространять код. Поэтому не хотел бы это делать в явном виде.


      1. sergio_nsk
        04.09.2023 12:00

        Скопировал с 32-битной виртуалки. Работает в W10. Только он не запоминает режим после закрытия и нового запуска приложение. Ну хоть что-то.
        Ему нельзя передать View mode через командную строку?


  1. kgenius
    04.09.2023 12:00

    А можно от куда-нибудь скачать итоговый рабочий вариант?



  1. Mike-M
    04.09.2023 12:00
    +1

    [немного не в тему] Калькулятор в Windows 10 — практически единственное встроенное приложение, которым я с удовольствием ежедневно пользуюсь.