diff --git a/samples/vs2002/CppExe/CppExe.vcproj b/samples/vs2002/CppExe/CppExe.vcproj new file mode 100644 index 00000000..6e66c470 --- /dev/null +++ b/samples/vs2002/CppExe/CppExe.vcproj @@ -0,0 +1,111 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/vs2002/MySolution.sln b/samples/vs2002/MySolution.sln new file mode 100644 index 00000000..8ba916b3 --- /dev/null +++ b/samples/vs2002/MySolution.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 7.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppExe", "CppExe/CppExe.vcproj", "{AE61726D-187C-E440-BD07-2556188A6565}" +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + ConfigName.0 = Debug + ConfigName.1 = Release + EndGlobalSection + GlobalSection(ProjectDependencies) = postSolution + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {AE61726D-187C-E440-BD07-2556188A6565}.Debug.ActiveCfg = Debug|Win32 + {AE61726D-187C-E440-BD07-2556188A6565}.Debug.Build.0 = Debug|Win32 + {AE61726D-187C-E440-BD07-2556188A6565}.Release.ActiveCfg = Release|Win32 + {AE61726D-187C-E440-BD07-2556188A6565}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/samples/vs2003/CppExe/CppExe.vcproj b/samples/vs2003/CppExe/CppExe.vcproj new file mode 100644 index 00000000..9c108251 --- /dev/null +++ b/samples/vs2003/CppExe/CppExe.vcproj @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/vs2003/MySolution.sln b/samples/vs2003/MySolution.sln new file mode 100644 index 00000000..122efcaa --- /dev/null +++ b/samples/vs2003/MySolution.sln @@ -0,0 +1,21 @@ +Microsoft Visual Studio Solution File, Format Version 8.00 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppExe", "CppExe/CppExe.vcproj", "{2606321E-67AA-8244-A5C1-67F2E3F8CA0C}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfiguration) = preSolution + Debug = Debug + Release = Release + EndGlobalSection + GlobalSection(ProjectConfiguration) = postSolution + {2606321E-67AA-8244-A5C1-67F2E3F8CA0C}.Debug.ActiveCfg = Debug|Win32 + {2606321E-67AA-8244-A5C1-67F2E3F8CA0C}.Debug.Build.0 = Debug|Win32 + {2606321E-67AA-8244-A5C1-67F2E3F8CA0C}.Release.ActiveCfg = Release|Win32 + {2606321E-67AA-8244-A5C1-67F2E3F8CA0C}.Release.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + EndGlobalSection + GlobalSection(ExtensibilityAddIns) = postSolution + EndGlobalSection +EndGlobal diff --git a/src/action/make/make_solution.c b/src/action/make/make_solution.c index 5304e3f6..eb4494e5 100644 --- a/src/action/make/make_solution.c +++ b/src/action/make/make_solution.c @@ -43,15 +43,14 @@ int make_solution_create(Session sess, Solution sln, Stream strm) */ int make_solution_signature(Session sess, Solution sln, Stream strm) { - int z = OKAY; + int z; assert(strm); - sess = 0; /* unused */ - sln = 0; /* unused */ + UNUSED(sess); + UNUSED(sln); - z |= stream_writeline(strm, "# GNU Makefile autogenerated by Premake"); + z = stream_writeline(strm, "# GNU Makefile autogenerated by Premake"); z |= stream_writeline(strm, "# Usage: make [ CONFIG=config_name ]"); z |= stream_writeline(strm, "# Where {config_name} is one of:"); - return z; } diff --git a/src/action/vs200x/tests/vs2002_solution_tests.cpp b/src/action/vs200x/tests/vs2002_solution_tests.cpp new file mode 100644 index 00000000..bd89da2a --- /dev/null +++ b/src/action/vs200x/tests/vs2002_solution_tests.cpp @@ -0,0 +1,111 @@ +/** + * \file vs2002_solution_tests.cpp + * \brief Automated tests for VS2002 solution processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "action/vs200x/vs200x_solution.h" +} + +#include "vs200x_tests.h" + + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxVs200x, Vs2002_Signature_IsCorrect) + { + session_set_action(sess, "vs2002"); + vs2002_solution_signature(sess, sln, strm); + CHECK_EQUAL( + "Microsoft Visual Studio Solution File, Format Version 7.00\r\n", + buffer); + } + + + /********************************************************************** + * Project entry tests + **********************************************************************/ + + TEST_FIXTURE(FxVs200x, Vs2002_ProjectEntry_UsesRelativePath) + { + vs2002_solution_projects(sess, sln, strm); + CHECK_EQUAL( + "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"MyProject\", \"ProjectFolder\\MyProject.vcproj\", \"{AE2461B7-236F-4278-81D3-F0D476F9A4C0}\"\n" + "EndProject\n", + buffer); + } + + + /********************************************************************** + * Solution configuration tests + **********************************************************************/ + + TEST_FIXTURE(FxVs200x, Vs2002_SolutionConfiguration_IsCorrect) + { + vs2002_solution_configuration(sess, sln, strm); + CHECK_EQUAL( + "Global\n" + "\tGlobalSection(SolutionConfiguration) = preSolution\n" + "\t\tConfigName.0 = Debug\n" + "\t\tConfigName.1 = Release\n" + "\tEndGlobalSection\n", + buffer); + } + + + /********************************************************************** + * Project dependencies tests + **********************************************************************/ + + TEST_FIXTURE(FxVs200x, Vs2002_ProjectDependencies_IsCorrect) + { + vs2002_solution_dependencies(sess, sln, strm); + CHECK_EQUAL( + "\tGlobalSection(ProjectDependencies) = postSolution\n" + "\tEndGlobalSection\n", + buffer); + } + + + /********************************************************************** + * Project configuration tests + **********************************************************************/ + + TEST_FIXTURE(FxVs200x, Vs2002_ProjectConfiguration_IsCorrect) + { + vs2002_solution_project_configuration(sess, sln, strm); + CHECK_EQUAL( + "\tGlobalSection(ProjectConfiguration) = postSolution\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug.ActiveCfg = Debug|Win32\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug.Build.0 = Debug|Win32\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release.ActiveCfg = Release|Win32\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release.Build.0 = Release|Win32\n" + "\tEndGlobalSection\n", + buffer); + } + + + /********************************************************************** + * Solution extensibility tests + **********************************************************************/ + + TEST_FIXTURE(FxVs200x, Vs2002_Extensibility_IsCorrect) + { + vs2002_solution_extensibility(sess, sln, strm); + CHECK_EQUAL( + "\tGlobalSection(ExtensibilityGlobals) = postSolution\n" + "\tEndGlobalSection\n" + "\tGlobalSection(ExtensibilityAddIns) = postSolution\n" + "\tEndGlobalSection\n" + "EndGlobal\n", + buffer); + } + +} diff --git a/src/action/vs200x/tests/vs2003_solution_tests.cpp b/src/action/vs200x/tests/vs2003_solution_tests.cpp new file mode 100644 index 00000000..4fd8e59c --- /dev/null +++ b/src/action/vs200x/tests/vs2003_solution_tests.cpp @@ -0,0 +1,48 @@ +/** + * \file vs2003_solution_tests.cpp + * \brief Automated tests for VS2003 solution processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "action/vs200x/vs200x_solution.h" +} + +#include "vs200x_tests.h" + + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxVs200x, Vs2003_Signature_IsCorrect) + { + session_set_action(sess, "vs2003"); + vs2003_solution_signature(sess, sln, strm); + CHECK_EQUAL( + "Microsoft Visual Studio Solution File, Format Version 8.00\r\n", + buffer); + } + + + /********************************************************************** + * Solution configuration tests + **********************************************************************/ + + TEST_FIXTURE(FxVs200x, Vs2003_SolutionConfiguration_IsCorrect) + { + vs2003_solution_configuration(sess, sln, strm); + CHECK_EQUAL( + "Global\n" + "\tGlobalSection(SolutionConfiguration) = preSolution\n" + "\t\tDebug = Debug\n" + "\t\tRelease = Release\n" + "\tEndGlobalSection\n", + buffer); + } + +} diff --git a/src/action/vs200x/tests/vs2005_solution_tests.cpp b/src/action/vs200x/tests/vs2005_solution_tests.cpp new file mode 100644 index 00000000..2346cd1b --- /dev/null +++ b/src/action/vs200x/tests/vs2005_solution_tests.cpp @@ -0,0 +1,83 @@ +/** + * \file vs2005_solution_tests.cpp + * \brief Automated tests for VS2005 solution processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "action/vs200x/vs200x_solution.h" +} + +#include "vs200x_tests.h" + + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxVs200x, Vs2005_Signature_IsCorrect) + { + session_set_action(sess, "vs2005"); + vs2005_solution_signature(sess, sln, strm); + CHECK_EQUAL( + "\357\273\277\r\n" + "Microsoft Visual Studio Solution File, Format Version 9.00\r\n" + "# Visual Studio 2005\r\n", + buffer); + } + + + /********************************************************************** + * Solution Configuration Platforms tests + **********************************************************************/ + + TEST_FIXTURE(FxVs200x, Platforms_IsCorrect) + { + vs2005_solution_platforms(sess, sln, strm); + CHECK_EQUAL( + "Global\n" + "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n" + "\t\tDebug|Win32 = Debug|Win32\n" + "\t\tRelease|Win32 = Release|Win32\n" + "\tEndGlobalSection\n", + buffer); + } + + + /********************************************************************** + * Project Configuration Platforms tests + **********************************************************************/ + + TEST_FIXTURE(FxVs200x, ProjectPlatforms_IsCorrect) + { + vs2005_solution_project_platforms(sess, sln, strm); + CHECK_EQUAL( + "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug|Win32.ActiveCfg = Debug|Win32\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug|Win32.Build.0 = Debug|Win32\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release|Win32.ActiveCfg = Release|Win32\n" + "\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release|Win32.Build.0 = Release|Win32\n" + "\tEndGlobalSection\n", + buffer); + } + + + /********************************************************************** + * Solution Project tests + **********************************************************************/ + + TEST_FIXTURE(FxVs200x, Properties_IsCorrect) + { + vs2005_solution_properties(sess, sln, strm); + CHECK_EQUAL( + "\tGlobalSection(SolutionProperties) = preSolution\n" + "\t\tHideSolutionNode = FALSE\n" + "\tEndGlobalSection\n" + "EndGlobal\n", + buffer); + } +} diff --git a/src/action/vs200x/tests/vs200x_solution_tests.cpp b/src/action/vs200x/tests/vs200x_solution_tests.cpp deleted file mode 100644 index 01589729..00000000 --- a/src/action/vs200x/tests/vs200x_solution_tests.cpp +++ /dev/null @@ -1,112 +0,0 @@ -/** - * \file vs200x_solution_tests.cpp - * \brief Automated tests for VS200x solution processing. - * \author Copyright (c) 2008 Jason Perkins and the Premake project - */ - -#include "premake.h" -#include "testing/testing.h" -extern "C" { -#include "action/vs200x/vs200x_solution.h" -} - -struct FxVs200xSln -{ - Session sess; - Stream strm; - Solution sln; - char buffer[8192]; - - FxVs200xSln() - { - sess = session_create(); - - strm = stream_create_null(); - stream_set_buffer(strm, buffer); - - sln = solution_create(); - solution_set_name(sln, "MySolution"); - solution_set_base_dir(sln, "/Root"); - } - - ~FxVs200xSln() - { - solution_destroy(sln); - stream_destroy(strm); - session_destroy(sess); - } - - Project AddProject() - { - Project prj = project_create(); - project_set_name(prj, "MyProject"); - project_set_base_dir(prj, "/Root"); - project_set_guid(prj, "AE2461B7-236F-4278-81D3-F0D476F9A4C0"); - solution_add_project(sln, prj); - return prj; - } -}; - - -SUITE(action) -{ - /********************************************************************** - * Signature tests - **********************************************************************/ - - TEST_FIXTURE(FxVs200xSln, Signature_IsCorrect_OnVs2002) - { - session_set_action(sess, "vs2002"); - vs200x_solution_signature(sess, sln, strm); - CHECK_EQUAL( - "\357\273\277Microsoft Visual Studio Solution File, Format Version 7.00\r\n", - buffer); - } - - TEST_FIXTURE(FxVs200xSln, Signature_IsCorrect_OnVs2003) - { - session_set_action(sess, "vs2003"); - vs200x_solution_signature(sess, sln, strm); - CHECK_EQUAL( - "\357\273\277Microsoft Visual Studio Solution File, Format Version 8.00\r\n", - buffer); - } - - TEST_FIXTURE(FxVs200xSln, Signature_IsCorrect_OnVs2005) - { - session_set_action(sess, "vs2005"); - vs200x_solution_signature(sess, sln, strm); - CHECK_EQUAL( - "\357\273\277\r\n" - "Microsoft Visual Studio Solution File, Format Version 9.00\r\n" - "# Visual Studio 2005\r\n", - buffer); - } - - - /********************************************************************** - * Project entry tests - **********************************************************************/ - - TEST_FIXTURE(FxVs200xSln, ProjectEntry_IsCorrect_OnCppProject) - { - AddProject(); - vs200x_solution_projects(sess, sln, strm); - CHECK_EQUAL( - "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"MyProject\", \"MyProject.vcproj\", \"{AE2461B7-236F-4278-81D3-F0D476F9A4C0}\"\n" - "EndProject\n", - buffer); - } - - TEST_FIXTURE(FxVs200xSln, ProjectEntry_UsesRelativePath) - { - Project prj = AddProject(); - project_set_location(prj, "ProjectFolder"); - vs200x_solution_projects(sess, sln, strm); - CHECK_EQUAL( - "Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"MyProject\", \"ProjectFolder\\MyProject.vcproj\", \"{AE2461B7-236F-4278-81D3-F0D476F9A4C0}\"\n" - "EndProject\n", - buffer); - } - -} diff --git a/src/action/vs200x/tests/vs200x_tests.cpp b/src/action/vs200x/tests/vs200x_tests.cpp index 0228717d..6643970d 100644 --- a/src/action/vs200x/tests/vs200x_tests.cpp +++ b/src/action/vs200x/tests/vs200x_tests.cpp @@ -10,20 +10,8 @@ extern "C" { #include "action/vs200x/vs200x.h" } -struct FxVs200x -{ - Session sess; +#include "vs200x_tests.h" - FxVs200x() - { - sess = session_create(); - } - - ~FxVs200x() - { - session_destroy(sess); - } -}; SUITE(action) { diff --git a/src/action/vs200x/tests/vs200x_tests.h b/src/action/vs200x/tests/vs200x_tests.h new file mode 100644 index 00000000..b9676541 --- /dev/null +++ b/src/action/vs200x/tests/vs200x_tests.h @@ -0,0 +1,42 @@ +/** + * \file vs200x_tests.h + * \brief Standard test fixtures for Visual Studio. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +struct FxVs200x +{ + Session sess; + Stream strm; + Solution sln; + Project prj; + char buffer[8192]; + + FxVs200x() + { + sess = session_create(); + + strm = stream_create_null(); + stream_set_buffer(strm, buffer); + + sln = solution_create(); + solution_set_name(sln, "MySolution"); + solution_set_base_dir(sln, "/Root"); + solution_add_config_name(sln, "Debug"); + solution_add_config_name(sln, "Release"); + + prj = project_create(); + project_set_name(prj, "MyProject"); + project_set_base_dir(prj, "/Root"); + project_set_location(prj, "ProjectFolder"); + project_set_guid(prj, "AE2461B7-236F-4278-81D3-F0D476F9A4C0"); + solution_add_project(sln, prj); + } + + ~FxVs200x() + { + solution_destroy(sln); + stream_destroy(strm); + session_destroy(sess); + } +}; diff --git a/src/action/vs200x/vs2002.c b/src/action/vs200x/vs2002.c index 27349b52..8c0c8a96 100644 --- a/src/action/vs200x/vs2002.c +++ b/src/action/vs200x/vs2002.c @@ -13,7 +13,13 @@ /** The VS2002 solution writing process, for session_enumerate_objects() */ static SessionSolutionCallback Vs2002SolutionCallbacks[] = { - vs200x_solution_create, + vs2002_solution_create, + vs2002_solution_signature, + vs2002_solution_projects, + vs2002_solution_configuration, + vs2002_solution_dependencies, + vs2002_solution_project_configuration, + vs2002_solution_extensibility, NULL }; diff --git a/src/action/vs200x/vs2002_solution.c b/src/action/vs200x/vs2002_solution.c new file mode 100644 index 00000000..b824b8c9 --- /dev/null +++ b/src/action/vs200x/vs2002_solution.c @@ -0,0 +1,192 @@ +/** + * \file vs2002_solution.c + * \brief Visual Studio 2002 solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "vs200x.h" +#include "vs200x_solution.h" +#include "vs200x_project.h" +#include "base/path.h" + + +/** + * Create the Visual Studio 2002 solution configuration block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2002_solution_configuration(Session sess, Solution sln, Stream strm) +{ + int i, n, z; + UNUSED(sess); + + z = stream_writeline(strm, "Global"); + z |= stream_writeline(strm, "\tGlobalSection(SolutionConfiguration) = preSolution"); + + n = solution_num_configs(sln); + for (i = 0; i < n; ++i) + { + const char* config_name = solution_get_config_name(sln, i); + z |= stream_writeline(strm, "\t\tConfigName.%d = %s", i, config_name); + } + + z |= stream_writeline(strm, "\tEndGlobalSection"); + return z; +} + + +/** + * Create the Visual Studio 2002 project dependencies block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2002_solution_dependencies(Session sess, Solution sln, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(sln); + z = stream_writeline(strm, "\tGlobalSection(ProjectDependencies) = postSolution"); + z |= stream_writeline(strm, "\tEndGlobalSection"); + return z; +} + + +/** + * Write out the Visual Studio 2002 solution extensibility block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2002_solution_extensibility(Session sess, Solution sln, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(sln); + z = stream_writeline(strm, "\tGlobalSection(ExtensibilityGlobals) = postSolution"); + z |= stream_writeline(strm, "\tEndGlobalSection"); + z |= stream_writeline(strm, "\tGlobalSection(ExtensibilityAddIns) = postSolution"); + z |= stream_writeline(strm, "\tEndGlobalSection"); + z |= stream_writeline(strm, "EndGlobal"); + return z; +} + + +/** + * Create a new output stream for a solution, and make it active for subsequent writes. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2002_solution_create(Session sess, Solution sln, Stream strm) +{ + /* create the solution file */ + const char* filename = solution_get_filename(sln, NULL, ".sln"); + strm = stream_create_file(filename); + if (!strm) + { + return !OKAY; + } + + /* make the stream active for the functions that come after */ + session_set_active_stream(sess, strm); + return OKAY; +} + + +/** + * Write out the Visual Studio 2002 project configurations block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2002_solution_project_configuration(Session sess, Solution sln, Stream strm) +{ + int pi, pn, z; + UNUSED(sess); + z = stream_writeline(strm, "\tGlobalSection(ProjectConfiguration) = postSolution"); + pn = solution_num_projects(sln); + for (pi = 0; pi < pn; ++pi) + { + int ci, cn; + Project prj = solution_get_project(sln, pi); + const char* prj_id = project_get_guid(prj); + + cn = solution_num_configs(sln); + for (ci = 0; ci < cn; ++ci) + { + const char* config_name = solution_get_config_name(sln, ci); + z |= stream_writeline(strm, "\t\t{%s}.%s.ActiveCfg = %s|Win32", prj_id, config_name, config_name); + z |= stream_writeline(strm, "\t\t{%s}.%s.Build.0 = %s|Win32", prj_id, config_name, config_name); + } + } + z |= stream_writeline(strm, "\tEndGlobalSection"); + return z; +} + + +/** + * Write out the list of projects contained by the solution. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2002_solution_projects(Session sess, Solution sln, Stream strm) +{ + const char* sln_path; + int i, n; + + UNUSED(sess); + + /* project file paths are specified relative to the solution */ + sln_path = path_directory(solution_get_filename(sln, NULL, NULL)); + + n = solution_num_projects(sln); + for (i = 0; i < n; ++i) + { + Project prj = solution_get_project(sln, i); + const char* prj_name = project_get_name(prj); + const char* prj_id = project_get_guid(prj); + const char* prj_lang = project_get_language(prj); + const char* prj_ext = vs200x_project_extension(prj); + const char* prj_file = project_get_filename(prj, prj_name, prj_ext); + const char* tool_id = vs200x_tool_guid(prj_lang); + + /* convert absolute project file name to be relative to solution */ + prj_file = path_relative(sln_path, prj_file); + prj_file = path_translate(prj_file, "\\"); + + stream_writeline(strm, "Project(\"{%s}\") = \"%s\", \"%s\", \"{%s}\"", tool_id, prj_name, prj_file, prj_id); + stream_writeline(strm, "EndProject"); + } + + return OKAY; +} + + +/** + * Write the Visual Studio 2002 solution file signature. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2002_solution_signature(Session sess, Solution sln, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(sln); + stream_set_newline(strm, "\r\n"); + z = stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 7.00"); + return z; +} diff --git a/src/action/vs200x/vs2003.c b/src/action/vs200x/vs2003.c index c5e83b0e..4bc026ad 100644 --- a/src/action/vs200x/vs2003.c +++ b/src/action/vs200x/vs2003.c @@ -13,7 +13,12 @@ /** The VS2003 solution writing process, for session_enumerate_objects() */ static SessionSolutionCallback Vs2003SolutionCallbacks[] = { - vs200x_solution_create, + vs2002_solution_create, + vs2003_solution_signature, + vs2002_solution_projects, + vs2003_solution_configuration, + vs2002_solution_project_configuration, + vs2002_solution_extensibility, NULL }; @@ -34,4 +39,3 @@ int vs2003_action(Session sess) stream_writeline(Console, "Generating project files for Visual Studio 2003..."); return session_enumerate_objects(sess, Vs2003SolutionCallbacks, Vs2003ProjectCallbacks); } - diff --git a/src/action/vs200x/vs2003_solution.c b/src/action/vs200x/vs2003_solution.c new file mode 100644 index 00000000..d2ee82b7 --- /dev/null +++ b/src/action/vs200x/vs2003_solution.c @@ -0,0 +1,55 @@ +/** + * \file vs2003_solution.c + * \brief Visual Studio 2003 solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "vs200x_solution.h" + + +/** + * Create the Visual Studio 2003 solution configuration block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2003_solution_configuration(Session sess, Solution sln, Stream strm) +{ + int i, n, z; + UNUSED(sess); + + z = stream_writeline(strm, "Global"); + z |= stream_writeline(strm, "\tGlobalSection(SolutionConfiguration) = preSolution"); + + n = solution_num_configs(sln); + for (i = 0; i < n; ++i) + { + const char* config_name = solution_get_config_name(sln, i); + z |= stream_writeline(strm, "\t\t%s = %s", config_name, config_name); + } + + z |= stream_writeline(strm, "\tEndGlobalSection"); + return z; +} + + +/** + * Write the Visual Studio 2003 solution file signature. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2003_solution_signature(Session sess, Solution sln, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(sln); + stream_set_newline(strm, "\r\n"); + z = stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 8.00"); + return z; +} diff --git a/src/action/vs200x/vs2005.c b/src/action/vs200x/vs2005.c index 7e8953fd..975d0f6c 100644 --- a/src/action/vs200x/vs2005.c +++ b/src/action/vs200x/vs2005.c @@ -13,9 +13,12 @@ /** The VS2005 solution writing process, for session_enumerate_objects() */ static SessionSolutionCallback Vs2005SolutionCallbacks[] = { - vs200x_solution_create, - vs200x_solution_signature, - vs200x_solution_projects, + vs2002_solution_create, + vs2005_solution_signature, + vs2002_solution_projects, + vs2005_solution_platforms, + vs2005_solution_project_platforms, + vs2005_solution_properties, NULL }; diff --git a/src/action/vs200x/vs2005_solution.c b/src/action/vs200x/vs2005_solution.c new file mode 100644 index 00000000..09aef762 --- /dev/null +++ b/src/action/vs200x/vs2005_solution.c @@ -0,0 +1,110 @@ +/** + * \file vs2005_solution.c + * \brief Visual Studio 2005 solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include +#include +#include "premake.h" +#include "vs200x_solution.h" + + +/** + * Write out the Visual Studio solution-level platform configuration block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2005_solution_platforms(Session sess, Solution sln, Stream strm) +{ + int i, n, z; + UNUSED(sess); + + z = stream_writeline(strm, "Global"); + z |= stream_writeline(strm, "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution"); + + n = solution_num_configs(sln); + for (i = 0; i < n; ++i) + { + const char* config_name = solution_get_config_name(sln, i); + z |= stream_writeline(strm, "\t\t%s|Win32 = %s|Win32", config_name, config_name); + } + + z |= stream_writeline(strm, "\tEndGlobalSection"); + return z; +} + + +/** + * Write out the Visual Studio 2005 project-level platform configurations block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2005_solution_project_platforms(Session sess, Solution sln, Stream strm) +{ + int pi, pn, z; + UNUSED(sess); + z = stream_writeline(strm, "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution"); + pn = solution_num_projects(sln); + for (pi = 0; pi < pn; ++pi) + { + int ci, cn; + Project prj = solution_get_project(sln, pi); + const char* prj_id = project_get_guid(prj); + + cn = solution_num_configs(sln); + for (ci = 0; ci < cn; ++ci) + { + const char* config_name = solution_get_config_name(sln, ci); + z |= stream_writeline(strm, "\t\t{%s}.%s|Win32.ActiveCfg = %s|Win32", prj_id, config_name, config_name); + z |= stream_writeline(strm, "\t\t{%s}.%s|Win32.Build.0 = %s|Win32", prj_id, config_name, config_name); + } + } + z |= stream_writeline(strm, "\tEndGlobalSection"); + return z; +} + + +/** + * Write out the Visual Studio 2005 solution properties block. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2005_solution_properties(Session sess, Solution sln, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(sln); + z = stream_writeline(strm, "\tGlobalSection(SolutionProperties) = preSolution"); + z |= stream_writeline(strm, "\t\tHideSolutionNode = FALSE"); + z |= stream_writeline(strm, "\tEndGlobalSection"); + z |= stream_writeline(strm, "EndGlobal"); + return z; +} + + +/** + * Write the Visual Studio 2005 solution file signature. + * \param sess The execution session context. + * \param sln The current solution. + * \param strm The currently active stream; set with session_set_active_stream(). + * \returns OKAY if successful. + */ +int vs2005_solution_signature(Session sess, Solution sln, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(sln); + stream_set_newline(strm, "\r\n"); + z = stream_write_unicode_marker(strm); + z |= stream_writeline(strm, ""); + z |= stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 9.00"); + z |= stream_writeline(strm, "# Visual Studio 2005"); + return z; +} diff --git a/src/action/vs200x/vs200x.c b/src/action/vs200x/vs200x.c index eaf61763..61f01234 100644 --- a/src/action/vs200x/vs200x.c +++ b/src/action/vs200x/vs200x.c @@ -5,9 +5,11 @@ */ #include +#include #include "premake.h" #include "vs200x.h" #include "base/cstr.h" +#include "base/error.h" /** @@ -36,3 +38,26 @@ int vs200x_get_target_version(Session sess) return 0; } } + + +/** + * Returns the Visual Studio GUID for a particular project type. + * \param language The programming language used in the project. + * \returns The GUID corresponding the programming language. + */ +const char* vs200x_tool_guid(const char* language) +{ + if (cstr_eq(language, "c") || cstr_eq(language, "c++")) + { + return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"; + } + else if (cstr_eq(language, "c#")) + { + return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"; + } + else + { + error_set("unsupported language '%s'", language); + return NULL; + } +} diff --git a/src/action/vs200x/vs200x.h b/src/action/vs200x/vs200x.h index 5053551b..a0ddbf37 100644 --- a/src/action/vs200x/vs200x.h +++ b/src/action/vs200x/vs200x.h @@ -8,7 +8,9 @@ #include "engine/session.h" -int vs200x_get_target_version(Session sess); +int vs200x_get_target_version(Session sess); +const char* vs200x_tool_guid(const char* language); + #endif diff --git a/src/action/vs200x/vs200x_solution.c b/src/action/vs200x/vs200x_solution.c deleted file mode 100644 index 2b21589f..00000000 --- a/src/action/vs200x/vs200x_solution.c +++ /dev/null @@ -1,137 +0,0 @@ -/** - * \file vs200x_solution.c - * \brief Visual Studio 200x solution generation functions. - * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project - */ - -#include -#include -#include "premake.h" -#include "vs200x.h" -#include "vs200x_solution.h" -#include "vs200x_project.h" -#include "base/cstr.h" -#include "base/error.h" -#include "base/path.h" - - -/** - * Create a new output stream for a solution, and make it active for subsequent writes. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs200x_solution_create(Session sess, Solution sln, Stream strm) -{ - /* create the solution file */ - const char* filename = solution_get_filename(sln, NULL, ".sln"); - strm = stream_create_file(filename); - if (!strm) - { - return !OKAY; - } - - /* make the stream active for the functions that come after */ - session_set_active_stream(sess, strm); - return OKAY; -} - - -/** - * Write out the list of projects contained by the solution. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs200x_solution_projects(Session sess, Solution sln, Stream strm) -{ - const char* sln_path; - int i, n; - sess = 0; /* unused */ - - /* project file paths are specified relative to the solution */ - sln_path = path_directory(solution_get_filename(sln, NULL, NULL)); - - n = solution_num_projects(sln); - for (i = 0; i < n; ++i) - { - Project prj = solution_get_project(sln, i); - const char* prj_name = project_get_name(prj); - const char* prj_id = project_get_guid(prj); - const char* prj_ext = vs200x_project_extension(prj); - const char* prj_file = project_get_filename(prj, prj_name, prj_ext); - const char* tool_id = vs200x_solution_tool_guid("c++"); - - /* convert absolute project file name to be relative to solution */ - prj_file = path_relative(sln_path, prj_file); - prj_file = path_translate(prj_file, "\\"); - - stream_writeline(strm, "Project(\"{%s}\") = \"%s\", \"%s\", \"{%s}\"", tool_id, prj_name, prj_file, prj_id); - stream_writeline(strm, "EndProject"); - } - - return OKAY; -} - - -/** - * Write the solution file signature block. - * \param sess The execution session context. - * \param sln The current solution. - * \param strm The currently active stream; set with session_set_active_stream(). - * \returns OKAY if successful. - */ -int vs200x_solution_signature(Session sess, Solution sln, Stream strm) -{ - int version, z; - - assert(sess); - assert(strm); - sln = 0; /* unused */ - - stream_set_newline(strm, "\r\n"); - z = stream_write_unicode_marker(strm); - - version = vs200x_get_target_version(sess); - switch (version) - { - case 2002: - z |= stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 7.00"); - break; - case 2003: - z |= stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 8.00"); - break; - case 2005: - z |= stream_writeline(strm, ""); - z |= stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 9.00"); - z |= stream_writeline(strm, "# Visual Studio 2005"); - break; - } - - return z; -} - - -/** - * Returns the Visual Studio GUID for a particular project type. - * \param language The programming language used in the project. - * \returns The GUID corresponding the programming language. - */ -const char* vs200x_solution_tool_guid(const char* language) -{ - if (cstr_eq(language, "c") || cstr_eq(language, "c++")) - { - return "8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942"; - } - else if (cstr_eq(language, "c#")) - { - return "FAE04EC0-301F-11D3-BF4B-00C04F79EFBC"; - } - else - { - error_set("unsupported language '%s'", language); - return NULL; - } -} diff --git a/src/action/vs200x/vs200x_solution.h b/src/action/vs200x/vs200x_solution.h index 1c3eaf02..1d926d4d 100644 --- a/src/action/vs200x/vs200x_solution.h +++ b/src/action/vs200x/vs200x_solution.h @@ -8,9 +8,20 @@ #include "engine/session.h" -int vs200x_solution_create(Session sess, Solution sln, Stream strm); -int vs200x_solution_projects(Session sess, Solution sln, Stream strm); -int vs200x_solution_signature(Session sess, Solution sln, Stream strm); -const char* vs200x_solution_tool_guid(const char* language); +int vs2002_solution_configuration(Session sess, Solution sln, Stream strm); +int vs2002_solution_create(Session sess, Solution sln, Stream strm); +int vs2002_solution_dependencies(Session sess, Solution sln, Stream strm); +int vs2002_solution_extensibility(Session sess, Solution sln, Stream strm); +int vs2002_solution_project_configuration(Session sess, Solution sln, Stream strm); +int vs2002_solution_projects(Session sess, Solution sln, Stream strm); +int vs2002_solution_signature(Session sess, Solution sln, Stream strm); + +int vs2003_solution_configuration(Session sess, Solution sln, Stream strm); +int vs2003_solution_signature(Session sess, Solution sln, Stream strm); + +int vs2005_solution_platforms(Session sess, Solution sln, Stream strm); +int vs2005_solution_project_platforms(Session sess, Solution sln, Stream strm); +int vs2005_solution_properties(Session sess, Solution sln, Stream strm); +int vs2005_solution_signature(Session sess, Solution sln, Stream strm); #endif diff --git a/src/engine/unload.c b/src/engine/unload.c index 399f505b..3a213054 100644 --- a/src/engine/unload.c +++ b/src/engine/unload.c @@ -8,6 +8,8 @@ #include "premake.h" #include "internals.h" +static int unload_solution_projects(Session sess, lua_State* L, struct UnloadFuncs* funcs, Solution sln); + /** * Copy project information out of the scripting environment and into C objects that @@ -34,29 +36,17 @@ int unload_all(Session sess, lua_State* L, struct UnloadFuncs* funcs) { Solution sln = solution_create(); session_add_solution(sess, sln); - lua_rawgeti(L, -1, si); + + /* hardcoded a standard set of configurations for now */ + solution_add_config_name(sln, "Debug"); + solution_add_config_name(sln, "Release"); + + /* extract the project fields */ status = funcs->unload_solution(sess, L, sln); if (status == OKAY) { - /* iterate over list of projects */ - int pi, pn; - lua_getfield(L, -1, PROJECTS_KEY); - pn = luaL_getn(L, -1); - for (pi = 1; status == OKAY && pi <= pn; ++pi) - { - Project prj = project_create(); - solution_add_project(sln, prj); - - lua_rawgeti(L, -1, pi); - status = funcs->unload_project(sess, L, prj); - - /* remove project object from stack */ - lua_pop(L, 1); - } - - /* remove list of projects from stack */ - lua_pop(L, 1); + status = unload_solution_projects(sess, L, funcs, sln); } /* remove solution object from stack */ @@ -69,6 +59,33 @@ int unload_all(Session sess, lua_State* L, struct UnloadFuncs* funcs) } +static int unload_solution_projects(Session sess, lua_State* L, struct UnloadFuncs* funcs, Solution sln) +{ + int pi, pn; + int status = OKAY; + + /* iterate over list of projects from the solution */ + lua_getfield(L, -1, PROJECTS_KEY); + pn = luaL_getn(L, -1); + for (pi = 1; status == OKAY && pi <= pn; ++pi) + { + Project prj = project_create(); + solution_add_project(sln, prj); + + /* unload the project fields */ + lua_rawgeti(L, -1, pi); + status = funcs->unload_project(sess, L, prj); + + /* remove project object from stack */ + lua_pop(L, 1); + } + + /* remove list of projects from stack */ + lua_pop(L, 1); + return status; +} + + /** * Unload information from the scripting environment for a particular solution. * \param sess The session object which contains the scripted project objects. diff --git a/src/premake.h b/src/premake.h index e54c1753..88f09ef0 100644 --- a/src/premake.h +++ b/src/premake.h @@ -35,3 +35,9 @@ */ #define ALLOC_CLASS(n) (n)malloc(sizeof(struct n##_impl)) + +/** + * Mark a variable as unused, so the compiler won't complain about it. I suspect + * there is a better way to do this. + */ +#define UNUSED(var) var = 0 diff --git a/src/premake.lua b/src/premake.lua index 7f6ccde9..c3b8f406 100644 --- a/src/premake.lua +++ b/src/premake.lua @@ -83,7 +83,7 @@ local subsystems = table.insert(package.files, matchfiles("testing/*.h", "testing/*.cpp", unittest.."/*")) for k,m in subsystems do - table.insert(package.files, matchfiles(m.."/tests/*.cpp")) + table.insert(package.files, matchfiles(m.."/tests/*.h", m.."/tests/*.cpp")) end if (windows) then diff --git a/src/project/project.c b/src/project/project.c index a433ac60..2b7ac4ab 100644 --- a/src/project/project.c +++ b/src/project/project.c @@ -111,6 +111,18 @@ const char* project_get_guid(Project prj) } +/** + * Retrieve the programming language specified for a project. + * \param prj The project to query. + * \returns The programming language specified for the project. + */ +const char* project_get_language(Project prj) +{ + prj = 0; + return "c++"; +} + + /** * Retrieve the output location (the relative path from the base directory to the * target output directory) for this project. diff --git a/src/project/project.h b/src/project/project.h index 9944abd8..c80c477c 100644 --- a/src/project/project.h +++ b/src/project/project.h @@ -33,6 +33,7 @@ void project_destroy(Project prj); const char* project_get_base_dir(Project prj); const char* project_get_filename(Project prj, const char* basename, const char* ext); const char* project_get_guid(Project prj); +const char* project_get_language(Project prj); const char* project_get_location(Project prj); const char* project_get_name(Project prj); const char* project_get_value(Project prj, enum ProjectField field); diff --git a/src/project/solution.c b/src/project/solution.c index dd68abfa..3d99ea66 100644 --- a/src/project/solution.c +++ b/src/project/solution.c @@ -27,6 +27,7 @@ struct FieldInfo SolutionFieldInfo[] = DEFINE_CLASS(Solution) { Fields fields; + Array configs; Array projects; }; @@ -39,6 +40,7 @@ Solution solution_create() { Solution sln = ALLOC_CLASS(Solution); sln->fields = fields_create(SolutionFieldInfo); + sln->configs = array_create(); sln->projects = array_create(); return sln; } @@ -54,6 +56,7 @@ void solution_destroy(Solution sln) assert(sln); fields_destroy(sln->fields); + array_destroy(sln->configs); n = solution_num_projects(sln); for (i = 0; i < n; ++i) @@ -67,6 +70,19 @@ void solution_destroy(Solution sln) } +/** + * Add a configuration name to a solution. + * \param sln The solution to contain the project. + * \param config_name The name of the configuration add. + */ +void solution_add_config_name(Solution sln, const char* config_name) +{ + assert(sln); + assert(config_name); + array_add(sln->configs, (void*)config_name); +} + + /** * Add a project to a solution. * \param sln The solution to contain the project. @@ -92,6 +108,21 @@ const char* solution_get_base_dir(Solution sln) } +/** + * Get the configuration name at a given index. + * \param sln The solution to query. + * \param index The configuration index to query. + * \returns The configuration name at the given index. + */ +const char* solution_get_config_name(Solution sln, int index) +{ + const char* name; + assert(sln); + name = (const char*)array_item(sln->configs, index); + return name; +} + + /** * Get the path to the solution output file, using the provided file extension. * \param sln The solution object to query. @@ -179,6 +210,18 @@ const char* solution_get_value(Solution sln, enum SolutionField field) } +/** + * Return the number of configurations contained by this solution. + * \param sln The solution to query. + * \returns The number of configurations contained by the solution. + */ +int solution_num_configs(Solution sln) +{ + assert(sln); + return array_size(sln->configs); +} + + /** * Return the number of projects contained by this solution. * \param sln The solution to query. diff --git a/src/project/solution.h b/src/project/solution.h index 5b8bbf78..8dfa48c4 100644 --- a/src/project/solution.h +++ b/src/project/solution.h @@ -30,13 +30,16 @@ DECLARE_CLASS(Solution) Solution solution_create(void); void solution_destroy(Solution sln); +void solution_add_config_name(Solution sln, const char* config_name); void solution_add_project(Solution sln, Project prj); const char* solution_get_base_dir(Solution sln); +const char* solution_get_config_name(Solution sln, int index); const char* solution_get_filename(Solution sln, const char* basename, const char* ext); const char* solution_get_location(Solution sln); const char* solution_get_name(Solution sln); Project solution_get_project(Solution sln, int index); const char* solution_get_value(Solution sln, enum SolutionField field); +int solution_num_configs(Solution sln); int solution_num_projects(Solution sln); void solution_set_base_dir(Solution sln, const char* base_dir); void solution_set_location(Solution sln, const char* location); diff --git a/src/project/tests/solution_tests.cpp b/src/project/tests/solution_tests.cpp index 5180337c..20539c8c 100644 --- a/src/project/tests/solution_tests.cpp +++ b/src/project/tests/solution_tests.cpp @@ -72,6 +72,31 @@ SUITE(project) } + /********************************************************************** + * Configuration containment tests + **********************************************************************/ + + TEST_FIXTURE(FxSolution, NumConfigs_IsZero_OnStartup) + { + int result = solution_num_configs(sln); + CHECK(result == 0); + } + + TEST_FIXTURE(FxSolution, AddConfig_IncrementsNumConfigs) + { + solution_add_config_name(sln, "Debug"); + int result = solution_num_configs(sln); + CHECK(result == 1); + } + + TEST_FIXTURE(FxSolution, AddConfig_CanRoundtrip) + { + solution_add_config_name(sln, "Debug"); + const char* result = solution_get_config_name(sln, 0); + CHECK_EQUAL("Debug", result); + } + + /********************************************************************** * Location tests **********************************************************************/