/********************************************************************** * Premake - vs6_cpp.c * The Visual C++ 6 C/C++ target * * Copyright (c) 2002-2005 Jason Perkins and the Premake project * * 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 in the file LICENSE.txt for details. **********************************************************************/ #include #include #include "premake.h" #include "vs6.h" static void writeCppFlags(); static void writeLinkFlags(); static const char* filterLinks(const char* name); static void listFiles(const char* path, int stage); int vs6_cpp() { const char* projTypeTag; const char* projTypeId; int i; /* Start the file */ if (!io_openfile(path_join(prj_get_pkgpath(), prj_get_pkgname(), "dsp"))) return 0; prj_select_config(0); if (prj_is_kind("winexe")) { projTypeTag = "Win32 (x86) Application"; projTypeId = "0x0101"; } else if (prj_is_kind("exe")) { projTypeTag = "Win32 (x86) Console Application"; projTypeId = "0x0103"; } else if (prj_is_kind("dll")) { projTypeTag = "Win32 (x86) Dynamic-Link Library"; projTypeId = "0x0102"; } else if (prj_is_kind("lib")) { projTypeTag = "Win32 (x86) Static Library"; projTypeId = "0x0104"; } else { puts("** Error: unrecognized package type"); return 0; } io_print("# Microsoft Developer Studio Project File - Name=\"%s\" - Package Owner=<4>\n", prj_get_pkgname()); io_print("# Microsoft Developer Studio Generated Build File, Format Version 6.00\n"); io_print("# ** DO NOT EDIT **\n"); io_print("\n"); io_print("# TARGTYPE \"%s\" %s\n", projTypeTag, projTypeId); io_print("\n"); prj_select_config(0); io_print("CFG=%s - Win32 %s\n", prj_get_pkgname(), prj_get_cfgname()); io_print("!MESSAGE This is not a valid makefile. To build this project using NMAKE,\n"); io_print("!MESSAGE use the Export Makefile command and run\n"); io_print("!MESSAGE \n"); io_print("!MESSAGE NMAKE /f \"%s.mak\".\n", prj_get_pkgname()); io_print("!MESSAGE \n"); io_print("!MESSAGE You can specify a configuration when running NMAKE\n"); io_print("!MESSAGE by defining the macro CFG on the command line. For example:\n"); io_print("!MESSAGE \n"); io_print("!MESSAGE NMAKE /f \"%s.mak\" CFG=\"%s - Win32 %s\"\n", prj_get_pkgname(), prj_get_pkgname(), prj_get_cfgname()); io_print("!MESSAGE \n"); io_print("!MESSAGE Possible choices for configuration are:\n"); io_print("!MESSAGE \n"); for (i = prj_get_numconfigs() - 1; i >= 0; --i) { prj_select_config(i); io_print("!MESSAGE \"%s - Win32 %s\" (based on \"%s\")\n", prj_get_pkgname(), prj_get_cfgname(), projTypeTag); } io_print("!MESSAGE \n"); io_print("\n"); io_print("# Begin Project\n"); io_print("# PROP AllowPerConfigDependencies 0\n"); io_print("# PROP Scc_ProjName \"\"\n"); io_print("# PROP Scc_LocalPath \"\"\n"); io_print("CPP=cl.exe\n"); if (!prj_is_kind("lib")) io_print("MTL=midl.exe\n"); io_print("RSC=rc.exe\n\n"); for (i = prj_get_numconfigs() - 1; i >= 0; --i) { const char* debugSymbol; int optimizeSize = prj_has_flag("optimize-size"); int optimizeSpeed = prj_has_flag("optimize-speed") || prj_has_flag("optimize"); int useDebugLibs = (!optimizeSize && !optimizeSpeed); prj_select_config(i); io_print("!%s \"$(CFG)\" == \"%s - Win32 %s\"\n\n", (i == (prj_get_numconfigs() - 1) ? "IF" : "ELSEIF"), prj_get_pkgname(), prj_get_cfgname()); io_print("# PROP BASE Use_MFC 0\n"); io_print("# PROP BASE Use_Debug_Libraries %d\n", useDebugLibs ? 1 : 0); io_print("# PROP BASE Output_Dir \"%s\"\n", prj_get_outdir()); io_print("# PROP BASE Intermediate_Dir \"%s\"\n", prj_get_objdir()); io_print("# PROP BASE Target_Dir \"\"\n"); io_print("# PROP Use_MFC 0\n"); io_print("# PROP Use_Debug_Libraries %d\n", useDebugLibs ? 1 : 0); io_print("# PROP Output_Dir \"%s\"\n", prj_get_outdir()); io_print("# PROP Intermediate_Dir \"%s\"\n", prj_get_objdir()); if (prj_is_kind("dll") && prj_has_flag("no-import-lib")) io_print("# PROP Ignore_Export_Lib 1\n"); io_print("# PROP Target_Dir \"\"\n"); io_print("# ADD BASE CPP /nologo"); writeCppFlags(); io_print("# ADD CPP /nologo"); writeCppFlags(); debugSymbol = prj_has_flag("no-symbols") ? "NDEBUG" : "_DEBUG"; if (prj_is_kind("winexe") || prj_is_kind("dll")) { io_print("# ADD BASE MTL /nologo /D \"%s\" /mktyplib203 /win32\n", debugSymbol); io_print("# ADD MTL /nologo /D \"%s\" /mktyplib203 /win32\n", debugSymbol); } io_print("# ADD BASE RSC /l 0x409 /d \"%s\"", debugSymbol); print_list(prj_get_resdefines(), " /d \"", "\"", "", NULL); print_list(prj_get_respaths(), " /i \"", "\"", "", NULL); print_list(prj_get_resoptions(), " ", "", "", NULL); io_print("\n"); io_print("# ADD RSC /l 0x409 /d \"%s\"", debugSymbol); print_list(prj_get_resdefines(), " /d \"", "\"", "", NULL); print_list(prj_get_respaths(), " /i \"", "\"", "", NULL); print_list(prj_get_resoptions(), " ", "", "", NULL); io_print("\n"); io_print("BSC32=bscmake.exe\n"); io_print("# ADD BASE BSC32 /nologo\n"); io_print("# ADD BSC32 /nologo\n"); if (prj_is_kind("lib")) { io_print("LINK32=link.exe -lib\n"); io_print("# ADD BASE LIB32 /nologo\n"); io_print("# ADD LIB32 /nologo"); io_print(" /out:\"%s\"\n", prj_get_target()); } else { io_print("LINK32=link.exe\n"); io_print("# ADD BASE LINK32"); writeLinkFlags(); io_print("# ADD LINK32"); writeLinkFlags(); } if (prj_get_numprelinkcommands() > 0 || prj_get_numpostbuildcommands() > 0) { io_print("# Begin Special Build Tool\n"); if (prj_get_numprelinkcommands() > 0) { io_print("PreLink_Cmds="); print_list(prj_get_prelinkcommands(), "", "", "\t", NULL); io_print("\n"); } if (prj_get_numpostbuildcommands() > 0) { io_print("PostBuild_Cmds="); print_list(prj_get_postbuildcommands(), "", "", "\t", NULL); io_print("\n"); } io_print("# End Special Build Tool\n"); } io_print("\n"); } io_print("!ENDIF\n"); io_print("\n"); io_print("# Begin Target\n"); io_print("\n"); for (i = prj_get_numconfigs() - 1; i >= 0; --i) { prj_select_config(i); io_print("# Name \"%s - Win32 %s\"\n", prj_get_pkgname(), prj_get_cfgname()); } print_source_tree("", listFiles); io_print("# End Target\n"); io_print("# End Project\n"); io_closefile(); return 1; } /************************************************************************ * Writes compiler flags for current configuration ***********************************************************************/ static void writeCppFlags() { int optimizeSize = prj_has_flag("optimize-size"); int optimizeSpeed = prj_has_flag("optimize-speed") || prj_has_flag("optimize"); int useDebugLibs = (!optimizeSize && !optimizeSpeed); if (useDebugLibs) io_print(prj_has_flag("static-runtime") ? " /MTd" : " /MDd"); else io_print(prj_has_flag("static-runtime") ? " /MT" : " /MD"); io_print(" /W%d", prj_has_flag("extra-warnings") ? 4 : 3); if (prj_has_flag("fatal-warnings")) io_print(" /WX"); if (useDebugLibs) io_print(" /Gm"); /* minimal rebuild */ if (!prj_has_flag("no-rtti")) io_print(" /GR"); if (!prj_has_flag("no-exceptions")) io_print(" /GX"); if (!prj_has_flag("no-symbols")) io_print(" /ZI"); /* debug symbols for edit-and-continue */ if (optimizeSize) io_print(" /O1"); else if (optimizeSpeed) io_print(" /O2"); else io_print(" /Od"); if (prj_has_flag("no-frame-pointer")) io_print(" /Oy"); print_list(prj_get_incpaths(), " /I \"", "\"", "", NULL); print_list(prj_get_defines(), " /D \"", "\"", "", NULL); io_print(" /YX /FD"); if (!optimizeSize && !optimizeSpeed) io_print(" /GZ"); io_print(" /c"); print_list(prj_get_buildoptions(), " ", "", "", NULL); io_print("\n"); } /************************************************************************ * Writes linker flags for current configuration ***********************************************************************/ static void writeLinkFlags() { print_list(prj_get_links(), " ", ".lib", "", filterLinks); io_print(" /nologo"); if ((prj_is_kind("winexe") || prj_is_kind("exe")) && !prj_has_flag("no-main")) io_print(" /entry:\"mainCRTStartup\""); if (prj_is_kind("winexe")) io_print(" /subsystem:windows"); else if (prj_is_kind("exe")) io_print(" /subsystem:console"); else io_print(" /dll"); if (!prj_has_flag("no-symbols")) io_print(" /incremental:yes /debug"); io_print(" /machine:I386"); if (prj_is_kind("dll")) { io_print(" /implib:\""); if (prj_has_flag("no-import-lib")) { io_print(prj_get_objdir()); } else { const char* str; io_print(prj_get_libdir()); str = path_getdir(prj_get_target_raw()); if (strlen(str) > 0) io_print("/%s", str); } if (prj_has_importlibname()) io_print("/%s.lib\"", prj_get_importlibname()); else io_print("/%s.lib\"", path_getbasename(prj_get_target())); } io_print(" /out:\"%s\"", prj_get_target()); if (!prj_has_flag("no-symbols")) io_print(" /pdbtype:sept"); io_print(" /libpath:\"%s\"", prj_get_libdir()); print_list(prj_get_libpaths(), " /libpath:\"", "\"", "", NULL); print_list(prj_get_linkoptions(), " ", "", "", NULL); io_print("\n"); } /************************************************************************ * Checks each entry in the list of package links. If the entry refers * to a sibling package, returns the path to that package's output ***********************************************************************/ static const char* filterLinks(const char* name) { int i = prj_find_package(name); if (i >= 0) { /* If this is a sibling package, don't return anything. VC6 * links to dependent projects implicitly */ return NULL; } else { return name; } } /************************************************************************ * Callback for print_source_tree() ***********************************************************************/ static void listFiles(const char* path, int stage) { const char* ptr = strrchr(path, '/'); ptr = (ptr == NULL) ? path : ptr + 1; switch (stage) { case WST_OPENGROUP: if (strlen(path) > 0 && strcmp(ptr, "..") != 0) { io_print("# Begin Group \"%s\"\n\n", ptr); io_print("# PROP Default_Filter \"\"\n"); } break; case WST_CLOSEGROUP: if (strlen(path) > 0 && strcmp(ptr, "..") != 0) io_print("# End Group\n"); break; case WST_SOURCEFILE: io_print("# Begin Source File\n\n"); io_print("SOURCE=%s\n", path); io_print("# End Source File\n"); break; } }