File: makefile_builder.sh

package info (click to toggle)
exult 1.12.1-1
  • links: PTS, VCS
  • area: contrib
  • in suites: forky, sid
  • size: 43,856 kB
  • sloc: cpp: 170,016; xml: 7,400; yacc: 2,850; makefile: 2,419; java: 1,901; ansic: 1,654; lex: 673; sh: 550; objc: 416
file content (290 lines) | stat: -rwxr-xr-x 12,051 bytes parent folder | download
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
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
#!/bin/bash

# This script generates Makefile.am and Makefile.mingw files for Exult mods that
# follow a certain layout, as long as they (1) are in a subdir of this script
# and (2) have their own *.cfg file. The layouts are somewhat flexible; data to
# go into the 'patch' dir is searched for under 'patch' and 'data' subdirs. Any
# generated files (such as flex files and usecode files) do not follow these
# restrictions; *.in files (other than Makefile.in) are used with expack to make
# flexes, usecode.uc file is used with ucc to make final usecode file, and they
# will be installed wherever they are generated.
#
# Warning 1: This should be run only from ./content and only after a 'make clean'
# has been executed.
#
# Warning 2: This is a bash script and is likely NON-PORTABLE due to many of the
# commands used. For this reason, the generated makefiles have been included in
# Exult SVN.

n=$'\n'
t=$'\t'

# Find all cfg files.
find . -mindepth 2 -iname "*.cfg" | while read -r cfgfile; do
	# Strip initial ./ from cfg name.
	cfgfile="${cfgfile#./}"
	# Get the dir we will process now.
	moddir=$(dirname "$cfgfile")
	# Destination dir for mod data (equal to cfg file name).
	installdir=$(basename "$cfgfile" .cfg)
	# Check for 'patch' or 'data' dirs. Only these dirs are known for now.
	patchdir=""
	if [[ -d "$moddir/patch" ]]; then
		patchdir="patch/"
	elif [[ -d "$moddir/data" ]]; then
		patchdir="data/"
	fi

	# Find usecode.uc location and check if we need to set ucc includes.
	sourcedir="$(find "$moddir" -name usecode.uc)"
	sourcedir=$(dirname "${sourcedir#*$moddir/}")
	include=""
	if [[ -n "$sourcedir" ]]; then
		include="-I $sourcedir"
		sourcedir="$sourcedir/"
	fi

	# Determine the base game mod. We assume forgeofvirtue except for the two
	# we know are for silverseed.
	case "$moddir" in
		"si") export basedest="silverseed";;
		"sifixes") export basedest="silverseed";;
		*) export basedest="forgeofvirtue";;
	esac

	# Variables used to build the makefiles.
	nodist_datafiles_am=""
	datafiles_am=""
	datafiles_mingw=""
	extradist_am=""
	buildrules=""
	buildexpack="no"
	builducc="no"
	targets_mingw="all:"
	cleanfiles=""

	# Remove existing makefiles.
	modmakefile_am="$moddir/Makefile.am"
	modmakefile_mingw="$moddir/Makefile.mingw"
	rm -f "$modmakefile_am" "$modmakefile_mingw"

	# Boilerplate for Makefile.am:
	echo "# This is an automatically generated file; please do not edit it manually.
# Instead, run makefile_builder.sh from the parent directory.

# Base of the exult source
UCCDIR:=\$(top_srcdir)/tools/compiler
UCC:=\$(UCCDIR)/ucc

EXPACKDIR:=\$(top_srcdir)/tools
EXPACK:=\$(EXPACKDIR)/expack
" >> "$modmakefile_am"

	# Boilerplate for Makefile.mingw:
	echo "# This is an automatically generated file; please do not edit it manually.
# Instead, run makefile_builder.sh from the parent directory.
# It may require a little tweaking. (paths)

# Where is Ultima 7 installed
U7PATH:=C:/Ultima7

# Base of the exult source
SRC:=../..

srcdir:=.

UCCDIR:=\$(SRC)
UCC:=\$(UCCDIR)/ucc.exe

EXPACKDIR:=\$(SRC)
EXPACK:=\$(EXPACKDIR)/expack.exe

${moddir}dir:=\$(U7PATH)/$basedest/mods
" >> "$modmakefile_mingw"

	# Store MinGW dest dir:
	destdir_mingw="\$(${moddir}dir)/$installdir"

	# MinGW EXTRADIST
	distfiles_mingw=$(find "$moddir" -maxdepth 1 -iname '*.ico' -or -iname '*.png' -or -iname '*.txt' | while read -r f; do file="${f#$moddir/}" ; echo "${t}cp ${file} \$(${moddir}dir)/${installdir}/${file}"; done | sort)
	if [[ -n "$distfiles_mingw" ]]; then
		distfiles_mingw="${distfiles_mingw}${n}${t}cp ./../../COPYING \$(${moddir}dir)/${installdir}/License.txt"
	elif [[ -f "$moddir/README" ]]; then
		distfiles_mingw="${t}cp README \$(${moddir}dir)/${installdir}/Readme.txt${n}${t}cp ./../../COPYING \$(${moddir}dir)/${installdir}/License.txt"
	else
		distfiles_mingw="${t}cp ./../../COPYING \$(${moddir}dir)/${installdir}/License.txt"
	fi

	# Automake EXTRADIST
	distfiles=$(find "$moddir" -maxdepth 1 -iname '*.ico' -or -iname '*.png' -or -iname '*.mingw' -or -iname '*.txt' | sort | sed -r "s%^(.*)$moddir/(.*)\s*\$%${t}\2% ; \$!s%^(.*)\s*\$%\1${t}\\\\%")
	if [[ -n "$distfiles" ]]; then
		extradist_am="$extradist_am${t}\\${n}${distfiles}"
	fi
	distfiles=$(find "$moddir" -iname 'make.*' | sort | sed -r "s%^(.*)$moddir/(.*)\s*\$%${t}\2% ; \$!s%^(.*)\s*\$%\1${t}\\\\%")
	if [[ -n "$distfiles" ]]; then
		extradist_am="$extradist_am${t}\\${n}${distfiles}"
	fi

	# Get usecode dependencies.
	sources=$(find "$moddir" -iname "*.uc" | sort | sed -r "s%^(.*)$moddir/(.*)\s*\$%${t}\2% ; \$!s%^(.*)\s*\$%\1${t}\\\\%")
	if [[ -n "$sources" ]]; then
		extradist_am="$extradist_am${t}\\${n}${t}\$(USECODE_OBJECTS)"
		locoutput="USECODE_OBJECTS :=${t}\\${n}${sources}"
		echo -e "$locoutput" >> "$modmakefile_am"
		echo -e "$locoutput" >> "$modmakefile_mingw"
		nodist_datafiles_am="$nodist_datafiles_am\\${n}${t}${patchdir}usecode${t}"
		datafiles_mingw="$datafiles_mingw${t}cp ${patchdir}usecode $destdir_mingw/${patchdir}usecode${n}"
		targets_mingw="$targets_mingw ${patchdir}usecode"
		buildrules="$buildrules${n}${patchdir}usecode: \$(UCC) \$(USECODE_OBJECTS)${n}${t}\$(UCC) $include -o ${patchdir}usecode ${sourcedir}usecode.uc${n}"
		cleanfiles="$cleanfiles${n}${t}${patchdir}usecode${t}\\"
		builducc="yes"
	fi

	# Get flex file dependencies from expack scripts. We check *.in scripts for
	# this, except for any Makefile.in files.
	infiles=$(find "$moddir" -iname "*.in" | grep -v "Makefile.in" | sort)
	for f in $infiles; do
		# Get first line of script for the destination file name.
		read -r flexname < "$f"
		# Warning: I am taking a shortcut here and assuming that expack will
		# place the destination flex file in the patch dir we found earlier.
		# This is because I don't want to have to figure out which dir the
		# flex is supposed to be built from.
		#fpath="$(readlink -m $(dirname $f)/$flexname)"
		#fpath="${fpath#$(pwd)/$moddir}"
		fpath="$(basename "$flexname")"
		fname="${f#*$moddir/}"
		fnamep="${patchdir}$fpath"
		skippedfirst="no"
		# Parse, format and sort dependencies.
		flist=$(sed '/^$/d' "$f" | while read -r g; do if [[ "$skippedfirst" == "no" ]]; then skippedfirst="yes"; else echo "	${sourcedir}graphics/${g#:*:}	\\"; fi; done | sort)
		if [[ -n "$flist" ]]; then
			fnameu=$(echo "${fpath//./_}_OBJECTS" | tr "[:lower:]" "[:upper:]")
			extradist_am="$extradist_am${t}\\${n}${t}\$($fnameu)"
			locoutput="${n}$fnameu :=${t}\\${n}${t}$fname${t}\\${n}${flist%${t}*}"
			echo -e "$locoutput" >> "$modmakefile_am"
			echo -e "$locoutput" >> "$modmakefile_mingw"
			nodist_datafiles_am="$nodist_datafiles_am\\${n}${t}$fnamep${t}"
			datafiles_mingw="$datafiles_mingw${t}cp $fnamep $destdir_mingw/$fnamep${n}"
			targets_mingw="$targets_mingw $fnamep"
			buildrules="$buildrules${n}$fnamep: \$(EXPACK) \$($fnameu)${n}${t}\$(EXPACK) -i \$(srcdir)${f#$moddir}${n}"
			cleanfiles="$cleanfiles${n}${t}$fnamep${t}\\${n}${t}${fnamep//./_}.h${t}\\"
			buildexpack="yes"
		fi
	done

	# Automake dest dir:
	destdir_am="\$(datadir)/exult/$basedest/mods"
	extradist_am="$extradist_am${t}\\${n}${t}\$(${moddir}_DATA)"
	echo -e "${n}${moddir}dir := $destdir_am${n}${n}${moddir}_DATA :=${t}\\${n}${t}$(basename "$cfgfile")${n}" >> "$modmakefile_am"

	destdir_am="\$(${moddir}dir)/$installdir"

	# MinGW install mkdir for generated files. We set a flag to prevent the
	# output of a second mkdir for this same directory later on.
	didpatchroot="no"
	if [[ -n "$datafiles_mingw" ]]; then
		datafiles_mingw="${t}mkdir -p $destdir_mingw/${patchdir%/}
$datafiles_mingw"
		didpatchroot="yes"
	fi

	# Generate install locations of all patch data files.
	if [[ -n "$patchdir" ]]; then
		# We have a known patch dir.
		# Search this dir, all mapXX subdirs and music subdir, if present.
		for dirname in "$moddir/${patchdir%/}" $(find "$moddir/$patchdir" -type d -regex "$moddir/${patchdir}map[0-9A-Fa-f][0-9A-Fa-f]") $(find "$moddir/$patchdir" -type d -name "$moddir/${patchdir}music"); do
			# Compute automake rule name.
			dirrule="${dirname#$moddir/}"
			dirrule="${dirrule//[^a-zA-Z0-9]/}"
			# Gather files. Maybe replace with a more targetted list?
			dirfiles=$(find "$dirname" -maxdepth 1 -type f \( \! -iname "*.h" -a \! -iname "*~" -a \! -iname "usecode" -a \! -iname "*.flx" -a \! -iname "*.vga" \) -o -iname "combos.flx" -o -iname "minimaps.vga" | sort)
			if [[ -n "$dirfiles" || -n "$datafiles_am" || -n "$nodist_datafiles_am" ]]; then
				echo -e "${moddir}${dirrule}dir =${t}$destdir_am/${dirname#$moddir/}${n}" >> "$modmakefile_am"
				if [[ -n "$nodist_datafiles_am" ]]; then
					echo -e "nodist_${moddir}${dirrule}_DATA :=${t}${nodist_datafiles_am%${t}*}${n}" >> "$modmakefile_am"
				fi
				if [[ "$didpatchroot" == "no" || "$dirname" != "$moddir/${patchdir%/}" ]]; then
					datafiles_mingw="$datafiles_mingw${n}\tmkdir -p $destdir_mingw/${dirname#$moddir/}${n}"
				fi
				echo -e "${moddir}${dirrule}_DATA :=${t}\\" >> "$modmakefile_am"
				extradist_am="$extradist_am${t}\\${n}${t}\$(${moddir}${dirrule}_DATA)"
				# Format and sort file list for automake makefile.
				infiles_am=$(echo "$dirfiles" | while read -r f; do echo -e "${t}${f#$moddir/}${t}\\"; done | sort)
				datafiles_am="$datafiles_am$infiles_am"
				datafiles_am="${datafiles_am%${t}*}"
				if [[ -n "$datafiles_am" ]]; then
					echo -e "$datafiles_am${n}" >> "$modmakefile_am"
				fi
				# Format and sort file list for MinGW makefile.
				infiles_mingw=$(echo "$dirfiles" | while read -r f; do dest="${f#$moddir/}"; echo -e "${t}cp $dest $destdir_mingw/$dest"; done | sort)
				datafiles_mingw="$datafiles_mingw$infiles_mingw"
			fi
			datafiles_am=""
			nodist_datafiles_am=""
		done
	else
		# We do not have a known patch dir.
		if [[ -n "$nodist_datafiles_am" || -n "$datafiles_am" ]]; then
			echo -e "${moddir}patchdir := $destdir_am/patch${n}" >> "$modmakefile_am"
		fi
		if [[ -n "$nodist_datafiles_am" ]]; then
			# We do not have a known patch dir.
			echo -e "nodist_${moddir}patch_DATA :=${t}${nodist_datafiles_am%${t}*}${n}" >> "$modmakefile_am"
			nodist_datafiles_am=""
		fi

		if [[ -n "$datafiles_am" ]]; then
			echo -e "${moddir}patch_DATA :=${t}\\${n}${datafiles_am%${t}*}${n}" >> "$modmakefile_am"
			datafiles_am=""
		fi
	fi

	# Print the EXTRADIST diles
	if [[ -n "$extradist_am" ]]; then
		echo -e "EXTRA_DIST :=$extradist_am${n}" >> "$modmakefile_am"
	fi

	# Print the list of files to delete on 'make clean'.
	if [[ -n "$cleanfiles" ]]; then
		locoutput="CLEANFILES :=${t}\\${cleanfiles%${t}*}${n}"
		echo -e "$locoutput" >> "$modmakefile_am"
		echo -e "${n}$locoutput" >> "$modmakefile_mingw"
	fi

	# Rules for MinGW 'make install' and 'make uninstall'.
	if [[ -n "$datafiles_mingw" ]]; then
		if [[ -n "$distfiles_mingw" ]]; then
			datafiles_mingw="${datafiles_mingw%$'\n'}${n}$distfiles_mingw"
		else
			datafiles_mingw="$datafiles_mingw"
		fi
	elif [[ -n "$distfiles_mingw" ]]; then
		datafiles_mingw="$distfiles_mingw"
	else
		datafiles_mingw=""
	fi
	echo -e "$targets_mingw${n}\ninstall: all${n}\tmkdir -p \$(${moddir}dir)${n}\tcp $(basename "$cfgfile") \$(${moddir}dir)/$(basename "$cfgfile")${n}$datafiles_mingw${n}\nuninstall:${n}\trm -f \$(${moddir}dir)/$(basename "$cfgfile")${n}\trm -rf $destdir_mingw${n}" >> "$modmakefile_mingw"

	# Output rule to build expack, if needed.
	if [[ "$buildexpack" == "yes" ]]; then
		echo -e "\$(EXPACK):${n}${t}+(cd \$(EXPACKDIR);\$(MAKE) expack)${n}" >> "$modmakefile_am"
		echo -e "\$(EXPACK):${n}${t}+(cd \$(EXPACKDIR);\$(MAKE) -f Makefile.mingw expack.exe)${n}" >> "$modmakefile_mingw"
	fi

	# Output rule to build ucc, if needed.
	if [[ "$builducc" == "yes" ]]; then
		echo -e "\$(UCC):${n}${t}+(cd \$(UCCDIR);\$(MAKE))${n}" >> "$modmakefile_am"
		echo -e "\$(UCC):${n}${t}+(cd \$(UCCDIR);\$(MAKE) -f Makefile.mingw ucc.exe)${n}" >> "$modmakefile_mingw"
	fi

	# Build rules for data files.
	echo -e "$buildrules" >> "$modmakefile_am"
	echo -e "$buildrules" >> "$modmakefile_mingw"

	# Rule for MinGW 'make clean'.
	if [[ -n "$cleanfiles" ]]; then
		echo -e "clean:${n}\trm -f \$(CLEANFILES)${n}" >> "$modmakefile_mingw"
	fi
done