336 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			336 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/bin/bash
 | |
| 
 | |
| # $Id$
 | |
| 
 | |
| # This file is part of OpenTTD.
 | |
| # OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
 | |
| # OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 | |
| # See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
 | |
| 
 | |
| # This file generates all project files based on sources.list, so everyone who
 | |
| #  can start a bash process, can update the project files.
 | |
| 
 | |
| # Set neutral locale so sort behaves the same everywhere
 | |
| LC_ALL=C
 | |
| export LC_ALL
 | |
| 
 | |
| # We really need gawk for this!
 | |
| AWK=gawk
 | |
| 
 | |
| ${AWK} --version > /dev/null 2> /dev/null
 | |
| if [ "$?" != "0" ]; then
 | |
| 	echo "This script needs gawk to run properly"
 | |
| 	exit 1
 | |
| fi
 | |
| 
 | |
| ROOT_DIR="`pwd`/.."
 | |
| if ! [ -e "$ROOT_DIR/source.list" ]
 | |
| then
 | |
| 	ROOT_DIR="`pwd`"
 | |
| fi
 | |
| if ! [ -e "$ROOT_DIR/source.list" ]
 | |
| then
 | |
| 	echo "Can't find source.list, needed in order to make this run. Please go to either"
 | |
| 	echo " the project dir, or the root dir of a clean SVN checkout."
 | |
| 	exit 1
 | |
| fi
 | |
| 
 | |
| # openttd_vs142.sln             is for MSVC 2019
 | |
| # openttd_vs142.vcxproj         is for MSVC 2019
 | |
| # openttd_vs142.vcxproj.filters is for MSVC 2019
 | |
| # langs_vs142.vcxproj           is for MSVC 2019
 | |
| # strgen_vs142.vcxproj          is for MSVC 2019
 | |
| # strgen_vs142.vcxproj.filters  is for MSVC 2019
 | |
| # generate_vs142.vcxproj        is for MSVC 2019
 | |
| # version_vs142.vcxproj         is for MSVC 2019
 | |
| # basesets_vs142.vcxproj        is for MSVC 2019
 | |
| 
 | |
| # openttd_vs141.sln             is for MSVC 2017
 | |
| # openttd_vs141.vcxproj         is for MSVC 2017
 | |
| # openttd_vs141.vcxproj.filters is for MSVC 2017
 | |
| # langs_vs141.vcxproj           is for MSVC 2017
 | |
| # strgen_vs141.vcxproj          is for MSVC 2017
 | |
| # strgen_vs141.vcxproj.filters  is for MSVC 2017
 | |
| # generate_vs141.vcxproj        is for MSVC 2017
 | |
| # version_vs141.vcxproj         is for MSVC 2017
 | |
| # basesets_vs141.vcxproj        is for MSVC 2017
 | |
| 
 | |
| # openttd_vs140.sln             is for MSVC 2015
 | |
| # openttd_vs140.vcxproj         is for MSVC 2015
 | |
| # openttd_vs140.vcxproj.filters is for MSVC 2015
 | |
| # langs_vs140.vcxproj           is for MSVC 2015
 | |
| # strgen_vs140.vcxproj          is for MSVC 2015
 | |
| # strgen_vs140.vcxproj.filters  is for MSVC 2015
 | |
| # generate_vs140.vcxproj        is for MSVC 2015
 | |
| # version_vs140.vcxproj         is for MSVC 2015
 | |
| # basesets_vs140.vcxproj        is for MSVC 2015
 | |
| 
 | |
| 
 | |
| 
 | |
| 
 | |
| # First, collect the list of Windows files
 | |
| allegro_config=""
 | |
| sdl_config="1"
 | |
| png_config="1"
 | |
| os="MSVC"
 | |
| enable_dedicated="0"
 | |
| enable_ai="1"
 | |
| with_cocoa="0"
 | |
| enable_directmusic="1"
 | |
| enable_fluidsynth="0"
 | |
| with_threads="1"
 | |
| file_prefix="..\\\\\\\\src\\\\\\\\"
 | |
| 
 | |
| safety_check() {
 | |
| 	li=""
 | |
| 	for i in `cat $1 | grep -v "#\|ottdres.rc\|win32.cpp\|win32_v.cpp" | xargs -n 1 basename | sort`; do
 | |
| 		if [ "$li" = "$i" ]; then
 | |
| 			echo " !! ERROR !!"
 | |
| 			echo ""
 | |
| 			echo "The filename '$i' is already used in this project."
 | |
| 			echo "Because MSVC uses one single directory for all object files, it"
 | |
| 			echo "cannot handle filenames with the same name inside the same project."
 | |
| 			echo "Please rename either one of the file and try generating again."
 | |
| 			echo ""
 | |
| 			echo " !! ERROR !!"
 | |
| 			exit 1
 | |
| 		fi
 | |
| 		li="$i"
 | |
| 	done
 | |
| }
 | |
| 
 | |
| grep '\.h' "$ROOT_DIR/source.list" | grep -v '../objs/langs/table/strings.h\|../objs/settings/table/settings.h' | sed 's/	//g' | sort > tmp.headers.source.list
 | |
| find "$ROOT_DIR/src" \( -iname "*.h" -or -iname "*.hpp" \) -and -not -ipath "*/.svn/*" | sed "s~$ROOT_DIR/src/~~" | sort > tmp.headers.src
 | |
| if [ -n "`diff tmp.headers.source.list tmp.headers.src`" ]; then
 | |
| 	echo "The following headers are missing in source.list and not in /src/ or vice versa."
 | |
| 	diff tmp.headers.source.list tmp.headers.src | grep '[<>]' | sort
 | |
| 	echo ""
 | |
| fi
 | |
| rm tmp.headers.*
 | |
| 
 | |
| load_main_data() {
 | |
| 	# Read the source.list and process it
 | |
| 	RES="`cat $1 | ${AWK} -v BINMODE=1 '
 | |
| 		{ gsub("\\r", "", $0); }
 | |
| 		/^(	*)#end/  { if (deep == skip) { skip -= 1; } deep -= 1; next; }
 | |
| 		/^(	*)#else/ { if (deep == skip) { skip -= 1; } else if (deep - 1 == skip) { skip += 1; } next; }
 | |
| 		/^(	*)#if/   {
 | |
| 			gsub("	", "", $0);
 | |
| 			gsub("^#if", "", $0);
 | |
| 			gsub("^ ", "", $0);
 | |
| 
 | |
| 			if (deep != skip) { deep += 1; next; }
 | |
| 
 | |
| 			deep += 1;
 | |
| 
 | |
| 			if ($0 == "ALLEGRO"     && "'$allegro_config'" == "")      { next; }
 | |
| 			if ($0 == "SDL"         && "'$sdl_config'" == "")          { next; }
 | |
| 			if ($0 == "PNG"         && "'$png_config'" == "")          { next; }
 | |
| 			if ($0 == "OSX"         && "'$os'" != "OSX")               { next; }
 | |
| 			if ($0 == "OS2"         && "'$os'" != "OS2")               { next; }
 | |
| 			if ($0 == "DOS"         && "'$os'" != "DOS")               { next; }
 | |
| 			if ($0 == "DEDICATED"   && "'$enable_dedicated'" != "1")   { next; }
 | |
| 			if ($0 == "AI"          && "'$enable_ai'" == "0")          { next; }
 | |
| 			if ($0 == "COCOA"       && "'$with_cocoa'" == "0")         { next; }
 | |
| 			if ($0 == "HAIKU"       && "'$os'" != "HAIKU")             { next; }
 | |
| 			if ($0 == "WIN32"       && "'$os'" != "MINGW" &&
 | |
| 											"'$os'" != "CYGWIN" && "'$os'" != "MSVC" ) { next; }
 | |
| 			if ($0 == "MSVC"        && "'$os'" != "MSVC")              { next; }
 | |
| 			if ($0 == "MINGW"       && "'$os'" != "MINGW")             { next; }
 | |
| 			if ($0 == "DIRECTMUSIC" && "'$enable_directmusic'" != "1") { next; }
 | |
| 			if ($0 == "FLUIDSYNTH"  && "'$enable_fluidsynth'" != "1")  { next; }
 | |
| 			if ($0 == "USE_XAUDIO2" && "'$with_xaudio2'" == "0")       { next; }
 | |
| 			if ($0 == "USE_THREADS" && "'$with_threads'" == "0")       { next; }
 | |
| 
 | |
| 			skip += 1;
 | |
| 
 | |
| 			next;
 | |
| 		}
 | |
| 		/^(	*)#/ {
 | |
| 			if (deep == skip) {
 | |
| 				gsub("	", "", $0);
 | |
| 				gsub("^#", "", $0);
 | |
| 				gsub("^ ", "", $0);
 | |
| 				filter = $0;
 | |
| 				print "#3    <Filter Include=\\""filter"\\">";
 | |
| 				printf "#3      <UniqueIdentifier>{c76ff9f1-1e62-46d8-8d55-%012d}</UniqueIdentifier>\n", i;
 | |
| 				print "#3    </Filter>";
 | |
| 				i += 1;
 | |
| 			}
 | |
| 
 | |
| 			next;
 | |
| 		}
 | |
| 		/^$/ { next }
 | |
| 		{
 | |
| 			if (deep == skip) {
 | |
| 				gsub("	", "", $0);
 | |
| 				gsub("/", "\\\\\\\\", $0);
 | |
| 				split($0, file, ".");
 | |
| 				cltype = "ClInclude"
 | |
| 				if (file[2] == "cpp") cltype = "ClCompile";
 | |
| 				if (file[2] == "rc") cltype = "ResourceCompile";
 | |
| 				print "#2    <"cltype" Include=\\"'$file_prefix'"$0"\\" />";
 | |
| 				print "#4    <"cltype" Include=\\"'$file_prefix'"$0"\\">";
 | |
| 				print "#4      <Filter>"filter"</Filter>";
 | |
| 				print "#4    </"cltype">";
 | |
| 			}
 | |
| 		}
 | |
| 	'`"
 | |
| 
 | |
| 	eval "$2=\"\$RES\""
 | |
| }
 | |
| 
 | |
| load_lang_data() {
 | |
| 	RES=""
 | |
| 	# Windows Folder sort and Linux Folder sort are slightly different.
 | |
| 	# By removing the extension and sorting it on Linux, they are the same.
 | |
| 	for i in `ls $1 | sed s~.txt$~~g | sort`
 | |
| 	do
 | |
| 		i=`basename $i`
 | |
| 		if [ "$i" == "english" ]
 | |
| 		then
 | |
| 			continue
 | |
| 		fi
 | |
| 		RES="$RES
 | |
| #2    <CustomBuild Include=\"..\\\\src\\\\lang\\\\"$i".txt\">
 | |
| #2      <Message Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">Generating "$i" language file</Message>
 | |
| #2      <Command Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">..\\\\objs\\\\strgen\\\\strgen.exe -s ..\\\\src\\\\lang -d ..\\\\bin\\\\lang \"%(FullPath)\"</Command>
 | |
| #2      <AdditionalInputs Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">..\\\\src\\\\lang\\\\english.txt;..\\\\objs\\\\strgen\\\\strgen.exe;%(AdditionalInputs)</AdditionalInputs>
 | |
| #2      <Outputs Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">..\\\\bin\\\\lang\\\\"$i".lng;%(Outputs)</Outputs>
 | |
| #2    </CustomBuild>
 | |
| #3    <CustomBuild Include=\"..\\\\src\\\\lang\\\\"$i".txt\">
 | |
| #3      <Filter>Translations</Filter>
 | |
| #3    </CustomBuild>"
 | |
| 	done
 | |
| 
 | |
| 	eval "$2=\"\$RES\""
 | |
| }
 | |
| 
 | |
| load_settings_data() {
 | |
| 	RES=""
 | |
| 	RES2="
 | |
| #3..\\\\objs\\\\settings\\\\settings_gen.exe -o ..\\\\objs\\\\settings\\\\table\\\\settings.h -b ..\\\\src\\\\table\\\\settings.h.preamble -a ..\\\\src\\\\table\\\\settings.h.postamble"
 | |
| 	for i in `ls $1`
 | |
| 	do
 | |
| 		i=`basename $i`
 | |
| 		RES="$RES
 | |
| #2    <None Include=\"..\\\\src\\\\table\\\\"$i"\" />
 | |
| #4    <None Include=\"..\\\\src\\\\table\\\\"$i"\">
 | |
| #4      <Filter>INI</Filter>
 | |
| #4    </None>"
 | |
| 		RES2="$RES2 ..\\\\src\\\\table\\\\"$i
 | |
| 	done
 | |
| 
 | |
| 	eval "$2=\"\$RES\$RES2\""
 | |
| }
 | |
| 
 | |
| load_baseset_data() {
 | |
| 	FIRST=""
 | |
| 	RES=""
 | |
| 	RES2="
 | |
| #4    <Langs>"
 | |
| 	# Windows Folder sort and Linux Folder sort are slightly different.
 | |
| 	# By removing the extension and sorting it on Linux, they are the same.
 | |
| 	for i in `ls $2 | sed s~.txt$~~g | sort`
 | |
| 	do
 | |
| 		if [ "$FIRST" != "" ]; then
 | |
| 			RES2="$RES2;"
 | |
| 		else
 | |
| 			FIRST=1
 | |
| 		fi
 | |
| 		i=`basename $i`
 | |
| 		RES2="$RES2..\\\\src\\\\lang\\\\$i.txt"
 | |
| 	done
 | |
| 	RES2="$RES2</Langs>"
 | |
| 	# Windows Folder sort and Linux Folder sort are slightly different.
 | |
| 	# By fiddling with the extension and sorting it on Linux, they are the same.
 | |
| 	for i in `ls $1 | sed s~\\\.~000~g | sort | sed s~000~.~g`
 | |
| 	do
 | |
| 		i=`basename $i`
 | |
| 		RES="$RES
 | |
| #2    <CustomBuild Include=\"..\\\\media\\\\baseset\\\\"$i"\">
 | |
| #2      <Message Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">Generating "$i" baseset metadata file</Message>
 | |
| #2      <Command Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">cscript //nologo ..\\\\media\\\\baseset\\\\translations.vbs \"%(FullPath)\" \"\$(OutputPath)$i\" ..\\\\src\\\\lang ..\\\\bin\\\\baseset\\\\orig_extra.grf</Command>
 | |
| #2      <AdditionalInputs Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">\$(Langs);..\\\\bin\\\\baseset\\\\orig_extra.grf;%(AdditionalInputs)</AdditionalInputs>
 | |
| #2      <Outputs Condition=\"'\$(Configuration)|\$(Platform)'=='Debug|Win32'\">..\\\\bin\\\\baseset\\\\"$i";%(Outputs)</Outputs>
 | |
| #2    </CustomBuild>
 | |
| #3    <CustomBuild Include=\"..\\\\media\\\\baseset\\\\"$i"\">
 | |
| #3      <Filter>Baseset Metadata</Filter>
 | |
| #3    </CustomBuild>"
 | |
| 	done
 | |
| 
 | |
| 	eval "$3=\"\$RES\$RES2\""
 | |
| }
 | |
| 
 | |
| generate() {
 | |
| 	echo "Generating $2..."
 | |
| 	# Everything above the !!FILTERS!! marker
 | |
| 	cat "$ROOT_DIR/projects/$2".in | ${AWK} -v BINMODE=1 -v FILTERS="$3" -v FILES="$1" '
 | |
| 		{ CR = (match($0, "\\r$") > 0 ? "\r" : "") }
 | |
| 		/^$/ { next }
 | |
| 		/!!FILTERS!!/ {
 | |
| 			split(FILTERS, filters, "\n");
 | |
| 			for (i = 1; filters[i] != ""; i++) {
 | |
| 				print filters[i] CR;
 | |
| 			}
 | |
| 			next;
 | |
| 		}
 | |
| 		/!!FILES!!/ {
 | |
| 			split(FILES, files, "\n");
 | |
| 			for (i = 1; files[i] != ""; i++) {
 | |
| 				print files[i] CR;
 | |
| 			}
 | |
| 			next;
 | |
| 		}
 | |
| 		{
 | |
| 			print $0;
 | |
| 		}
 | |
| 	' > "$ROOT_DIR/projects/$2"
 | |
| }
 | |
| 
 | |
| safety_check "$ROOT_DIR/source.list"
 | |
| 
 | |
| load_main_data "$ROOT_DIR/source.list" openttd
 | |
| openttdfiles=`echo "$openttd" | grep "^#4" | sed "s~#4~~g"`
 | |
| openttdfilters=`echo "$openttd" | grep "^#3" | sed "s~#3~~g"`
 | |
| openttdvcxproj=`echo "$openttd" | grep "^#2" | sed "s~#2~~g"`
 | |
| 
 | |
| load_lang_data "$ROOT_DIR/src/lang/*.txt" lang
 | |
| langfiles=`echo "$lang" | grep "^#3" | sed "s~#3~~g"`
 | |
| langvcxproj=`echo "$lang" | grep "^#2" | sed "s~#2~~g"`
 | |
| 
 | |
| load_settings_data "$ROOT_DIR/src/table/*.ini" settings
 | |
| settingsfiles=`echo "$settings" | grep "^#4" | sed "s~#4~~g"`
 | |
| settingscommand=`echo "$settings" | grep "^#3" | sed "s~#3~~g"`
 | |
| settingsvcxproj=`echo "$settings" | grep "^#2" | sed "s~#2~~g"`
 | |
| 
 | |
| load_baseset_data "$ROOT_DIR/media/baseset/*.ob?" "$ROOT_DIR/src/lang/*.txt" baseset
 | |
| basesetfiles=`echo "$baseset" | grep "^#3" | sed "s-#3--g"`
 | |
| basesetvcxproj=`echo "$baseset" | grep "^#2" | sed "s~#2~~g"`
 | |
| basesetlangs=`echo "$baseset" | grep "^#4" | sed "s~#4~~g"`
 | |
| 
 | |
| generate "$openttdvcxproj" "openttd_vs140.vcxproj"
 | |
| generate "$openttdfiles" "openttd_vs140.vcxproj.filters" "$openttdfilters"
 | |
| generate "$openttdvcxproj" "openttd_vs141.vcxproj"
 | |
| generate "$openttdfiles" "openttd_vs141.vcxproj.filters" "$openttdfilters"
 | |
| generate "$openttdvcxproj" "openttd_vs142.vcxproj"
 | |
| generate "$openttdfiles" "openttd_vs142.vcxproj.filters" "$openttdfilters"
 | |
| generate "$langvcxproj" "langs_vs140.vcxproj"
 | |
| generate "$langfiles" "langs_vs140.vcxproj.filters"
 | |
| generate "$langvcxproj" "langs_vs141.vcxproj"
 | |
| generate "$langfiles" "langs_vs141.vcxproj.filters"
 | |
| generate "$langvcxproj" "langs_vs142.vcxproj"
 | |
| generate "$langfiles" "langs_vs142.vcxproj.filters"
 | |
| generate "$settingsvcxproj" "settings_vs140.vcxproj" "$settingscommand"
 | |
| generate "$settingsfiles" "settings_vs140.vcxproj.filters"
 | |
| generate "$settingsvcxproj" "settings_vs141.vcxproj" "$settingscommand"
 | |
| generate "$settingsfiles" "settings_vs141.vcxproj.filters"
 | |
| generate "$settingsvcxproj" "settings_vs142.vcxproj" "$settingscommand"
 | |
| generate "$settingsfiles" "settings_vs142.vcxproj.filters"
 | |
| generate "$basesetvcxproj" "basesets_vs140.vcxproj" "$basesetlangs"
 | |
| generate "$basesetfiles" "basesets_vs140.vcxproj.filters"
 | |
| generate "$basesetvcxproj" "basesets_vs141.vcxproj" "$basesetlangs"
 | |
| generate "$basesetfiles" "basesets_vs141.vcxproj.filters"
 | |
| generate "$basesetvcxproj" "basesets_vs142.vcxproj" "$basesetlangs"
 | |
| generate "$basesetfiles" "basesets_vs142.vcxproj.filters"
 | 
