aboutsummaryrefslogtreecommitdiff
path: root/build.bat
blob: e87d3ac39877360b35a5018bbc79a9f93f00b9a9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
@echo off

SET DEBUG=0
if "%1"=="/d" (
    SET DEBUG=1
    shift
)
if "%1"=="test" (SET DEBUG=1)

:: Detect architecture, or use user-specified one
if "%ARCH%"=="" goto :detect_arch
if "%ARCH%"=="PORTABLE" goto :arch_done
if "%ARCH%"=="AVX2" goto :arch_done
if "%ARCH%"=="NEON" goto :arch_done

echo Unsupported architecture '%ARCH%'
exit /b 1

:detect_arch
    if "%PROCESSOR_ARCHITECTURE%"=="AMD64" (
        SET ARCH=AVX2
    ) else if "%PROCESSOR_ARCHITECTURE%"=="ARM64" (
        SET ARCH=NEON
    ) else (
        SET ARCH=PORTABLE
    )
:arch_done

:: Default value for maximum number of threads
SET THREADS=16

:: Detect Python libraries path
for /f "delims=" %%i in ('python -c "import sys; print(sys.base_prefix)"') do set PYPATH=%%i
SET PYINCLUDE=%PYPATH%\include
SET PYLIBS=%PYPATH%\libs

:: Select compiler from possibly user-set %CC% variable
:: Currently we only support clang and MSVC
if "%CC%"=="" goto :set_msvc
if /I "%CC%"=="cl" goto :set_msvc
if /I "%CC%"=="msvc" goto :set_msvc
if /I "%CC%"=="clang" goto :set_clang

echo Unsupported compiler '%CC%'
exit /b 1

:set_msvc
    SET CC=cl
    SET CXX=cl

    SET DFLAGS=/Zi /DDEBUG
    SET WARNINGS=/wd4996
    SET VARIABLES=/DTHREADS=%THREADS% /D%ARCH%
    SET OFLAGS=/O2

    if %DEBUG%==1 (SET ODFLAGS=%DFLAGS%) else (SET ODFLAGS=%OFLAGS%)
    if "%ARCH%"=="AVX2" (SET ARCHOPTS=/arch:AVX2) else (SET ARCHOPTS=)

    SET CFLAGS=/std:c11 /experimental:c11atomics %ARCHOPTS% %WARNINGS% %VARIABLES%
    SET LFLAGS=/F 16777216

    SET CC_NISSY=%CC% %CFLAGS% %ODFLAGS% /c src\nissy.c
    SET CC_SHELL=%CC% %CFLAGS% %ODFALGS% %LFLAGS% nissy.o shell\shell.c /Fe:run.exe
    SET CC_PYTHON=%CC% %CFLAGS% %LFLAGS% /I"%PYINCLUDE%" /LD /Fe:python\nissy.pyd python\nissy_module.c nissy.o /link /LIBPATH:"%PYLIBS%" python3.lib
    SET CC_TEST=%CC% %CFLAGS% %ODFLAGS% %LFLAGS% /Fe:runtest.exe nissy.o
    SET CC_TOOL=%CC% %CFLAGS% %ODFLAGS% %LFLAGS% /Fe:runtool.exe nissy.o
    SET CC_CXX=%CXX% %ODFLAGS% /std:c++20 /Fe:runcpp.exe cpp\nissy.cpp nissy.o
goto :compiler_done

:set_clang
    SET CC=clang
    SET CXX=clang++

    SET DFLAGS=-g3 -DDEBUG
    SET WARNINGS=-Wno-deprecated-declarations
    SET VARIABLES=-DTHREADS=%THREADS% -D%ARCH%
    SET OFLAGS=-O3

    if %DEBUG%==1 (SET ODFLAGS=%DFLAGS%) else (SET ODFLAGS=%OFLAGS%)
    if "%ARCH%"=="AVX2" (SET ARCHOPTS=-mavx2) else (SET ARCHOPTS=)

    SET CFLAGS=-std=c11 %ARCHOPTS% %WARNINGS% %VARIABLES%
    SET LFLAGS=-Wl,-stack:16777216

    SET CC_NISSY=%CC% %CFLAGS% %ODFLAGS% -c src\nissy.c
    SET CC_SHELL=%CC% %CFLAGS% %ODFLAGS% %LFLAGS% nissy.o shell\shell.c -o run.exe
    SET CC_PYTHON=%CC% %CFLAGS% %LFLAGS% -I%PYINCLUDE% -L%PYLIBS% -shared -lpython3 python\nissy_module.c nissy.o -o python\nissy.pyd
    SET CC_TEST=%CC% %CFLAGS% %ODFLAGS% %LFLAGS% -o runtest.exe nissy.o
    SET CC_TOOL=%CC% %CFLAGS% %ODFLAGS% %LFLAGS% -o runtool.exe nissy.o
    SET CC_CXX=%CXX% %ODFLAGS% -std=c++20 -o runcpp.exe cpp\nissy.cpp nissy.o
:compiler_done

:: Select compilation target from command line argument
SET TARGET=%1
if not defined TARGET SET TARGET=nissy
SET EXPR=%2
for %%a in (nissy python shell test config help clean tool cpp solvetest) do (
    if %TARGET%==%%a (
        call:build_%TARGET% %*
        exit /b
    )
)
echo Target '%TARGET%' unavailable, run 'build help' for info
exit /b 1

:build_help
    echo *** Warning: support for building nissy on Windows is incomplete ***
    echo.
    echo Build system for nissy. Usage:
    echo.
    echo build [/d] [TARGET]
    echo.
    echo Possible values for TARGET (defaults to 'nissy' if unspecified):
    echo.
    echo nissy       Build the nissy.o object file.
    echo python      Build the Python module for nissy.
    echo             NOTE: Python development headers must be installed in
    echo                   order to build the Python module. The path of these
    echo                   headers is hardcoded in the PYPATH varible in
    echo                   build.bat. You may need to edit this file.
    echo shell       Build the basic nissy shell (./run).
    echo cpp FILE    Build and run the given C++ FILE.
    echo test [EXPR] Build and run unit tests. If EXPR is provided, only the
    echo             tests whose name contains EXPR are run. The /d option is
    echo             is always implied.
    echo tool EXPR   Run the 'tool' matching the given EXPR.
    echo solvetest   Build nissy and run a collection of tools for testing"
    echo             various solvers.
    echo help        Show this help message.
    echo config      Show build configuration and exit.
    echo clean       Remove all build files.
    echo.
    echo The /d option activates debug mode (slower, used for testing).
    echo Tests are automatically built in debug mode even without /d.
    echo For more on build configurations, see the comments in build.bat.
exit /b

:build_config
    echo Compiler: %CC%
    echo Architecture: %ARCH%
    echo Max threads: %THREADS%
    echo Optimization flags: %OFLAGS%
    echo Debug flags: %DFLAGS%
exit /b

:build_nissy
    @echo on
    %CC_NISSY% || exit /b 1
    @echo off
exit /b

:build_shell
    call:build_nissy || exit /b 1
    @echo on
    %CC_SHELL% || exit /b 1
    @echo off
exit /b

:build_python
    call:build_nissy || exit /b 1
    @echo on
    %CC_PYTHON% || exit /b 1
    @echo off
exit /b

:build_test
    call:build_nissy || exit /b 1
    if not defined EXPR (
        SET WILDCARD=*
    ) else (
        SET WILDCARD=*%EXPR%*
    )
    for /d %%d in ( test\%WILDCARD% ) do (
        if exist %%d\* (
            call:build_single_test %%d || exit /b 1
        )
    )
exit /b

:build_clean
    @echo on
    del *.o *.so *.a *.ilk *.pdb *.exe
    @echo off
exit /b

:build_tool
    if not defined EXPR (
        @echo Please provide a valid EXPR to select a tool
        exit /b 1
    )
    
    set toolname=
    for /d %%d in ( tools\*%EXPR%* ) do (
        set toolname=%%~nd
    )

    if [%toolname%]==[] (
        @echo Expression '%EXPR%' does not match any tool
        exit /b 1
    )
    
    call:build_nissy || exit /b 1
    call:build_single_tool %*
exit /b

:build_cpp
    if not defined EXPR (
        @echo Please provide a valid C++ source file.
        exit /b 1
    )
    if not exist %EXPR% (
        @echo File %EXPR% does not exist.
        exit /b 1
    )
    call:build_nissy || exit /b 1
    @echo on
    %CC_CXX% %EXPR% || exit /b 1
    runcpp
    @echo off
exit /b

:build_solvetest
    call:build_nissy || exit /b 1
    for /d %%d in ( tools\*solvetest* ) do (
        set toolname=%%~nd
        call:build_single_tool
    )
exit /b

:build_single_test
    %CC_TEST% %1\*.c || exit /b 1
    set error=0
    for %%c in ( %1\*.in ) do (
        if %error%==1 exit /b 1
        @echo | set /p v="%1\%%~nc: "
        runtest < %%c > test\last.out 2> test\last.err
        FC /a %1\%%~nc.out test\last.out > test\last.fc.out
        if ERRORLEVEL 1 (
            @echo Test failed! Different output:
            type test\last.fc.out
            @echo stderr:
            type test\last.err
            goto :error
        ) else (
            @echo ok
        )
    )
    if %error%==1 exit /b 1
    del runtest.*
exit /b

:build_single_tool
    @echo on
    %CC_TOOL% tools\%toolname%\*.c || exit /b 1
    @echo off
    runtool %3 %4 %5 %6 %7 %8 %9 || exit /b 1
    @echo.
    @echo (On Windows, the output of a tool is not saved to any file.)
exit /b

:error
    exit /b 1

Generated with cgit - Back to sebastiano.tronto.net