2010-11-10 03:56:42 +00:00
/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers , whose names
* are too numerous to list here . Please refer to the COPYRIGHT
* file distributed with this source distribution .
*
* This program 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 ; either version 2
* of the License , or ( at your option ) any later version .
*
* This program 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 this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 , USA .
*
*/
2011-04-24 13:33:23 -04:00
# include "config.h"
2010-11-10 03:56:42 +00:00
# include "msvc.h"
# include <fstream>
# include <algorithm>
2019-07-01 02:46:02 +01:00
# include <cstring>
2010-11-10 03:56:42 +00:00
2020-05-08 13:17:36 -07:00
std : : map < MSVC_Architecture , StringList > s_arch_disabled_features {
// NASM not supported for Windows on AMD64 target
{ MSVC_Architecture : : ARCH_AMD64 , { " nasm " } } ,
// NASM not supported for WoA target
// No OpenGL, OpenGL ES on Windows on ARM
// https://github.com/microsoft/vcpkg/issues/11248 [fribidi] Fribidi doesn't cross-compile on x86-64 to target arm/arm64
{ MSVC_Architecture : : ARCH_ARM64 , { " nasm " , " opengl " , " opengles " , " fribidi " } } ,
} ;
2010-11-10 03:56:42 +00:00
namespace CreateProjectTool {
//////////////////////////////////////////////////////////////////////////
// MSVC Provider (Base class)
//////////////////////////////////////////////////////////////////////////
2019-04-15 18:59:00 +01:00
MSVCProvider : : MSVCProvider ( StringList & global_warnings , std : : map < std : : string , StringList > & project_warnings , const int version , const MSVCVersion & msvc )
: ProjectProvider ( global_warnings , project_warnings , version ) , _msvcVersion ( msvc ) {
2012-09-05 07:54:33 -04:00
_enableLanguageExtensions = tokenize ( ENABLE_LANGUAGE_EXTENSIONS , ' , ' ) ;
_disableEditAndContinue = tokenize ( DISABLE_EDIT_AND_CONTINUE , ' , ' ) ;
2010-11-10 03:56:42 +00:00
}
void MSVCProvider : : createWorkspace ( const BuildSetup & setup ) {
2011-09-06 16:01:10 -04:00
UUIDMap : : const_iterator svmUUID = _uuidMap . find ( setup . projectName ) ;
2010-11-10 03:56:42 +00:00
if ( svmUUID = = _uuidMap . end ( ) )
2011-09-06 16:01:10 -04:00
error ( " No UUID for \" " + setup . projectName + " \" project created " ) ;
2010-11-10 03:56:42 +00:00
const std : : string svmProjectUUID = svmUUID - > second ;
assert ( ! svmProjectUUID . empty ( ) ) ;
2019-06-16 00:19:38 +01:00
std : : string solutionUUID = createUUID ( setup . projectName + " .sln " ) ;
2010-11-10 03:56:42 +00:00
2011-09-06 16:01:10 -04:00
std : : ofstream solution ( ( setup . outputDir + ' / ' + setup . projectName + " .sln " ) . c_str ( ) ) ;
2010-11-10 03:56:42 +00:00
if ( ! solution )
2011-09-06 16:01:10 -04:00
error ( " Could not open \" " + setup . outputDir + ' / ' + setup . projectName + " .sln \" for writing " ) ;
2010-11-10 03:56:42 +00:00
2019-04-15 18:59:00 +01:00
solution < < " Microsoft Visual Studio Solution File, Format Version " < < _msvcVersion . solutionFormat < < " \n " ;
solution < < " # Visual Studio " < < _msvcVersion . solutionVersion < < " \n " ;
2010-11-10 03:56:42 +00:00
2011-09-06 16:01:10 -04:00
// Write main project
if ( ! setup . devTools ) {
solution < < " Project( \" { " < < solutionUUID < < " } \" ) = \" " < < setup . projectName < < " \" , \" " < < setup . projectName < < getProjectExtension ( ) < < " \" , \" { " < < svmProjectUUID < < " } \" \n " ;
2010-11-10 03:56:42 +00:00
2011-09-06 16:01:10 -04:00
// Project dependencies are moved to vcxproj files in Visual Studio 2010
if ( _version < 10 )
writeReferences ( setup , solution ) ;
2010-11-10 03:56:42 +00:00
2011-09-06 16:01:10 -04:00
solution < < " EndProject \n " ;
}
2010-11-10 03:56:42 +00:00
// Note we assume that the UUID map only includes UUIDs for enabled engines!
for ( UUIDMap : : const_iterator i = _uuidMap . begin ( ) ; i ! = _uuidMap . end ( ) ; + + i ) {
2011-09-06 16:01:10 -04:00
if ( i - > first = = setup . projectName )
2010-11-10 03:56:42 +00:00
continue ;
solution < < " Project( \" { " < < solutionUUID < < " } \" ) = \" " < < i - > first < < " \" , \" " < < i - > first < < getProjectExtension ( ) < < " \" , \" { " < < i - > second < < " } \" \n "
< < " EndProject \n " ;
}
solution < < " Global \n "
" \t GlobalSection(SolutionConfigurationPlatforms) = preSolution \n "
" \t \t Debug|Win32 = Debug|Win32 \n "
2012-09-05 07:54:33 -04:00
" \t \t Analysis|Win32 = Analysis|Win32 \n "
2013-09-05 23:48:33 -04:00
" \t \t LLVM|Win32 = LLVM|Win32 \n "
2010-11-10 03:56:42 +00:00
" \t \t Release|Win32 = Release|Win32 \n "
" \t \t Debug|x64 = Debug|x64 \n "
2012-09-05 07:54:33 -04:00
" \t \t Analysis|x64 = Analysis|x64 \n "
2013-09-05 23:48:33 -04:00
" \t \t LLVM|x64 = LLVM|x64 \n "
2010-11-10 03:56:42 +00:00
" \t \t Release|x64 = Release|x64 \n "
2020-05-08 13:17:36 -07:00
" \t \t Debug|arm64 = Debug|arm64 \n "
" \t \t Analysis|arm64 = Analysis|arm64 \n "
" \t \t LLVM|arm64 = LLVM|arm64 \n "
" \t \t Release|arm64 = Release|arm64 \n "
2010-11-10 03:56:42 +00:00
" \t EndGlobalSection \n "
" \t GlobalSection(ProjectConfigurationPlatforms) = postSolution \n " ;
for ( UUIDMap : : const_iterator i = _uuidMap . begin ( ) ; i ! = _uuidMap . end ( ) ; + + i ) {
solution < < " \t \t { " < < i - > second < < " }.Debug|Win32.ActiveCfg = Debug|Win32 \n "
" \t \t { " < < i - > second < < " }.Debug|Win32.Build.0 = Debug|Win32 \n "
2012-09-05 07:54:33 -04:00
" \t \t { " < < i - > second < < " }.Analysis|Win32.ActiveCfg = Analysis|Win32 \n "
" \t \t { " < < i - > second < < " }.Analysis|Win32.Build.0 = Analysis|Win32 \n "
2013-09-05 23:48:33 -04:00
" \t \t { " < < i - > second < < " }.LLVM|Win32.ActiveCfg = LLVM|Win32 \n "
" \t \t { " < < i - > second < < " }.LLVM|Win32.Build.0 = LLVM|Win32 \n "
2010-11-10 03:56:42 +00:00
" \t \t { " < < i - > second < < " }.Release|Win32.ActiveCfg = Release|Win32 \n "
" \t \t { " < < i - > second < < " }.Release|Win32.Build.0 = Release|Win32 \n "
" \t \t { " < < i - > second < < " }.Debug|x64.ActiveCfg = Debug|x64 \n "
" \t \t { " < < i - > second < < " }.Debug|x64.Build.0 = Debug|x64 \n "
2012-09-05 07:54:33 -04:00
" \t \t { " < < i - > second < < " }.Analysis|x64.ActiveCfg = Analysis|x64 \n "
" \t \t { " < < i - > second < < " }.Analysis|x64.Build.0 = Analysis|x64 \n "
2013-09-05 23:48:33 -04:00
" \t \t { " < < i - > second < < " }.LLVM|x64.ActiveCfg = LLVM|x64 \n "
" \t \t { " < < i - > second < < " }.LLVM|x64.Build.0 = LLVM|x64 \n "
2010-11-10 03:56:42 +00:00
" \t \t { " < < i - > second < < " }.Release|x64.ActiveCfg = Release|x64 \n "
2020-05-08 13:17:36 -07:00
" \t \t { " < < i - > second < < " }.Release|x64.Build.0 = Release|x64 \n "
" \t \t { " < < i - > second < < " }.Debug|arm64.ActiveCfg = Debug|arm64 \n "
" \t \t { " < < i - > second < < " }.Debug|arm64.Build.0 = Debug|arm64 \n "
" \t \t { " < < i - > second < < " }.Analysis|arm64.ActiveCfg = Analysis|arm64 \n "
" \t \t { " < < i - > second < < " }.Analysis|arm64.Build.0 = Analysis|arm64 \n "
" \t \t { " < < i - > second < < " }.LLVM|arm64.ActiveCfg = LLVM|arm64 \n "
" \t \t { " < < i - > second < < " }.LLVM|arm64.Build.0 = LLVM|arm64 \n "
" \t \t { " < < i - > second < < " }.Release|arm64.ActiveCfg = Release|arm64 \n "
" \t \t { " < < i - > second < < " }.Release|arm64.Build.0 = Release|arm64 \n " ;
2010-11-10 03:56:42 +00:00
}
solution < < " \t EndGlobalSection \n "
" \t GlobalSection(SolutionProperties) = preSolution \n "
" \t \t HideSolutionNode = FALSE \n "
" \t EndGlobalSection \n "
" EndGlobal \n " ;
}
void MSVCProvider : : createOtherBuildFiles ( const BuildSetup & setup ) {
// Create the global property file
createGlobalProp ( setup ) ;
// Create the configuration property files (for Debug and Release with 32 and 64bits versions)
// Note: we use the debug properties for the analysis configuration
2020-05-08 13:17:36 -07:00
createBuildProp ( setup , true , MSVC_Architecture : : ARCH_AMD64 , " Release " ) ;
createBuildProp ( setup , true , MSVC_Architecture : : ARCH_X86 , " Release " ) ;
createBuildProp ( setup , true , MSVC_Architecture : : ARCH_ARM64 , " Release " ) ;
createBuildProp ( setup , false , MSVC_Architecture : : ARCH_AMD64 , " Debug " ) ;
createBuildProp ( setup , false , MSVC_Architecture : : ARCH_X86 , " Debug " ) ;
createBuildProp ( setup , false , MSVC_Architecture : : ARCH_ARM64 , " Debug " ) ;
createBuildProp ( setup , false , MSVC_Architecture : : ARCH_AMD64 , " Analysis " ) ;
createBuildProp ( setup , false , MSVC_Architecture : : ARCH_X86 , " Analysis " ) ;
createBuildProp ( setup , false , MSVC_Architecture : : ARCH_ARM64 , " Analysis " ) ;
createBuildProp ( setup , false , MSVC_Architecture : : ARCH_AMD64 , " LLVM " ) ;
createBuildProp ( setup , false , MSVC_Architecture : : ARCH_X86 , " LLVM " ) ;
createBuildProp ( setup , false , MSVC_Architecture : : ARCH_ARM64 , " LLVM " ) ;
2010-11-10 03:56:42 +00:00
}
2015-12-01 21:00:32 +01:00
void MSVCProvider : : addResourceFiles ( const BuildSetup & setup , StringList & includeList , StringList & excludeList ) {
includeList . push_back ( setup . srcDir + " /icons/ " + setup . projectName + " .ico " ) ;
includeList . push_back ( setup . srcDir + " /dists/ " + setup . projectName + " .rc " ) ;
}
2010-11-10 03:56:42 +00:00
void MSVCProvider : : createGlobalProp ( const BuildSetup & setup ) {
2020-05-08 13:17:36 -07:00
std : : ofstream properties ( ( setup . outputDir + ' / ' + setup . projectDescription + " _Global " + getMSVCArchName ( MSVC_Architecture : : ARCH_X86 ) + getPropertiesExtension ( ) ) . c_str ( ) ) ;
2010-11-10 03:56:42 +00:00
if ( ! properties )
2020-05-08 13:17:36 -07:00
error ( " Could not open \" " + setup . outputDir + ' / ' + setup . projectDescription + " _Global " + getMSVCArchName ( MSVC_Architecture : : ARCH_X86 ) + getPropertiesExtension ( ) + " \" for writing " ) ;
2010-11-10 03:56:42 +00:00
2020-05-08 13:17:36 -07:00
outputGlobalPropFile ( setup , properties , MSVC_Architecture : : ARCH_X86 , setup . defines , convertPathToWin ( setup . filePrefix ) , setup . runBuildEvents ) ;
2010-11-10 03:56:42 +00:00
properties . close ( ) ;
2020-05-08 13:17:36 -07:00
properties . open ( ( setup . outputDir + ' / ' + setup . projectDescription + " _Global " + getMSVCArchName ( MSVC_Architecture : : ARCH_AMD64 ) + getPropertiesExtension ( ) ) . c_str ( ) ) ;
2010-11-10 03:56:42 +00:00
if ( ! properties )
2020-05-08 13:17:36 -07:00
error ( " Could not open \" " + setup . outputDir + ' / ' + setup . projectDescription + " _Global " + getMSVCArchName ( MSVC_Architecture : : ARCH_AMD64 ) + getPropertiesExtension ( ) + " \" for writing " ) ;
BuildSetup amd64setup = setup ;
auto amd64_disabled_features_it = s_arch_disabled_features . find ( MSVC_Architecture : : ARCH_AMD64 ) ;
if ( amd64_disabled_features_it ! = s_arch_disabled_features . end ( ) ) {
for ( auto feature : amd64_disabled_features_it - > second ) {
amd64setup = removeFeatureFromSetup ( amd64setup , feature ) ;
2019-07-01 02:46:02 +01:00
}
}
2011-01-16 19:38:22 +00:00
2020-05-08 13:17:36 -07:00
outputGlobalPropFile ( amd64setup , properties , MSVC_Architecture : : ARCH_AMD64 , amd64setup . defines , convertPathToWin ( amd64setup . filePrefix ) , amd64setup . runBuildEvents ) ;
properties . close ( ) ;
properties . open ( ( setup . outputDir + ' / ' + setup . projectDescription + " _Global " + getMSVCArchName ( MSVC_Architecture : : ARCH_ARM64 ) + getPropertiesExtension ( ) ) . c_str ( ) ) ;
if ( ! properties )
error ( " Could not open \" " + setup . outputDir + ' / ' + setup . projectDescription + " _Global " + getMSVCArchName ( MSVC_Architecture : : ARCH_ARM64 ) + getPropertiesExtension ( ) + " \" for writing " ) ;
BuildSetup arm64setup = setup ;
auto arm64_disabled_features_it = s_arch_disabled_features . find ( MSVC_Architecture : : ARCH_ARM64 ) ;
if ( arm64_disabled_features_it ! = s_arch_disabled_features . end ( ) ) {
for ( auto feature : arm64_disabled_features_it - > second ) {
arm64setup = removeFeatureFromSetup ( arm64setup , feature ) ;
}
}
outputGlobalPropFile ( arm64setup , properties , MSVC_Architecture : : ARCH_ARM64 , arm64setup . defines , convertPathToWin ( setup . filePrefix ) , setup . runBuildEvents ) ;
properties . close ( ) ;
2010-11-10 03:56:42 +00:00
}
2010-11-19 14:12:33 +00:00
std : : string MSVCProvider : : getPreBuildEvent ( ) const {
2010-11-10 03:56:42 +00:00
std : : string cmdLine = " " ;
cmdLine = " @echo off \n "
2010-11-19 14:12:33 +00:00
" echo Executing Pre-Build script... \n "
2015-09-28 19:23:58 -04:00
" echo. \n "
2018-12-19 05:56:36 +00:00
" @call "$(SolutionDir)../../devtools/create_project/scripts/prebuild.cmd" "$(SolutionDir)/../.." "$(SolutionDir)" \n "
2010-11-10 03:56:42 +00:00
" EXIT /B0 " ;
return cmdLine ;
}
2013-07-07 11:23:19 -04:00
std : : string MSVCProvider : : getTestPreBuildEvent ( const BuildSetup & setup ) const {
// Build list of folders containing tests
std : : string target = " " ;
for ( StringList : : const_iterator it = setup . testDirs . begin ( ) ; it ! = setup . testDirs . end ( ) ; + + it )
target + = " $(SolutionDir) " + * it + " *.h " ;
2018-12-19 06:03:50 +00:00
return " "$(SolutionDir)../../test/cxxtest/cxxtestgen.py" --runner=ParenPrinter --no-std --no-eh -o "$(SolutionDir)test_runner.cpp" " + target ;
2013-07-07 11:23:19 -04:00
}
2020-05-08 13:17:36 -07:00
std : : string MSVCProvider : : getPostBuildEvent ( MSVC_Architecture arch , const BuildSetup & setup ) const {
2010-11-10 03:56:42 +00:00
std : : string cmdLine = " " ;
cmdLine = " @echo off \n "
2010-11-19 14:12:33 +00:00
" echo Executing Post-Build script... \n "
" echo. \n "
2011-04-09 23:47:35 +02:00
" @call "$(SolutionDir)../../devtools/create_project/scripts/postbuild.cmd" "$(SolutionDir)/../.." "$(OutDir)" " ;
2010-11-19 14:12:33 +00:00
2018-12-19 20:47:51 +00:00
cmdLine + = ( setup . useSDL2 ) ? " SDL2 " : " SDL " ;
2010-11-19 14:12:33 +00:00
2018-12-19 20:47:51 +00:00
cmdLine + = " "% " LIBS_DEFINE " %/lib/ " ;
2020-05-08 13:17:36 -07:00
cmdLine + = getMSVCArchName ( arch ) ;
2018-12-19 20:47:51 +00:00
cmdLine + = " /$(Configuration)" " ;
2011-04-26 20:10:46 -04:00
// Specify if installer needs to be built or not
2018-12-19 20:47:51 +00:00
cmdLine + = ( setup . createInstaller ? " 1 " : " 0 " ) ;
2011-04-24 13:33:23 -04:00
2010-11-19 14:12:33 +00:00
cmdLine + = " \n "
" EXIT /B0 " ;
2010-11-10 03:56:42 +00:00
return cmdLine ;
}
} // End of CreateProjectTool namespace