-
-
Notifications
You must be signed in to change notification settings - Fork 483
/
build.sh
executable file
·271 lines (241 loc) · 7.6 KB
/
build.sh
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
263
264
265
266
267
268
269
270
271
#!/bin/bash
# Parse the command line
ExeName=
while [ "$1" ]; do
case "$1" in
--debug)
# enable debug build
debug=1
shift
;;
--profile)
profile=1
PLATFORM="vc-win64" # force 64 bit build for profiler
VC32TOOLS_OPTIONS="--64"
shift
;;
--vc)
vc_ver=$2
shift 2
;;
--64)
# switch to 64 bit platform (Win64)
PLATFORM="vc-win64"
VC32TOOLS_OPTIONS="--64"
shift
;;
--exe)
ExeName=$2
shift 2
;;
--file)
# compile a single file from VSCode, should replace slashes
single_file=${2//\\//}
shift 2
;;
*)
echo "Usage: build.sh [--debug] [--profile] [--vc <version>] [--64] [--exe <file.exe>] [--file <cpp file>]"
exit
;;
esac
done
function DebugPrint()
{
# echo ">> Debug: $*" # uncomment this line to see debug stuff
: # just allow commented 'echo' above
}
#-------------------------------------------------------------
# Setup default project when running this script directly. Used to build UmodelTool.
function SetupDefaultProject()
{
is_default_project=1
project="UmodelTool/umodel"
root="."
render=1
if [ -z "$ExeName" ]; then
ExeName="umodel"
[ "$debug" ] && ExeName+="-debug"
[ "$profile" ] && ExeName+="-profile"
[ "$PLATFORM" == "vc-win64" ] && ExeName+="_64"
fi
GENMAKE_OPTIONS+=" EXE_NAME=$ExeName"
}
#-------------------------------------------------------------
# Get revision number from Git
function GetBuildNumber()
{
local revision="(unversioned)" # this value will be used in a case of missing git
local version_file="UmodelTool/Version.h"
if [ -d .git ]; then
local git=`type -p git` # equals to `which git`
if [ -z "$git" ]; then
if [ "$OSTYPE" == "msys" ]; then
# assume Windows, find local git distribution
# progs="${PROGRAMFILES//\\//}" # get from environment with slash replacement
# progs="/${progs//:/}" # for msys: convert "C:/Program Files" to "/C/Program Files"
[ -d "$PROGRAMFILES/Git" ] && gitpath="$PROGRAMFILES/Git/bin"
[ -d "$PROGRAMW6432/Git" ] && gitpath="$PROGRAMW6432/Git/bin"
! [ "$gitpath" ] && [ -d "$PROGRAMFILES/SmartGitHg/git" ] && gitpath="$PROGRAMFILES/SmartGitHg/git/bin"
! [ "$gitpath" ] && [ -d "$LOCALAPPDATA/Atlassian/SourceTree/git_local" ] && gitpath="$LOCALAPPDATA/Atlassian/SourceTree/git_local/bin"
[ "$gitpath" ] && PATH="$PATH:$gitpath"
# find git
git=`type -p git`
fi
fi
[ "$git" ] && revision=`git rev-list --count HEAD`
DebugPrint "Git revision: $revision"
fi
# update tool version
# read current revision
[ -f "$version_file" ] && [ "$revision" ] && read last_revision < $version_file
local last_revision=${last_revision##* } # cut "#define ..."
# write back to a file if value differs or if file doesn't exist (only for UModel project, i.e. when $project is empty)
[ "$is_default_project" ] && [ "$last_revision" != "$revision" ] && echo "#define GIT_REVISION $revision" > $version_file
}
#-------------------------------------------------------------
function DetectBuildPlatform()
{
# force PLATFORM=linux under Linux OS
if [ "$OSTYPE" == "linux-gnu" ] || [ "$OSTYPE" == "linux" ]; then
# PLATFORM="linux" - old case, now we'll recognize 32 or 64 bit OS for proper use of oodle.project
if [ $(uname -m) == 'x86_64' ]; then
PLATFORM="linux64"
else
PLATFORM="linux32"
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
PLATFORM=osx
else
[ "$PLATFORM" ] || PLATFORM="vc-win32"
fi
DebugPrint "Detected platform: $PLATFORM"
}
#-------------------------------------------------------------
# We have some makefile dependency on Visual Studio compiler version, so we should detect it
function DetectVisualStudioVersion()
{
# setup default compiler version
[ "$vc_ver" ] || vc_ver=latest
# Find Visual Studio
. vc32tools $VC32TOOLS_OPTIONS --version=$vc_ver --check
[ -z "$found_vc_year" ] && exit 1 # nothing found
# Adjust vc_ver to found one
vc_ver=$found_vc_year
DebugPrint "Found: Visual Studio $found_vc_year at \"$workpath\", Version = $vc_ver"
GENMAKE_OPTIONS+=" VC_VER=$vc_ver" # specify compiler for genmake script
}
#-------------------------------------------------------------
function ProcessShaderFiles()
{
# build shader includes before call to genmake
if [ $render -eq 1 ]; then
# 'cd' calls below won't work if we're not calling from the project's root
if [ "$root" != "." ]; then
echo "Bad 'root'"
exit 1
fi
# build shaders
#?? move this command to makefile
Unreal/Shaders/make.pl
fi
}
#-------------------------------------------------------------
function GenerateMakefile()
{
# prepare makefile parameters, store in obj directory
local projectName=${project##*/}
makefile="$root/obj/$projectName-$PLATFORM"
if ! [ -d $root/obj ]; then
mkdir $root/obj
fi
# debugging options
if [ "$debug" ]; then
makefile="${makefile}-debug"
GENMAKE_OPTIONS+=" DEBUG=1"
elif [ "$profile" ]; then
makefile="${makefile}-profile"
GENMAKE_OPTIONS+=" TRACY=1"
fi
makefile="${makefile}.mak"
DebugPrint "Using makefile: $makefile"
# update makefile when needed
# [ $makefile -ot $project ] &&
$root/Tools/genmake $project.project TARGET=$PLATFORM $GENMAKE_OPTIONS > $makefile
}
#-------------------------------------------------------------
# Parse generated makefile to find an obj file which is built from provided c or cpp file $single_file.
# Function parameters are passed via global variables $makefile, $single_file
function FindSingleFileTarget()
{
# Using perl with HEREDOC for parsing of makefile to find object file matching required target.
# Code layout: target=`perl << 'EOF'
# EOF
# `
# 1) using quoted 'EOF' to prevent variable expansion
# 2) passing parameters to a script using command line, return value as output capture
# 3) putting perl command into `` (inverse quotes)
# 4) s/// command in perl code has extra quote for '$'
target=`perl -w - "$makefile" "$single_file" <<'EOF'
my $makefile = $ARGV[0];
my $single_file = $ARGV[1];
open(FILE, $makefile) or die;
$defines = ();
while ($line = <FILE>)
{
next if $line !~ /^\S+/; # we're interested only in lines starting without indent
next if $line =~ /^\#/; # no comments
$line =~ s/(\r|\n)//; # string end of line
# print($line."\n");
# parse assignment
($var, $val) = $line =~ /^(\w+)\s*\=\s*(.*)$/;
if (defined($var) && defined($val)) {
$defines{$var} = $val;
} else {
# parse target
($target, $cpp) = $line =~ /^(\S+)\s*\:\s*(\S+)(\s|$)/;
if (defined($target) && defined($cpp)) {
next if $cpp ne $single_file; # match with single_file value
# print("$cpp -> $target\n");
for my $key (keys(%defines)) {
my $value = $defines{$key};
$target =~ s/\\$\($key\)/$value/g; # replace $(var) with value
}
# print("$cpp -> $target\n");
print("$target");
exit;
}
}
}
EOF
`
DebugPrint "SingleFile target: $target"
if [ -z "$target" ]; then echo "Error: failed to find a build target for '$single_file'"; exit; fi
}
#-------------------------------------------------------------
[ "$project" ] || SetupDefaultProject
GetBuildNumber
DetectBuildPlatform
[ "${PLATFORM:0:3}" == "vc-" ] && DetectVisualStudioVersion
ProcessShaderFiles
GenerateMakefile
[ "$single_file" ] && FindSingleFileTarget
# Perform a build
# if $target is empty, whole project will be built, otherwise a single file
case "$PLATFORM" in
"vc-win32"|"vc-win64")
Make $makefile $target || exit 1
;;
"mingw32"|"cygwin")
PATH=/bin:/usr/bin:$PATH # configure paths for Cygwin
gccfilt make -f $makefile $target || exit 1
;;
linux*)
make -j 4 -f $makefile $target || exit 1 # use 4 jobs for build
;;
osx)
make -f $makefile $target || exit 1
;;
*)
echo "Unknown PLATFORM=\"$PLATFORM\""
exit 1
esac