Дисклеймер
Все действия, описанные автором в статье, сделаны исключительно в исследовательских и образовательных целях. 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.
Настройка окружения
Определимся, что нам потребуется:
Хост с установленной Windows. В моем случае Windows 10.
Qt. Я использую как QtCreator, так и порт GCC для Windows MinGW-64. Устанавливал оба с помощью Qt Maintanance Tool. После установки компилятор необходимо добавить в Path.
Собирать будем с помощью
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
Тут видим ощутимое количество предупреждений, среди них:
unknown-pragmas (#pragma warning)
sign-compare
parentheses
unused-variable
maybe-uninitialized
dangling-else
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)
AndreyDmitriev
04.09.2023 12:00+6Если есть идеи, что стоило бы еще запустить из Windows XP, пишите в комментариях.
А соберите, пожалуйста, старенький Task Manager, если не лень.
Я, кстати, именно из этих утёкших исходников почерпнул, что если там зажать клавишу Control, и удерживая её, вызвать меню File->Run new task, то вместо окна запуска новой задачи выскочит консоль, запущенная с правами администратора, чем и пользуюсь иногда.
Schokn-Itrch
04.09.2023 12:00+3На https://win7games.com есть Task Manager из Windows 7, который практически идентичен wxp/w2k3, и не только он, но и калькулятор и игры и paint.
ZhksB Автор
04.09.2023 12:00+1Я хотел начать c Task Manager. Сравнив объем работы, который нужно было сдалать, в итоге решил начать с чего-либо попроще и с меньшим количеством зависимостей. Последние имеют свойство накапливаться, и их всех нужно тоже собирать. А это куча времени. Сама подготовка материала для статьи (не сам билд) заняла несколько недель.
ZhksB Автор
04.09.2023 12:00+4В целом я считаю, что тема до конца не раскрыта. В планах есть сбилдить и запустить этот же калькулятор под Linux. Если он собирается gcc под виндовс, то и под линуксом тоже должно получиться. Единственное, что нужны библиотеки-конвертеры системных вызовов windows-linux. Но это тема для отдельной статьи :)
NeoCode
04.09.2023 12:00+4А интересно, за это время появились какие-нибудь большие хакерские проекты с этими исходниками? Самое очевидное - попытаться дописать недостающие функции ядра из win7/10 с сохранением старого доброго GUI.
boris768
04.09.2023 12:00+2были всякие попытки, собственно автор и указал на одну из самых известных, содержит множество фиксов, в основном необходимые для успешной сборки на свежих системах, но есть и обновления корневых сертификатов, добавление EncodePointer и DecodePointer.
Может кто-то кроме меня знает какой-либо проект, который до сих пор не заглох, ибо все что я видел - уже так или иначе заброшены.
Blaukovitch
04.09.2023 12:00+5попытаться дописать недостающие функции ядра из win7/10 с сохранением старого доброго GUI.
После успешного портирования Chrome 114 под Windows 7, скажу так что ядро в 7/10 - это реферанс в сторону "контенеризации" и изоляции процессов, что негативно сказывается на производительности. Хотя часть низкоуровневых функций прекрасно перепишется и "встанет" нормально в работу, при успешной реализации всего остального даже Windows XP (лучше 2k3) заметно просядет в производительности.
Наиболее целесообразно попробовать:
Скомпилить XP/2k3 x86 с поддержкой SSE2;
Пофиксить явные вырвиглазные вещи GUI типа невозможности замены уже существующего файла в папке;
-
В идеале нужен DirectX11/10/DXGI, чтобы современный Chrome браузер запустить & в игрушки поиграть. С другой стороны - кто-то должен переписать видеодрайвера. Или прокидывать это через OpenGL 4.5 а-ля Linux;
-Так навскидку.
ZhksB Автор
04.09.2023 12:00Много чего можно придумать. Например, прикрутить графический интерфейс Luna к линуксовому ядру. Это позволит использовать последние версии софта и драйверов. Причем версии ядра можно регулировать в зависимости от степени старости железа.
nagayev
04.09.2023 12:00+1Возможно Вам будет интересен reactos.
Это попытка сделать open source Windows XP, точнее Server 2003.
Совместимость с приложениями под Windows XP там очень даже достойная.
ZhksB Автор
04.09.2023 12:00+2Я думаю, что самая большая проблема - это лицензирование. Официально с кодом ничего не получится сделать, разве что можно использовать в образовательно-исследовательских целях для энтузиастов. Если бы Майкрософт разрешила использовать эти исходники, я думаю, что всякие проекты на базе XP росли бы как грибы после дождя.
А так можно потратить огромное количество времени, а результате Майкрософт прихлопнет репу :(.
Bartez
04.09.2023 12:00+5В WindowsXP был очень лёгкий и удобный просмотрщик изображений. С удовольствием бы им пользовался в 10-ке.
rafaelpro
04.09.2023 12:00+1qView ( https://github.com/jurplel/qView ) можно использовать, схожий open-source просмотрщик, можно еще поднастроить, чтобы был более удобным.
mini_nightingale
04.09.2023 12:00+8Это было интересно.
В итоге все слинковалось, а в папке
build
мы имеет готовую аппликациюcalc.exe
.О времена, о нравы. Тогда уж не в папке а в фолдере...
ZhksB Автор
04.09.2023 12:00+1Мне интерсен вопрос в части про статистику количества кода в архиве. Я запускал cloc на свежеразархивированной версии исходников. Но при этом есть файлы Qt. Любопытно, это реальные файлы Qt или просто анализатор некорректно приписывает файлы Qt? В любом случае интересно нету ли в этих файлах конфликта лицензий.
XenRE
04.09.2023 12:00В итоге имеем скомилированную версию калькулятора версии Windows XP с помощью GCC x64, который запускается на современных версиях Windows.
А обычный калькулятор из XP разве не запускается на десятке?
А этот новоскомпиленный калькулятор запуститься на XP?ZhksB Автор
04.09.2023 12:00Новоскомпиленый на чистом XP без библиотек из MinGW точно нет. И обычно XP 32-битная, а эта версия калькулятора 64 бит. Билд 32 битного калькулятора сделать сложнее с помощью GCC, поскольку там много asm вставок, заточенных на майкрософтовский компилятор.
Касательно готового калькулятора с XP на 10-ке, то должно работать.
skyazimuth
04.09.2023 12:00+3Обычный калькулятор XP запускается на Десятке. Его как раз и использую :)
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".
alan008
04.09.2023 12:00+1Пинбол "Звездный кадет". Но его исходников скорее всего нет ) И с ним была интересная история
https://habr.com/ru/articles/163105/
и еще
boris768
04.09.2023 12:00+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
ZhksB Автор
04.09.2023 12:00Если его собрать GCC x64 в связке с анализаторами и санитайзерами, есть шанс, что баг бы тоже исчез. Ведь проект собирался майкрософтовским компилятором по умолчанию...
ZhksB Автор
04.09.2023 12:00Посмотрел, его исходников действительно нет в играх:
NT\shell\osshell\games\
Хотя упоминание в корневом файлеdirs
присутствует. Странно, учитывая что эта версия исходников очень старая (SP1). Может их куда переместили в другое место проекта
stanukih
04.09.2023 12:00Здесь интересно сравнить, скомпилированный бинарник gcc, clang, vs. Вес, потребление памяти
sergio_nsk
04.09.2023 12:00+1Отлично! Где бы его скачать ещё. А то задолбался переключать новый калькулятор между программерским и научным режимами.
ZhksB Автор
04.09.2023 12:00Можно скачать из установленной XP. Или собирать самому из исходников. Думал сделать патч, но в итоге пока отказался, все же лицензия не позволяет распространять код. Поэтому не хотел бы это делать в явном виде.
sergio_nsk
04.09.2023 12:00Скопировал с 32-битной виртуалки. Работает в W10. Только он не запоминает режим после закрытия и нового запуска приложение. Ну хоть что-то.
Ему нельзя передать View mode через командную строку?
Mike-M
04.09.2023 12:00+1[немного не в тему] Калькулятор в Windows 10 — практически единственное встроенное приложение, которым я с удовольствием ежедневно пользуюсь.
dlinyj
Очень хабратортно! Спасибо за статью!