CREATE_PROJECT: Add a name table for MSVC library dependencies

Adds support for Debug/Release lib names and moves
Windows-specific code to the MSVC generator
This commit is contained in:
SupSuper 2020-08-15 14:45:55 +01:00 committed by Eugene Sandulenko
parent 6b15081607
commit dfb0123d56
5 changed files with 118 additions and 18 deletions

View File

@ -303,10 +303,14 @@ void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::s
// Link configuration for main project
if (name == setup.projectName || setup.devTools || setup.tests) {
std::string libraries;
std::string libraries = outputLibraryDependencies(setup, isRelease);
for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i)
libraries += *i + ".lib;";
// MSBuild uses ; for separators instead of spaces
for (std::string::iterator i = libraries.begin(); i != libraries.end(); ++i) {
if (*i == ' ') {
*i = ';';
}
}
project << "\t\t<Link>\n"
<< "\t\t\t<OutputFile>$(OutDir)" << ((setup.devTools || setup.tests) ? name : setup.projectName) << ".exe</OutputFile>\n"

View File

@ -53,6 +53,94 @@ MSVCProvider::MSVCProvider(StringList &global_warnings, std::map<std::string, St
_arch_disabled_features[ARCH_ARM64] = arm64_disabled_features;
}
std::string MSVCProvider::getLibraryFromFeature(const char *feature, const BuildSetup &setup, bool isRelease) const {
static const MSVCLibrary s_libraries[] = {
// Libraries
{ "sdl", "SDL.lib", "SDLd.lib", "winmm.lib imm32.lib version.lib setupapi.lib", 0 },
{ "sdl2", "SDL2.lib", "SDL2d.lib", "winmm.lib imm32.lib version.lib setupapi.lib", 0 },
{ "libz", "zlib.lib", "zlibd.lib", 0, 0 },
{ "mad", "mad.lib", 0, 0, "libmad.lib" },
{ "fribidi", "libfribidi.lib", 0, 0, 0 },
{ "ogg", "ogg.lib", 0, 0, "libogg_static.lib" },
{ "vorbis", "vorbis.lib vorbisfile.lib", 0, 0, "libvorbisfile_static.lib libvorbis_static.lib" },
{ "flac", "FLAC.lib", 0, 0, "libFLAC_static.lib win_utf8_io_static.lib" },
{ "png", "libpng16.lib", "libpng16d.lib", 0, 0 },
{ "faad", "faad.lib", 0, 0, "libfaad.lib" },
{ "mpeg2", "mpeg2.lib", 0, 0, "libmpeg2.lib" },
{ "theora", "theora.lib", 0, 0, "libtheora_static.lib" },
{ "freetype", "freetype.lib", "freetyped.lib", 0, 0 },
{ "jpeg", "jpeg.lib", "jpegd.lib", 0, "jpeg-static.lib" },
{"fluidsynth", "fluidsynth.lib", 0, 0, "libfluidsynth.lib" },
{ "libcurl", "libcurl.lib", "libcurl-d.lib", "ws2_32.lib wldap32.lib crypt32.lib normaliz.lib", 0 },
{ "sdlnet", "SDL_net.lib", 0, "iphlpapi.lib", 0 },
{ "sdl2net", "SDL2_net.lib", 0, "iphlpapi.lib", "SDL_net.lib" },
// Feature flags with library dependencies
{ "updates", "winsparkle.lib", 0, 0, 0 },
{ "tts", 0, 0, "sapi.lib", 0 }
};
// HACK for switching SDL_net to SDL2_net
const char *sdl2net = "sdl2net";
if (std::strcmp(feature, "sdlnet") == 0 && setup.useSDL2) {
feature = sdl2net;
}
const MSVCLibrary *library = 0;
for (unsigned int i = 0; i < sizeof(s_libraries) / sizeof(s_libraries[0]); i++) {
if (std::strcmp(feature, s_libraries[i].feature) == 0) {
library = &s_libraries[i];
break;
}
}
std::string libs;
if (library) {
// Dependencies come first
if (library->depends) {
libs += library->depends;
libs += " ";
}
const char *basename = library->release;
if (setup.useCanonicalLibNames) {
// Debug name takes priority
if (!isRelease && library->debug) {
basename = library->debug;
}
} else {
// Legacy name ignores configuration
if (library->legacy) {
basename = library->legacy;
}
}
if (basename) {
libs += basename;
}
}
return libs;
}
std::string MSVCProvider::outputLibraryDependencies(const BuildSetup &setup, bool isRelease) const {
std::string libs;
if (setup.useSDL2) {
libs += getLibraryFromFeature("sdl2", setup, isRelease);
} else {
libs += getLibraryFromFeature("sdl", setup, isRelease);
}
libs += " ";
for (FeatureList::const_iterator i = setup.features.begin(); i != setup.features.end(); ++i) {
if (i->enable) {
std::string lib = getLibraryFromFeature(i->name, setup, isRelease);
if (!lib.empty())
libs += lib + " ";
}
}
return libs;
}
void MSVCProvider::createWorkspace(const BuildSetup &setup) {
UUIDMap::const_iterator svmUUID = _uuidMap.find(setup.projectName);
if (svmUUID == _uuidMap.end())

View File

@ -38,7 +38,21 @@ protected:
StringList _disableEditAndContinue;
std::list<MSVC_Architecture> _archs;
std::map<MSVC_Architecture, StringList> _arch_disabled_features;
std::map<MSVC_Architecture, StringList> _arch_disabled_features;
/**
* MSVC properties for a library required by a feature
*/
struct MSVCLibrary {
const char *feature; ///< Feature ID.
const char *release; ///< Filename of the Release build of the library.
const char *debug; ///< Filename of the Debug build of the library.
const char *depends; ///< Win32 libs this library must be linked against.
const char *legacy; ///< Legacy name for old precompiled libraries (deprecated).
};
std::string getLibraryFromFeature(const char *feature, const BuildSetup &setup, bool isRelease) const;
std::string outputLibraryDependencies(const BuildSetup &setup, bool isRelease) const;
void createWorkspace(const BuildSetup &setup);

View File

@ -79,19 +79,11 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std:
std::map<std::string, std::list<std::string> >::iterator warningsIterator = _projectWarnings.find(name);
if (setup.devTools || setup.tests || name == setup.projectName) {
std::string libraries;
for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i)
libraries += ' ' + *i + ".lib";
// For 'x64' we must disable NASM support. Usually we would need to disable the "nasm" feature for that and
// re-create the library list, BUT since NASM doesn't link any additional libraries, we can just use the
// libraries list created for IA-32. If that changes in the future, we need to adjust this part!
for (std::list<MSVC_Architecture>::const_iterator arch = _archs.begin(); arch != _archs.end(); ++arch) {
outputConfiguration(project, setup, libraries, "Debug", *arch);
outputConfiguration(project, setup, libraries, "Analysis", *arch);
outputConfiguration(project, setup, libraries, "LLVM", *arch);
outputConfiguration(project, setup, libraries, "Release", *arch);
outputConfiguration(project, setup, false, "Debug", *arch);
outputConfiguration(project, setup, false, "Analysis", *arch);
outputConfiguration(project, setup, false, "LLVM", *arch);
outputConfiguration(project, setup, true, "Release", *arch);
}
} else {
@ -140,7 +132,9 @@ void VisualStudioProvider::createProjectFile(const std::string &name, const std:
<< "</VisualStudioProject>\n";
}
void VisualStudioProvider::outputConfiguration(std::ostream &project, const BuildSetup &setup, const std::string &libraries, const std::string &config, const MSVC_Architecture arch) {
void VisualStudioProvider::outputConfiguration(std::ostream &project, const BuildSetup &setup, bool isRelease, const std::string &config, const MSVC_Architecture arch) {
std::string libraries = outputLibraryDependencies(setup, isRelease);
project << "\t\t<Configuration Name=\"" << config << "|" << getMSVCConfigName(arch) << "\" ConfigurationType=\"1\" InheritedPropertySheets=\".\\" << setup.projectDescription << "_" << config << getMSVCArchName(arch) << ".vsprops\">\n"
<< "\t\t\t<Tool\tName=\"VCCLCompilerTool\" DisableLanguageExtensions=\"false\" DebugInformationFormat=\"3\" />\n"
<< "\t\t\t<Tool\tName=\"VCLinkerTool\" OutputFile=\"$(OutDir)/" << setup.projectName << ".exe\"\n"

View File

@ -50,7 +50,7 @@ protected:
const char *getProjectExtension();
const char *getPropertiesExtension();
void outputConfiguration(std::ostream &project, const BuildSetup &setup, const std::string &libraries, const std::string &config, const MSVC_Architecture arch);
void outputConfiguration(std::ostream &project, const BuildSetup &setup, bool isRelease, const std::string &config, const MSVC_Architecture arch);
void outputConfiguration(const BuildSetup &setup, std::ostream &project, const std::string &toolConfig, const std::string &config, const MSVC_Architecture arch);
void outputBuildEvents(std::ostream &project, const BuildSetup &setup, const MSVC_Architecture arch);
};