diff options
Diffstat (limited to 'src/actions')
44 files changed, 4528 insertions, 0 deletions
diff --git a/src/actions/actions.c b/src/actions/actions.c new file mode 100644 index 0000000..78b0d67 --- /dev/null +++ b/src/actions/actions.c @@ -0,0 +1,20 @@ +/** + * \file actions.c + * \brief Built-in engine actions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <string.h> +#include "premake.h" +#include "actions/actions.h" + + +SessionAction Actions[] = +{ + { "gmake", "GNU Makefiles for POSIX, MinGW, and Cygwin", gmake_action }, + { "vs2002", "Microsoft Visual Studio 2002", vs2002_action }, + { "vs2003", "Microsoft Visual Studio 2003", vs2003_action }, + { "vs2005", "Microsoft Visual Studio 2005 (includes Express editions)", vs2005_action }, + { "vs2008", "Microsoft Visual Studio 2008 (includes Express editions)", vs2008_action }, + { 0, 0, 0 } +}; diff --git a/src/actions/actions.h b/src/actions/actions.h new file mode 100644 index 0000000..5bdc6a5 --- /dev/null +++ b/src/actions/actions.h @@ -0,0 +1,31 @@ +/** + * \file actions.h + * \brief Built-in engine actions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + * + * \defgroup action Actions + * + * The actions component contains the implementation of all of the built-in + * Premake actions, along with a few common support functions. + * + * @{ + */ +#if !defined(PREMAKE_ACTIONS_H) +#define PREMAKE_ACTIONS_H + +#include "session/session.h" + + +int gmake_action (Session sess); +int vs2002_action(Session sess); +int vs2003_action(Session sess); +int vs2005_action(Session sess); +int vs2008_action(Session sess); + + +/* the list of built-in Premake actions */ +extern SessionAction Actions[]; + + +#endif +/** @} */ diff --git a/src/actions/make/gmake.c b/src/actions/make/gmake.c new file mode 100644 index 0000000..073cb5e --- /dev/null +++ b/src/actions/make/gmake.c @@ -0,0 +1,88 @@ +/** + * \file gmake.c + * \brief GNU makefile generation action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <stdlib.h> +#include "premake.h" +#include "actions/actions.h" +#include "make.h" +#include "make_solution.h" +#include "make_project.h" + + +/** The project features supported by this action */ +static SessionFeatures Features = +{ + { "c", "c++", NULL }, +}; + + +/** The GNU make solution writing process, for session_enumerate_objects() */ +static SessionSolutionCallback SolutionCallbacks[] = +{ + make_solution_create, + make_solution_signature, + make_solution_default_config, + make_solution_phony_rule, + make_solution_all_rule, + make_solution_projects, + make_solution_clean_rule, + NULL +}; + +/** The GNU make project writing process, for session_enumerate_objects() */ +static SessionProjectCallback ProjectCallbacks[] = +{ + make_project_create, + make_project_signature, + session_enumerate_configurations, + make_project_objects, + make_project_resources, + gmake_project_shell_detect, + make_project_phony_rule, + make_project_target, + make_project_mkdir_rules, + make_project_clean_rules, + make_project_source_rules, + make_project_include_dependencies, + NULL +}; + + +/** The GNU make configuration writing process, for session_enumerate_configurations() */ +static SessionProjectCallback ConfigCallbacks[] = +{ + make_project_config_conditional, + make_project_config_outdir, + make_project_config_outfile, + make_project_config_objdir, + make_project_config_cppflags, + make_project_config_cflags, + make_project_config_cxxflags, + make_project_config_ldflags, + make_project_config_lddeps, + make_project_config_resflags, + make_project_config_end, + NULL +}; + + +/** + * The GNU make action handler. + * \param sess The active session object. + * \returns OKAY if successful. + */ +int gmake_action(Session sess) +{ + /* make sure I can support all of the features used in the session */ + if (session_validate(sess, &Features) != OKAY) + { + return !OKAY; + } + + stream_writeline(Console, "Generating project files for GNU make..."); + return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); +} + diff --git a/src/actions/make/gmake_project.c b/src/actions/make/gmake_project.c new file mode 100644 index 0000000..3788e2d --- /dev/null +++ b/src/actions/make/gmake_project.c @@ -0,0 +1,49 @@ +/** + * \file gmake_project.c + * \brief GNU makefile project generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "make_project.h" + + +/** + * Write the shell detection block, which is used while building on Windows in + * order to detect the enclosing shell type: MS-DOS, Cygwin, or MinGW. The shell + * determines how directories and files should be created and removed. + * + * While the detection in important only on Windows, I write for all platforms. + * This simplifies the code generation, and makes portable makefiles possible + * (even though most will have platform-specific bits in them). + */ +int gmake_project_shell_detect(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + + UNUSED(sess); + UNUSED(prj); + + z |= stream_writeline(strm, "SHELLTYPE := msdos"); + z |= stream_writeline(strm, "ifeq (,$(ComSpec)$(COMSPEC))"); + z |= stream_writeline(strm, " SHELLTYPE := posix"); + z |= stream_writeline(strm, "endif"); + z |= stream_writeline(strm, "ifeq (/bin,$(findstring /bin,$(SHELL)))"); + z |= stream_writeline(strm, " SHELLTYPE := posix"); + z |= stream_writeline(strm, "endif"); + z |= stream_writeline(strm, ""); + z |= stream_writeline(strm, "ifeq (posix,$(SHELLTYPE))"); + z |= stream_writeline(strm, " MKDIR := mkdir -p"); + z |= stream_writeline(strm, " PATHSEP := /"); + z |= stream_writeline(strm, "else"); + z |= stream_writeline(strm, " MKDIR := mkdir"); + z |= stream_writeline(strm, " PATHSEP := \\\\"); + z |= stream_writeline(strm, "endif"); + z |= stream_writeline(strm, ""); + z |= stream_writeline(strm, "SYS_OUTDIR := $(subst /,$(PATHSEP),$(OUTDIR))"); + z |= stream_writeline(strm, "SYS_OUTFILE := $(subst /,$(PATHSEP),$(OUTFILE))"); + z |= stream_writeline(strm, "SYS_OBJDIR := $(subst /,$(PATHSEP),$(OBJDIR))"); + z |= stream_writeline(strm, ""); + return z; +} + diff --git a/src/actions/make/gmake_solution.c b/src/actions/make/gmake_solution.c new file mode 100644 index 0000000..5351441 --- /dev/null +++ b/src/actions/make/gmake_solution.c @@ -0,0 +1,19 @@ +/** + * \file gmake_solution.c + * \brief GNU makefile solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include "premake.h" +#include "make.h" +#include "make_solution.h" +#include "base/buffers.h" +#include "base/cstr.h" +#include "base/path.h" +#include "base/strings.h" + + + diff --git a/src/actions/make/make.c b/src/actions/make/make.c new file mode 100644 index 0000000..e2a1d7f --- /dev/null +++ b/src/actions/make/make.c @@ -0,0 +1,153 @@ +/** + * \file make.c + * \brief Support functions for the makefile action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <assert.h> +#include <stdlib.h> +#include "premake.h" +#include "make.h" +#include "base/cstr.h" +#include "base/error.h" +#include "base/path.h" + + +/** + * Given a source file filename, returns the name of the corresponding .o file. + * \param filename The source code filename. + * \returns The filename of the .o file. + */ +const char* make_get_obj_filename(const char* filename) +{ + const char* basename = path_basename(filename); + const char* obj_name = cstr_format("$(OBJDIR)/%s.o", basename); + return obj_name; +} + + +/** + * Get the name of the project makefile for a particular project. + * \param sess The current execution session context. + * \param prj The project being requested. + * \returns If this project is the only object which will generate output to + * its target location, then this function will return "Makefile" as + * the filename. If any other object shares this output location, it + * will return "ProjectName.make" instead, so that both objects may + * coexist in the same directory. + */ +const char* make_get_project_makefile(Session sess, Project prj) +{ + const char* my_path; + const char* their_path; + int si, sn; + + assert(sess); + assert(prj); + + /* get the full makefile path for this project */ + my_path = project_get_filename(prj, "Makefile", NULL); + + /* see if any other solution wants to use this same path */ + sn = session_num_solutions(sess); + for (si = 0; si < sn; ++si) + { + int pi, pn; + + Solution sln2 = session_get_solution(sess, si); + their_path = solution_get_filename(sln2, "Makefile", NULL); + if (cstr_eq(my_path, their_path)) + { + /* conflict; use the alternate name */ + my_path = project_get_filename(prj, NULL, ".make"); + return my_path; + } + + /* check any projects contained by this solution */ + pn = solution_num_projects(sln2); + for (pi = 0; pi < pn; ++pi) + { + Project prj2 = solution_get_project(sln2, pi); + if (prj != prj2) + { + their_path = project_get_filename(prj2, "Makefile", NULL); + if (cstr_eq(my_path, their_path)) + { + /* conflict; use the alternate name */ + my_path = project_get_filename(prj, NULL, ".make"); + return my_path; + } + } + } + } + + /* all good */ + return my_path; +} + + +/** + * Build a list of project names contained by the solution. + * \param sln The solution to query. + * \returns A list of project names. The caller owns this list and must destroy it when done. + */ +Strings make_get_project_names(Solution sln) +{ + Strings result; + int i, n; + + result = strings_create(); + n = solution_num_projects(sln); + for (i = 0; i < n; ++i) + { + Project prj = solution_get_project(sln, i); + const char* name = project_get_name(prj); + strings_add(result, name); + } + + return result; +} + + +/** + * Get the name of the solution makefile for a particular solution. + * \param sess The current execution session context. + * \param sln The solution being requested. + * \returns If this solution is the only object which will generate output to + * its target location, then this function will return "Makefile" as + * the filename. If any other solution shares this output location, it + * will return "SolutionName.make" instead, so that both objects may + * coexist in the same directory. + */ +const char* make_get_solution_makefile(Session sess, Solution sln) +{ + const char* my_path; + const char* their_path; + int i, n; + + assert(sess); + assert(sln); + + /* get the full makefile path for this solution */ + my_path = solution_get_filename(sln, "Makefile", NULL); + + /* see if any other solution wants to use this same path */ + n = session_num_solutions(sess); + for (i = 0; i < n; ++i) + { + Solution them = session_get_solution(sess, i); + if (them != sln) + { + their_path = solution_get_filename(them, "Makefile", NULL); + if (cstr_eq(my_path, their_path)) + { + /* conflict; use the alternate name */ + my_path = solution_get_filename(sln, NULL, ".make"); + return my_path; + } + } + } + + /* all good */ + return my_path; +} diff --git a/src/actions/make/make.h b/src/actions/make/make.h new file mode 100644 index 0000000..4ac8e43 --- /dev/null +++ b/src/actions/make/make.h @@ -0,0 +1,16 @@ +/** + * \file make.h + * \brief Support functions for the makefile action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_MAKE_H) +#define PREMAKE_MAKE_H + +#include "session/session.h" + +const char* make_get_obj_filename(const char* filename); +const char* make_get_project_makefile(Session sess, Project prj); +Strings make_get_project_names(Solution sln); +const char* make_get_solution_makefile(Session sess, Solution sln); + +#endif diff --git a/src/actions/make/make_project.c b/src/actions/make/make_project.c new file mode 100644 index 0000000..8e1298b --- /dev/null +++ b/src/actions/make/make_project.c @@ -0,0 +1,329 @@ +/** + * \file make_project.c + * \brief Makefile project generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <assert.h> +#include <stdlib.h> +#include "premake.h" +#include "actions/make/make.h" +#include "actions/make/make_project.h" +#include "base/error.h" +#include "base/path.h" + + +/** + * Write the rules to clean up output files on a `make clean`. + */ +int make_project_clean_rules(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + UNUSED(sess); + z |= stream_writeline(strm, "clean:"); + z |= stream_writeline(strm, "\t@echo Cleaning %s", project_get_name(prj)); + z |= stream_writeline(strm, "ifeq (posix, $(SHELLTYPE))"); + z |= stream_writeline(strm, "\t@rm -f $(SYS_OUTFILE)"); + z |= stream_writeline(strm, "\t@rm -rf $(SYS_OBJDIR)"); + z |= stream_writeline(strm, "else"); + z |= stream_writeline(strm, "\t@if exist $(SYS_OUTFILE) del $(SYS_OUTFILE)"); + z |= stream_writeline(strm, "\t@if exist $(SYS_OBJDIR) rmdir /s /q $(SYS_OBJDIR)"); + z |= stream_writeline(strm, "endif"); + z |= stream_writeline(strm, ""); + return OKAY; +} + + +/** + * Write the opening conditional for a configuration block. + */ +int make_project_config_conditional(Session sess, Project prj, Stream strm) +{ + const char* cfg_name = project_get_configuration_filter(prj); + UNUSED(sess); + return stream_writeline(strm, "ifeq ($(CONFIG),%s)", cfg_name); +} + + +/** + * Write the CFLAGS configuration variable. + */ +int make_project_config_cflags(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, " CFLAGS += $(CPPFLAGS) $(ARCHFLAGS)"); +} + + +/** + * Write the CPPFLAGS configuration variable. + */ +int make_project_config_cppflags(Session sess, Project prj, Stream strm) +{ + Strings values; + int z = OKAY; + UNUSED(sess); + + z |= stream_write(strm, " CPPFLAGS += -MMD"); + + values = project_get_config_values(prj, BlockDefines); + z |= stream_write_strings(strm, values, "", " -D \"", "\"", "", "", NULL); + + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write the CXXFLAGS configuration variable. + */ +int make_project_config_cxxflags(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, " CXXFLAGS += $(CFLAGS)"); +} + + +/** + * Write the opening conditional for a configuration block. + */ +int make_project_config_end(Session sess, Project prj, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(prj); + z = stream_writeline(strm, "endif"); + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write the LDDEPS configuration variable. + */ +int make_project_config_lddeps(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, " LDDEPS :="); +} + + +/** + * Write the LDFLAGS configuration variable. + */ +int make_project_config_ldflags(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, " LDFLAGS +="); +} + + +/** + * Write the OBJDIR configuration variable. + */ +int make_project_config_objdir(Session sess, Project prj, Stream strm) +{ + const char* cfg_name = project_get_configuration_filter(prj); + UNUSED(sess); + return stream_writeline(strm, " OBJDIR := obj/%s", cfg_name); +} + + +/** + * Write the OUTDIR configuration variable. + */ +int make_project_config_outdir(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, " OUTDIR := ."); +} + + +/** + * Write the OUTFILE configuration variable. + */ +int make_project_config_outfile(Session sess, Project prj, Stream strm) +{ + const char* outfile = project_get_outfile(prj); + UNUSED(sess); + return stream_writeline(strm, " OUTFILE := $(OUTDIR)/%s", outfile); +} + + +/** + * Write the RESFLAGS configuration variable. + */ +int make_project_config_resflags(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, " RESFLAGS +="); +} + + +/** + * Create a new output stream for a project , and make it active for subsequent writes. + */ +int make_project_create(Session sess, Project prj, Stream strm) +{ + /* create the makefile */ + const char* filename = make_get_project_makefile(sess, prj); + 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; +} + + +/** + * Include the auto-generated dependencies into the project makefile. + */ +int make_project_include_dependencies(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, "-include $(OBJECTS:%%.o=%%.d)"); +} + + +/** + * Write the rules to create the output and object directories. + */ +int make_project_mkdir_rules(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + UNUSED(sess); + UNUSED(prj); + z |= stream_writeline(strm, "$(OUTDIR):"); + z |= stream_writeline(strm, "\t@echo Creating $(OUTDIR)"); + z |= stream_writeline(strm, "\t@$(MKDIR) $(SYS_OUTDIR)"); + z |= stream_writeline(strm, ""); + z |= stream_writeline(strm, "$(OBJDIR):"); + z |= stream_writeline(strm, "\t@echo Creating $(OBJDIR)"); + z |= stream_writeline(strm, "\t@$(MKDIR) $(SYS_OBJDIR)"); + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write the OBJECTS project variable. + */ +int make_project_objects(Session sess, Project prj, Stream strm) +{ + Strings files; + int i, n, z; + UNUSED(sess); + + z = stream_writeline(strm, "OBJECTS := \\"); + + files = project_get_files(prj); + n = strings_size(files); + for (i = 0; i < n; ++i) + { + const char* filename = strings_item(files, i); + if (path_is_cpp_source(filename)) + { + const char* obj_name = make_get_obj_filename(filename); + z |= stream_writeline(strm, "\t%s \\", obj_name); + } + } + + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write the .PHONY rule for a project. + */ +int make_project_phony_rule(Session sess, Project prj, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(prj); + z = stream_writeline(strm, ".PHONY: clean"); + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write the RESOURCES project variable. + */ +int make_project_resources(Session sess, Project prj, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(prj); + z = stream_writeline(strm, "RESOURCES := \\"); + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write the project makefile signature. + */ +int make_project_signature(Session sess, Project prj, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(prj); + z = stream_writeline(strm, "# GNU Makefile autogenerated by Premake"); + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write makefile rules for each source code file. + */ +int make_project_source_rules(Session sess, Project prj, Stream strm) +{ + Strings files; + int i, n, z = OKAY; + UNUSED(sess); + + files = project_get_files(prj); + n = strings_size(files); + for (i = 0; i < n; ++i) + { + const char* filename = strings_item(files, i); + if (path_is_cpp_source(filename)) + { + const char* obj_name = make_get_obj_filename(filename); + z |= stream_writeline(strm, "%s: %s", obj_name, filename); + z |= stream_writeline(strm, "\t@echo $(notdir $<)"); + z |= stream_writeline(strm, "\t@$(CXX) $(CXXFLAGS) -o $@ -c $<"); + z |= stream_writeline(strm, ""); + } + } + + return z; +} + + +/** + * Write the project output target rule. + */ +int make_project_target(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + UNUSED(sess); + z |= stream_writeline(strm, "$(OUTFILE): $(OUTDIR) $(OBJDIR) $(OBJECTS) $(LDDEPS) $(RESOURCES)"); + z |= stream_writeline(strm, "\t@echo Linking %s", project_get_name(prj)); + z |= stream_writeline(strm, "\t@$(CXX) -o $@ $(LDFLAGS) $(ARCHFLAGS) $(OBJECTS) $(RESOURCES)"); + z |= stream_writeline(strm, ""); + return z; +} diff --git a/src/actions/make/make_project.h b/src/actions/make/make_project.h new file mode 100644 index 0000000..e8a3ef8 --- /dev/null +++ b/src/actions/make/make_project.h @@ -0,0 +1,35 @@ +/** + * \file make_project.h + * \brief Makefile project generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_MAKE_PROJECT_H) +#define PREMAKE_MAKE_PROJECT_H + +#include "session/session.h" + +int gmake_project_shell_detect(Session sess, Project prj, Stream strm); + +int make_project_clean_rules(Session sess, Project prj, Stream strm); +int make_project_config_conditional(Session sess, Project prj, Stream strm); +int make_project_config_cflags(Session sess, Project prj, Stream strm); +int make_project_config_cppflags(Session sess, Project prj, Stream strm); +int make_project_config_cxxflags(Session sess, Project prj, Stream strm); +int make_project_config_end(Session sess, Project prj, Stream strm); +int make_project_config_lddeps(Session sess, Project prj, Stream strm); +int make_project_config_ldflags(Session sess, Project prj, Stream strm); +int make_project_config_objdir(Session sess, Project prj, Stream strm); +int make_project_config_outdir(Session sess, Project prj, Stream strm); +int make_project_config_outfile(Session sess, Project prj, Stream strm); +int make_project_config_resflags(Session sess, Project prj, Stream strm); +int make_project_create(Session sess, Project prj, Stream strm); +int make_project_include_dependencies(Session sess, Project prj, Stream strm); +int make_project_mkdir_rules(Session sess, Project prj, Stream strm); +int make_project_objects(Session sess, Project prj, Stream strm); +int make_project_phony_rule(Session sess, Project prj, Stream strm); +int make_project_resources(Session sess, Project prj, Stream strm); +int make_project_signature(Session sess, Project prj, Stream strm); +int make_project_source_rules(Session sess, Project prj, Stream strm); +int make_project_target(Session sess, Project prj, Stream strm); + +#endif diff --git a/src/actions/make/make_solution.c b/src/actions/make/make_solution.c new file mode 100644 index 0000000..2516453 --- /dev/null +++ b/src/actions/make/make_solution.c @@ -0,0 +1,251 @@ +/** + * \file make_solution.c + * \brief Makefile solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include "premake.h" +#include "actions/make/make.h" +#include "actions/make/make_solution.h" +#include "base/buffers.h" +#include "base/cstr.h" +#include "base/error.h" +#include "base/path.h" + + +static const char* make_solution_project_rule(Session sess, Solution sln, Project prj); + + +/** + * Write the GNU solution makefile clean rules. + * \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 make_solution_clean_rule(Session sess, Solution sln, Stream strm) +{ + int i, n, z; + + assert(sess); + assert(sln); + assert(strm); + + z = stream_writeline(strm, "clean:"); + n = solution_num_projects(sln); + for (i = 0; i < n; ++i) + { + Project prj = solution_get_project(sln, i); + const char* rule = make_solution_project_rule(sess, sln, prj); + z |= stream_writeline(strm, "%s clean", rule); + } + + return z; +} + + +/** + * Write the makefile "all" rule. + * \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 make_solution_all_rule(Session sess, Solution sln, Stream strm) +{ + Strings prj_names; + int z; + + UNUSED(sess); + assert(sln); + assert(strm); + + prj_names = make_get_project_names(sln); + z = stream_writeline_strings(strm, prj_names, "all:", " ", "", ""); + z |= stream_writeline(strm, ""); + strings_destroy(prj_names); + 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 make_solution_create(Session sess, Solution sln, Stream strm) +{ + /* create the makefile */ + const char* filename = make_get_solution_makefile(sess, 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 makefile rules to set a default build configuration. + * \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 make_solution_default_config(Session sess, Solution sln, Stream strm) +{ + const char* default_config_name; + int z; + + UNUSED(sess); + assert(sln); + assert(strm); + + default_config_name = solution_get_config(sln, 0); + z = stream_writeline(strm, "ifndef CONFIG"); + z |= stream_writeline(strm, " CONFIG=%s", default_config_name); + z |= stream_writeline(strm, "endif"); + z |= stream_writeline(strm, "export CONFIG"); + z |= stream_writeline(strm, ""); + return z; +} + + +/** + * Write the makefile .PHONY rule. + * \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 make_solution_phony_rule(Session sess, Solution sln, Stream strm) +{ + Strings prj_names; + int z; + + UNUSED(sess); + assert(sln); + assert(strm); + + prj_names = make_get_project_names(sln); + z = stream_writeline_strings(strm, prj_names, ".PHONY: all clean", " ", "", ""); + z |= stream_writeline(strm, ""); + strings_destroy(prj_names); + return z; +} + + + +/** + * Build the makefile rule to call an individual project. + * \param sess The current session context. + * \param sln The solution containing the project. + * \param prj The project to be built. + * \returns The makefile rule to trigger the project build. + */ +const char* make_solution_project_rule(Session sess, Solution sln, Project prj) +{ + char* buffer = buffers_next(); + + /* project file paths are specified relative to the solution */ + const char* sln_path = path_directory(solution_get_filename(sln, NULL, NULL)); + + const char* prj_file = make_get_project_makefile(sess, prj); + const char* prj_file_dir = path_directory(prj_file); + const char* prj_file_name = path_filename(prj_file); + prj_file_dir = path_relative(sln_path, prj_file_dir); + + strcpy(buffer, "\t@$(MAKE)"); + if (!cstr_eq(".", prj_file_dir)) + { + strcat(buffer, " --no-print-directory -C "); + strcat(buffer, prj_file_dir); + } + if (!cstr_eq("Makefile", prj_file_name)) + { + strcat(buffer, " -f "); + strcat(buffer, prj_file_name); + } + + return buffer; +} + + +/** + * Write the solution makefile project entries. + * \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 make_solution_projects(Session sess, Solution sln, Stream strm) +{ + int i, n, z = OKAY; + + assert(sess); + assert(sln); + assert(strm); + + 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* rule = make_solution_project_rule(sess, sln, prj); + + z |= stream_writeline(strm, "%s:", prj_name); + z |= stream_writeline(strm, "\t@echo ==== Building %s ====", prj_name); + z |= stream_writeline(strm, rule); + z |= stream_writeline(strm, ""); + } + + return z; +} + + +/** + * Write the makefile 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 make_solution_signature(Session sess, Solution sln, Stream strm) +{ + const char* file_type; + Strings config_names; + int z; + + assert(sess); + assert(sln); + assert(strm); + + if (cstr_eq(session_get_action(sess), "gmake")) + { + file_type = "GNU Make"; + } + else + { + file_type = "(unknown)"; + assert(0); + } + + z = stream_writeline(strm, "# %s makefile autogenerated by Premake", file_type); + z |= stream_writeline(strm, "# Usage: make [ CONFIG=config_name ]"); + z |= stream_writeline(strm, "# Where {config_name} is one of:"); + + config_names = solution_get_configs(sln); + z |= stream_writeline_strings(strm, config_names, "# ", " ", "", ","); + z |= stream_writeline(strm, ""); + + return z; +} diff --git a/src/actions/make/make_solution.h b/src/actions/make/make_solution.h new file mode 100644 index 0000000..0ff86cd --- /dev/null +++ b/src/actions/make/make_solution.h @@ -0,0 +1,19 @@ +/** + * \file make_solution.h + * \brief Makefile solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_MAKE_SOLUTION_H) +#define PREMAKE_MAKE_SOLUTION_H + +#include "session/session.h" + +int make_solution_clean_rule(Session sess, Solution sln, Stream strm); +int make_solution_all_rule(Session sess, Solution sln, Stream strm); +int make_solution_create(Session sess, Solution sln, Stream strm); +int make_solution_default_config(Session sess, Solution sln, Stream strm); +int make_solution_phony_rule(Session sess, Solution sln, Stream strm); +int make_solution_projects(Session sess, Solution sln, Stream strm); +int make_solution_signature(Session sess, Solution sln, Stream strm); + +#endif diff --git a/src/actions/make/tests/make_config_tests.cpp b/src/actions/make/tests/make_config_tests.cpp new file mode 100644 index 0000000..5c8ae6b --- /dev/null +++ b/src/actions/make/tests/make_config_tests.cpp @@ -0,0 +1,142 @@ +/** + * \file make_config_tests.cpp + * \brief Automated tests for makefile configuration block processing. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "actions/tests/action_tests.h" +extern "C" { +#include "actions/make/make_project.h" +#include "platform/platform.h" +} + +SUITE(action) +{ + /********************************************************************** + * CPPFLAGS tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeCppFlags_Defaults) + { + make_project_config_cppflags(sess, prj, strm); + CHECK_EQUAL( + " CPPFLAGS += -MMD\n", + buffer); + } + + TEST_FIXTURE(FxAction, MakeCppFlags_WithDefines) + { + char* defines[] = { "DEFINE0", "DEFINE1", NULL}; + SetConfigField(prj, BlockDefines, defines); + make_project_config_cppflags(sess, prj, strm); + CHECK_EQUAL( + " CPPFLAGS += -MMD -D \"DEFINE0\" -D \"DEFINE1\"\n", + buffer); + } + + + /********************************************************************** + * CFLAGS tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_Config_CFlags) + { + make_project_config_cflags(sess, prj, strm); + CHECK_EQUAL( + " CFLAGS += $(CPPFLAGS) $(ARCHFLAGS)\n", + buffer); + } + + + /********************************************************************** + * CXXFLAGS tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_Config_CxxFlags) + { + make_project_config_cxxflags(sess, prj, strm); + CHECK_EQUAL( + " CXXFLAGS += $(CFLAGS)\n", + buffer); + } + + + /********************************************************************** + * LDDEPS tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_Config_LdDeps) + { + make_project_config_lddeps(sess, prj, strm); + CHECK_EQUAL( + " LDDEPS :=\n", + buffer); + } + + + /********************************************************************** + * LDFLAGS tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_Config_LdFlags) + { + make_project_config_ldflags(sess, prj, strm); + CHECK_EQUAL( + " LDFLAGS +=\n", + buffer); + } + + + /********************************************************************** + * OBJDIR tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_Config_ObjDir) + { + make_project_config_objdir(sess, prj, strm); + CHECK_EQUAL( + " OBJDIR := obj/Debug\n", + buffer); + } + + + /********************************************************************** + * OUTFILE tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_Config_OutFile) + { + platform_set(MacOSX); + make_project_config_outfile(sess, prj, strm); + CHECK_EQUAL( + " OUTFILE := $(OUTDIR)/MyProject\n", + buffer); + } + + + /********************************************************************** + * OUTDIR tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_Config_OutDir) + { + make_project_config_outdir(sess, prj, strm); + CHECK_EQUAL( + " OUTDIR := .\n", + buffer); + } + + + /********************************************************************** + * RESFLAGS tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_Config_ResFlags) + { + make_project_config_resflags(sess, prj, strm); + CHECK_EQUAL( + " RESFLAGS +=\n", + buffer); + } +} diff --git a/src/actions/make/tests/make_project_tests.cpp b/src/actions/make/tests/make_project_tests.cpp new file mode 100644 index 0000000..2ca0319 --- /dev/null +++ b/src/actions/make/tests/make_project_tests.cpp @@ -0,0 +1,186 @@ +/** + * \file make_project_tests.cpp + * \brief Automated tests for GNU makefile project processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "actions/tests/action_tests.h" +extern "C" { +#include "actions/make/make_project.h" +#include "platform/platform.h" +} + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_SignatureIsCorrect_OnGmake) + { + session_set_action(sess, "gmake"); + make_project_signature(sess, prj, strm); + CHECK_EQUAL( + "# GNU Makefile autogenerated by Premake\n" + "\n", + buffer); + } + + + /********************************************************************** + * Config block conditional tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_Config_Conditional) + { + make_project_config_conditional(sess, prj, strm); + CHECK_EQUAL( + "ifeq ($(CONFIG),Debug)\n", + buffer); + } + + TEST_FIXTURE(FxAction, MakeProject_Config_End) + { + make_project_config_end(sess, prj, strm); + CHECK_EQUAL( + "endif\n" + "\n", + buffer); + } + + + /********************************************************************** + * Object file list tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_Objects_ConvertsFileExtension) + { + char* files[] = { "Hello.cpp", "Goodbye.cpp", NULL }; + SetField(prj, ProjectFiles, files); + make_project_objects(sess, prj, strm); + CHECK_EQUAL( + "OBJECTS := \\\n" + "\t$(OBJDIR)/Hello.o \\\n" + "\t$(OBJDIR)/Goodbye.o \\\n" + "\n", + buffer); + } + + + /********************************************************************** + * Resource file list tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_Resources) + { + make_project_resources(sess, prj, strm); + CHECK_EQUAL( + "RESOURCES := \\\n" + "\n", + buffer); + } + + + /********************************************************************** + * .PHONY rule tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_PhonyRule) + { + make_project_phony_rule(sess, prj, strm); + CHECK_EQUAL( + ".PHONY: clean\n" + "\n", + buffer); + } + + + /********************************************************************** + * Output target tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_OutputTarget) + { + make_project_target(sess, prj, strm); + CHECK_EQUAL( + "$(OUTFILE): $(OUTDIR) $(OBJDIR) $(OBJECTS) $(LDDEPS) $(RESOURCES)\n" + "\t@echo Linking MyProject\n" + "\t@$(CXX) -o $@ $(LDFLAGS) $(ARCHFLAGS) $(OBJECTS) $(RESOURCES)\n" + "\n", + buffer); + } + + + /********************************************************************** + * Directory creation rules + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_MkdirRules) + { + make_project_mkdir_rules(sess, prj, strm); + CHECK_EQUAL( + "$(OUTDIR):\n" + "\t@echo Creating $(OUTDIR)\n" + "\t@$(MKDIR) $(SYS_OUTDIR)\n" + "\n" + "$(OBJDIR):\n" + "\t@echo Creating $(OBJDIR)\n" + "\t@$(MKDIR) $(SYS_OBJDIR)\n" + "\n", + buffer); + } + + + /********************************************************************** + * Clean rules + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_CleanRules) + { + make_project_clean_rules(sess, prj, strm); + CHECK_EQUAL( + "clean:\n" + "\t@echo Cleaning MyProject\n" + "ifeq (posix, $(SHELLTYPE))\n" + "\t@rm -f $(SYS_OUTFILE)\n" + "\t@rm -rf $(SYS_OBJDIR)\n" + "else\n" + "\t@if exist $(SYS_OUTFILE) del $(SYS_OUTFILE)\n" + "\t@if exist $(SYS_OBJDIR) rmdir /s /q $(SYS_OBJDIR)\n" + "endif\n" + "\n", + buffer); + } + + + /********************************************************************** + * Source rule tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_SourceRules) + { + char* files[] = { "Hello.cpp", NULL }; + SetField(prj, ProjectFiles, files); + make_project_source_rules(sess, prj, strm); + CHECK_EQUAL( + "$(OBJDIR)/Hello.o: Hello.cpp\n" + "\t@echo $(notdir $<)\n" + "\t@$(CXX) $(CXXFLAGS) -o $@ -c $<\n" + "\n", + buffer); + } + + + /********************************************************************** + * File dependency generation tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeProject_IncludeDependencies) + { + make_project_include_dependencies(sess, prj, strm); + CHECK_EQUAL( + "-include $(OBJECTS:%.o=%.d)\n", + buffer); + } +} diff --git a/src/actions/make/tests/make_solution_tests.cpp b/src/actions/make/tests/make_solution_tests.cpp new file mode 100644 index 0000000..896a8e5 --- /dev/null +++ b/src/actions/make/tests/make_solution_tests.cpp @@ -0,0 +1,122 @@ +/** + * \file make_solution_tests.cpp + * \brief Automated tests for makefile "solution" processing. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "actions/tests/action_tests.h" +extern "C" { +#include "actions/make/make_solution.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeSolution_SignatureIsCorrect_OnGmake) + { + session_set_action(sess, "gmake"); + make_solution_signature(sess, sln, strm); + CHECK_EQUAL( + "# GNU Make makefile autogenerated by Premake\n" + "# Usage: make [ CONFIG=config_name ]\n" + "# Where {config_name} is one of:\n" + "# Debug, Release\n" + "\n", + buffer); + } + + + /********************************************************************** + * Default configuration tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeSolution_DefaultConfigIsCorrect) + { + make_solution_default_config(sess, sln, strm); + CHECK_EQUAL( + "ifndef CONFIG\n" + " CONFIG=Debug\n" + "endif\n" + "export CONFIG\n" + "\n", + buffer); + } + + + /********************************************************************** + * Phony rule tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeSolution_PhonyRuleIsCorrect) + { + make_solution_phony_rule(sess, sln, strm); + CHECK_EQUAL( + ".PHONY: all clean MyProject\n" + "\n", + buffer); + } + + + /********************************************************************** + * All rule tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, MakeSolution_AllRuleIsCorrect) + { + make_solution_all_rule(sess, sln, strm); + CHECK_EQUAL( + "all: MyProject\n" + "\n", + buffer); + } + + + /********************************************************************** + * Project entry tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Make_ProjectEntry_InSameDirectory) + { + project_set_location(prj, ""); + make_solution_projects(sess, sln, strm); + CHECK_EQUAL( + "MyProject:\n" + "\t@echo ==== Building MyProject ====\n" + "\t@$(MAKE) -f MyProject.make\n" + "\n", + buffer); + } + + TEST_FIXTURE(FxAction, Make_ProjectEntry_InDifferentDirectory) + { + project_set_location(prj, "MyProject"); + make_solution_projects(sess, sln, strm); + CHECK_EQUAL( + "MyProject:\n" + "\t@echo ==== Building MyProject ====\n" + "\t@$(MAKE) --no-print-directory -C MyProject\n" + "\n", + buffer); + } + + + /********************************************************************** + * Clean rule tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Gmake_CleanRule_IsCorrect) + { + project_set_location(prj, ""); + make_solution_clean_rule(sess, sln, strm); + CHECK_EQUAL( + "clean:\n" + "\t@$(MAKE) -f MyProject.make clean\n", + buffer); + } + +} diff --git a/src/actions/make/tests/make_tests.cpp b/src/actions/make/tests/make_tests.cpp new file mode 100644 index 0000000..db4fe87 --- /dev/null +++ b/src/actions/make/tests/make_tests.cpp @@ -0,0 +1,98 @@ +/** + * \file make_tests.cpp + * \brief Automated tests for the makefile generator support functions. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "testing/testing.h" +extern "C" { +#include "actions/make/make.h" +#include "base/error.h" +} + + +struct FxMake +{ + Session sess; + Solution sln1; + Solution sln2; + Project prj1; + Project prj2; + + FxMake() + { + sess = session_create(); + sln1 = AddSolution("MySolution1"); + sln2 = AddSolution("MySolution2"); + prj1 = AddProject("MyProject1"); + prj2 = AddProject("MyProject2"); + } + + ~FxMake() + { + session_destroy(sess); + error_clear(); + } + + Solution AddSolution(const char* name) + { + Solution sln = solution_create(); + session_add_solution(sess, sln); + solution_set_name(sln, name); + solution_set_base_dir(sln, "."); + return sln; + } + + Project AddProject(const char* name) + { + Project prj = project_create(); + solution_add_project(sln1, prj); + project_set_name(prj, name); + project_set_base_dir(prj, "."); + return prj; + } +}; + + +SUITE(action) +{ + /********************************************************************** + * Makefile naming tests + **********************************************************************/ + + TEST_FIXTURE(FxMake, GetSolutionMakefile_ReturnsMakefile_OnUniqueLocation) + { + solution_set_location(sln1, "MySolution"); + const char* result = make_get_solution_makefile(sess, sln1); + CHECK_EQUAL("./MySolution/Makefile", result); + } + + TEST_FIXTURE(FxMake, GetSolutionMakefile_ReturnsDotMake_OnSharedLocation) + { + const char* result = make_get_solution_makefile(sess, sln1); + CHECK_EQUAL("./MySolution1.make", result); + } + + TEST_FIXTURE(FxMake, GetProjectMakefile_ReturnsMakefile_OnUniqueLocation) + { + project_set_location(prj1, "MyProject"); + const char* result = make_get_project_makefile(sess, prj1); + CHECK_EQUAL("./MyProject/Makefile", result); + } + + TEST_FIXTURE(FxMake, GetProjectMakefile_ReturnsDotMake_OnSharedWithSolution) + { + project_set_location(prj2, "MyProject"); + const char* result = make_get_project_makefile(sess, prj1); + CHECK_EQUAL("./MyProject1.make", result); + } + + TEST_FIXTURE(FxMake, GetProjectMakefile_ReturnsDotMake_OnSharedWithProject) + { + project_set_location(prj1, "MyProject"); + project_set_location(prj2, "MyProject"); + const char* result = make_get_project_makefile(sess, prj1); + CHECK_EQUAL("./MyProject/MyProject1.make", result); + } +} diff --git a/src/actions/support/sourcetree.c b/src/actions/support/sourcetree.c new file mode 100644 index 0000000..7659dcf --- /dev/null +++ b/src/actions/support/sourcetree.c @@ -0,0 +1,108 @@ +/** + * \file sourcetree.h + * \brief Source code tree enumerator. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <string.h> +#include "premake.h" +#include "sourcetree.h" +#include "base/buffers.h" +#include "base/cstr.h" +#include "base/string.h" + + +static int sourcetree_do(Session sess, Project prj, Stream strm, SourceTreeCallback handler, const char* group); + + +/** + * Walk a list of source files and pass them off, in nesting order, to + * the specified callback. Handles the grouping of related files info + * groups (by directory currently). + * \param sess The current execution session context. + * \param prj The project containing the files to enumerate. + * \param strm The active output stream. + * \param handler The per-file handler function. + * \returns OKAY on success. + */ +int sourcetree_walk(Session sess, Project prj, Stream strm, SourceTreeCallback handler) +{ + return sourcetree_do(sess, prj, strm, handler, ""); +} + + +static int sourcetree_do(Session sess, Project prj, Stream strm, SourceTreeCallback handler, const char* group) +{ + int i, n; + unsigned group_len; + Strings files; + char* buffer; + + group_len = strlen(group); + + /* open an enclosing group */ + buffer = buffers_next(); + strcpy(buffer, group); + cstr_trim(buffer, '/'); + handler(sess, prj, strm, buffer, GroupStart); + + /* scan all files in this group and process any subdirectories (subgroups) */ + files = project_get_files(prj); + n = strings_size(files); + for (i = 0; i < n; ++i) + { + const char* filename = strings_item(files, i); + + /* is this file in the group that I am currently processing? */ + if (cstr_starts_with(filename, group)) + { + /* see if this file contains an additional directory level (a new group) */ + const char* ptr = strchr(filename + group_len, '/'); + if (ptr) + { + int j; + + /* pull out the name of this new group */ + size_t len = ptr - filename + 1; + buffer = buffers_next(); + strncpy(buffer, filename, len); + buffer[len] = '\0'; + + /* have I processed this subdirectory already? See if it appears earlier in the list */ + for (j = 0; j < i; ++j) + { + if (cstr_starts_with(strings_item(files, j), buffer)) + break; + } + + if (i == j) + { + /* a new group, process it now */ + String new_group = string_create(buffer); + int z = sourcetree_do(sess, prj, strm, handler, string_cstr(new_group)); + string_destroy(new_group); + if (z != OKAY) return !OKAY; + } + } + } + } + + /* now process all files that belong to this current group (and not a subgroup) */ + for (i = 0; i < n; ++i) + { + const char* filename = strings_item(files, i); + if (cstr_starts_with(filename, group) && strchr(filename + group_len, '/') == NULL) + { + if (handler(sess, prj, strm, filename, SourceFile) != OKAY) + return !OKAY; + } + } + + /* close the group */ + buffer = buffers_next(); + strcpy(buffer, group); + cstr_trim(buffer, '/'); + handler(sess, prj, strm, buffer, GroupEnd); + return OKAY; +} + diff --git a/src/actions/support/sourcetree.h b/src/actions/support/sourcetree.h new file mode 100644 index 0000000..f39224f --- /dev/null +++ b/src/actions/support/sourcetree.h @@ -0,0 +1,38 @@ +/** + * \file sourcetree.h + * \brief Source code tree enumerator. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_SOURCETREE_H) +#define PREMAKE_SOURCETREE_H + +#include "session/session.h" + + +/** + * State values for the source tree enumeration functions. + */ +enum SourceTreeState +{ + GroupStart, + GroupEnd, + SourceFile +}; + + +/** + * Per-file callback signature for action_source_tree. + * \param sess The current execution state context. + * \param prj The current project; contains the file being enumerated. + * \param strm The active output stream; for writing the file markup. + * \param filename The name of the file to process. + * \param state One of the ActionSourceStates, enabling file grouping. + * \returns OKAY if successful. + */ +typedef int (*SourceTreeCallback)(Session sess, Project prj, Stream strm, const char* filename, int state); + + +int sourcetree_walk(Session sess, Project prj, Stream strm, SourceTreeCallback handler); + + +#endif diff --git a/src/actions/tests/action_tests.h b/src/actions/tests/action_tests.h new file mode 100644 index 0000000..71c53b8 --- /dev/null +++ b/src/actions/tests/action_tests.h @@ -0,0 +1,83 @@ +/** + * \file action_tests.h + * \brief Common test fixtures for all action tests. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "testing/testing.h" +extern "C" { +#include "session/session.h" +#include "project/project.h" +} + +struct FxAction +{ + Session sess; + Stream strm; + Solution sln; + Filter flt; + Project prj; + char buffer[8192]; + + FxAction() + { + sess = session_create(); + + strm = stream_create_null(); + stream_set_buffer(strm, buffer); + session_set_active_stream(sess, strm); + + sln = solution_create(); + session_add_solution(sess, sln); + solution_set_name(sln, "MySolution"); + solution_set_base_dir(sln, "/Root"); + solution_add_config(sln, "Debug"); + solution_add_config(sln, "Release"); + + prj = project_create(); + solution_add_project(sln, prj); + 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"); + project_set_language(prj, "c++"); + + flt = filter_create(); + filter_set_value(flt, FilterConfig, "Debug"); + project_set_filter(prj, flt); + } + + ~FxAction() + { + stream_destroy(strm); + session_destroy(sess); + filter_destroy(flt); + } + + + void SetField(Project prj, enum ProjectField index, char** values) + { + Strings strs = strings_create(); + for (char** value = values; (*value) != NULL; ++value) + { + strings_add(strs, *value); + } + + project_set_values(prj, index, strs); + } + + void SetConfigField(Project prj, enum BlockField index, char** values) + { + Strings strs = strings_create(); + for (char** value = values; (*value) != NULL; ++value) + { + strings_add(strs, *value); + } + + Block blk = block_create(); + block_set_values(blk, index, strs); + + Blocks blks = project_get_blocks(prj); + blocks_add(blks, blk); + } +}; diff --git a/src/actions/vs200x/tests/vs2002_solution_tests.cpp b/src/actions/vs200x/tests/vs2002_solution_tests.cpp new file mode 100644 index 0000000..1605ef9 --- /dev/null +++ b/src/actions/vs200x/tests/vs2002_solution_tests.cpp @@ -0,0 +1,108 @@ +/** + * \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 "actions/tests/action_tests.h" +extern "C" { +#include "actions/vs200x/vs200x_solution.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2002_Signature_IsCorrect) + { + 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(FxAction, 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(FxAction, 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(FxAction, Vs2002_ProjectDependencies_IsCorrect) + { + vs2002_solution_dependencies(sess, sln, strm); + CHECK_EQUAL( + "\tGlobalSection(ProjectDependencies) = postSolution\n" + "\tEndGlobalSection\n", + buffer); + } + + + /********************************************************************** + * Project configuration tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, 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(FxAction, 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/actions/vs200x/tests/vs2003_solution_tests.cpp b/src/actions/vs200x/tests/vs2003_solution_tests.cpp new file mode 100644 index 0000000..8ee8614 --- /dev/null +++ b/src/actions/vs200x/tests/vs2003_solution_tests.cpp @@ -0,0 +1,45 @@ +/** + * \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 "actions/tests/action_tests.h" +extern "C" { +#include "actions/vs200x/vs200x_solution.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2003_Signature_IsCorrect) + { + 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(FxAction, 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/actions/vs200x/tests/vs2005_solution_tests.cpp b/src/actions/vs200x/tests/vs2005_solution_tests.cpp new file mode 100644 index 0000000..e50edcb --- /dev/null +++ b/src/actions/vs200x/tests/vs2005_solution_tests.cpp @@ -0,0 +1,80 @@ +/** + * \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 "actions/tests/action_tests.h" +extern "C" { +#include "actions/vs200x/vs200x_solution.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2005_Signature_IsCorrect) + { + 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(FxAction, 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(FxAction, 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(FxAction, 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/actions/vs200x/tests/vs2008_solution_tests.cpp b/src/actions/vs200x/tests/vs2008_solution_tests.cpp new file mode 100644 index 0000000..7495b97 --- /dev/null +++ b/src/actions/vs200x/tests/vs2008_solution_tests.cpp @@ -0,0 +1,30 @@ +/** + * \file vs2008_solution_tests.cpp + * \brief Automated tests for VS2008 solution processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "actions/tests/action_tests.h" +extern "C" { +#include "actions/vs200x/vs200x_solution.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Signature tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs2008_Signature_IsCorrect) + { + vs2008_solution_signature(sess, sln, strm); + CHECK_EQUAL( + "\357\273\277\r\n" + "Microsoft Visual Studio Solution File, Format Version 10.00\r\n" + "# Visual Studio 2008\r\n", + buffer); + } + +} diff --git a/src/actions/vs200x/tests/vs200x_compiler_tests.cpp b/src/actions/vs200x/tests/vs200x_compiler_tests.cpp new file mode 100644 index 0000000..167ad30 --- /dev/null +++ b/src/actions/vs200x/tests/vs200x_compiler_tests.cpp @@ -0,0 +1,102 @@ +/** + * \file vs200x_compiler_tests.cpp + * \brief Automated tests for VS200x compiler block processing. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "actions/tests/action_tests.h" +extern "C" { +#include "actions/vs200x/vs200x_project.h" +} + +SUITE(action) +{ + /********************************************************************** + * Default settings + **********************************************************************/ + + TEST_FIXTURE(FxAction, VCCLCompilerTool_Defaults_OnVs2002) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_cl_compiler_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCCLCompilerTool\"\n" + "\t\t\t\tOptimization=\"0\"\n" + "\t\t\t\tMinimalRebuild=\"TRUE\"\n" + "\t\t\t\tBasicRuntimeChecks=\"3\"\n" + "\t\t\t\tRuntimeLibrary=\"3\"\n" + "\t\t\t\tRuntimeTypeInfo=\"TRUE\"\n" + "\t\t\t\tUsePrecompiledHeader=\"2\"\n" + "\t\t\t\tWarningLevel=\"3\"\n" + "\t\t\t\tDetect64BitPortabilityProblems=\"TRUE\"\n" + "\t\t\t\tDebugInformationFormat=\"4\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, VCCLCompilerTool_Defaults_OnVs2005) + { + session_set_action(sess, "vs2005"); + vs200x_project_vc_cl_compiler_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCCLCompilerTool\"\n" + "\t\t\t\tOptimization=\"0\"\n" + "\t\t\t\tMinimalRebuild=\"true\"\n" + "\t\t\t\tBasicRuntimeChecks=\"3\"\n" + "\t\t\t\tRuntimeLibrary=\"3\"\n" + "\t\t\t\tUsePrecompiledHeader=\"0\"\n" + "\t\t\t\tWarningLevel=\"3\"\n" + "\t\t\t\tDetect64BitPortabilityProblems=\"true\"\n" + "\t\t\t\tDebugInformationFormat=\"4\"\n" + "\t\t\t/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, VCCLCompilerTool_Defaults_OnVs2008) + { + session_set_action(sess, "vs2008"); + vs200x_project_vc_cl_compiler_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCCLCompilerTool\"\n" + "\t\t\t\tOptimization=\"0\"\n" + "\t\t\t\tMinimalRebuild=\"true\"\n" + "\t\t\t\tBasicRuntimeChecks=\"3\"\n" + "\t\t\t\tRuntimeLibrary=\"3\"\n" + "\t\t\t\tUsePrecompiledHeader=\"0\"\n" + "\t\t\t\tWarningLevel=\"3\"\n" + "\t\t\t\tDebugInformationFormat=\"4\"\n" + "\t\t\t/>\n", + buffer); + } + + + + /********************************************************************** + * Defines tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, VCCLCompilerTool_WithDefines) + { + session_set_action(sess, "vs2002"); + char* defines[] = { "DEFINE0", "DEFINE1", NULL }; + SetConfigField(prj, BlockDefines, defines); + vs200x_project_vc_cl_compiler_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCCLCompilerTool\"\n" + "\t\t\t\tOptimization=\"0\"\n" + "\t\t\t\tPreprocessorDefinitions=\"DEFINE0;DEFINE1\"\n" + "\t\t\t\tMinimalRebuild=\"TRUE\"\n" + "\t\t\t\tBasicRuntimeChecks=\"3\"\n" + "\t\t\t\tRuntimeLibrary=\"3\"\n" + "\t\t\t\tRuntimeTypeInfo=\"TRUE\"\n" + "\t\t\t\tUsePrecompiledHeader=\"2\"\n" + "\t\t\t\tWarningLevel=\"3\"\n" + "\t\t\t\tDetect64BitPortabilityProblems=\"TRUE\"\n" + "\t\t\t\tDebugInformationFormat=\"4\"/>\n", + buffer); + } +} diff --git a/src/actions/vs200x/tests/vs200x_config_tests.cpp b/src/actions/vs200x/tests/vs200x_config_tests.cpp new file mode 100644 index 0000000..7a8fbe9 --- /dev/null +++ b/src/actions/vs200x/tests/vs200x_config_tests.cpp @@ -0,0 +1,67 @@ +/** + * \file vs200x_config_tests.cpp + * \brief Automated tests for VS200x configuration settings processing. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "actions/tests/action_tests.h" +extern "C" { +#include "actions/vs200x/vs200x_config.h" +} + +SUITE(action) +{ + /************************************************************************* + * Character set tests + *************************************************************************/ + + TEST_FIXTURE(FxAction, VsCharacterSet_Defaults_OnVs2002) + { + session_set_action(sess, "vs2002"); + vs200x_config_character_set(sess, strm); + CHECK_EQUAL("\n\t\t\tCharacterSet=\"2\"", buffer); + } + + TEST_FIXTURE(FxAction, VsCharacterSet_Defaults_OnVs2003) + { + session_set_action(sess, "vs2003"); + vs200x_config_character_set(sess, strm); + CHECK_EQUAL("\n\t\t\tCharacterSet=\"2\"", buffer); + } + + TEST_FIXTURE(FxAction, VsCharacterSet_Defaults_OnVs2005) + { + session_set_action(sess, "vs2005"); + vs200x_config_character_set(sess, strm); + CHECK_EQUAL("\n\t\t\tCharacterSet=\"1\"", buffer); + } + + TEST_FIXTURE(FxAction, VsCharacterSet_Defaults_OnVs2008) + { + session_set_action(sess, "vs2008"); + vs200x_config_character_set(sess, strm); + CHECK_EQUAL("\n\t\t\tCharacterSet=\"1\"", buffer); + } + + + /************************************************************************* + * Defines tests + *************************************************************************/ + + TEST_FIXTURE(FxAction, VsDefines_Empty_OnNoSymbols) + { + session_set_action(sess, "vs2002"); + vs200x_config_defines(sess, strm, prj); + CHECK_EQUAL("", buffer); + } + + TEST_FIXTURE(FxAction, VsDefines_SemiSplitList) + { + session_set_action(sess, "vs2002"); + char* values[] = { "DEFINE0", "DEFINE1", "DEFINE2", NULL }; + SetConfigField(prj, BlockDefines, values); + vs200x_config_defines(sess, strm, prj); + CHECK_EQUAL("\n\t\t\t\tPreprocessorDefinitions=\"DEFINE0;DEFINE1;DEFINE2\"", buffer); + } +} diff --git a/src/actions/vs200x/tests/vs200x_linker_tests.cpp b/src/actions/vs200x/tests/vs200x_linker_tests.cpp new file mode 100644 index 0000000..10b8e01 --- /dev/null +++ b/src/actions/vs200x/tests/vs200x_linker_tests.cpp @@ -0,0 +1,80 @@ +/** + * \file vs200x_linker_tests.cpp + * \brief Automated tests for VS200x linker block processing. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "actions/tests/action_tests.h" +extern "C" { +#include "actions/vs200x/vs200x_project.h" +} + +SUITE(action) +{ + /********************************************************************** + * Default settings + **********************************************************************/ + + TEST_FIXTURE(FxAction, VCLinkerTool_Defaults_OnVs2002) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_linker_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCLinkerTool\"\n" + "\t\t\t\tLinkIncremental=\"2\"\n" + "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n" + "\t\t\t\tSubSystem=\"1\"\n" + "\t\t\t\tEntryPointSymbol=\"mainCRTStartup\"\n" + "\t\t\t\tTargetMachine=\"1\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, VCLinkerTool_Defaults_OnVs2003) + { + session_set_action(sess, "vs2003"); + vs200x_project_vc_linker_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCLinkerTool\"\n" + "\t\t\t\tLinkIncremental=\"2\"\n" + "\t\t\t\tGenerateDebugInformation=\"TRUE\"\n" + "\t\t\t\tSubSystem=\"1\"\n" + "\t\t\t\tEntryPointSymbol=\"mainCRTStartup\"\n" + "\t\t\t\tTargetMachine=\"1\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, VCLinkerTool_Defaults_OnVs2005) + { + session_set_action(sess, "vs2005"); + vs200x_project_vc_linker_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCLinkerTool\"\n" + "\t\t\t\tLinkIncremental=\"2\"\n" + "\t\t\t\tGenerateDebugInformation=\"true\"\n" + "\t\t\t\tSubSystem=\"1\"\n" + "\t\t\t\tEntryPointSymbol=\"mainCRTStartup\"\n" + "\t\t\t\tTargetMachine=\"1\"\n" + "\t\t\t/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, VCLinkerTool_Defaults_OnVs2008) + { + session_set_action(sess, "vs2008"); + vs200x_project_vc_linker_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCLinkerTool\"\n" + "\t\t\t\tLinkIncremental=\"2\"\n" + "\t\t\t\tGenerateDebugInformation=\"true\"\n" + "\t\t\t\tSubSystem=\"1\"\n" + "\t\t\t\tEntryPointSymbol=\"mainCRTStartup\"\n" + "\t\t\t\tTargetMachine=\"1\"\n" + "\t\t\t/>\n", + buffer); + } +} diff --git a/src/actions/vs200x/tests/vs200x_project_tests.cpp b/src/actions/vs200x/tests/vs200x_project_tests.cpp new file mode 100644 index 0000000..ff14eb9 --- /dev/null +++ b/src/actions/vs200x/tests/vs200x_project_tests.cpp @@ -0,0 +1,467 @@ +/** + * \file vs200x_project_tests.cpp + * \brief Automated tests for Visual Studio project processing. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "actions/tests/action_tests.h" +extern "C" { +#include "actions/vs200x/vs200x_project.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Encoding tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs200x_Encoding) + { + vs200x_project_encoding(sess, prj, strm); + CHECK_EQUAL( + "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n", + buffer); + } + + + /********************************************************************** + * Project element tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, VsProject_OnVs2002) + { + session_set_action(sess, "vs2002"); + vs200x_project_element(sess, prj, strm); + CHECK_EQUAL( + "<VisualStudioProject\n" + "\tProjectType=\"Visual C++\"\n" + "\tVersion=\"7.00\"\n" + "\tName=\"MyProject\"\n" + "\tProjectGUID=\"{AE2461B7-236F-4278-81D3-F0D476F9A4C0}\"\n" + "\tKeyword=\"Win32Proj\">\n", + buffer); + } + + TEST_FIXTURE(FxAction, VsProject_OnVs2003) + { + session_set_action(sess, "vs2003"); + vs200x_project_element(sess, prj, strm); + CHECK_EQUAL( + "<VisualStudioProject\n" + "\tProjectType=\"Visual C++\"\n" + "\tVersion=\"7.10\"\n" + "\tName=\"MyProject\"\n" + "\tProjectGUID=\"{AE2461B7-236F-4278-81D3-F0D476F9A4C0}\"\n" + "\tKeyword=\"Win32Proj\">\n", + buffer); + } + + TEST_FIXTURE(FxAction, VsProject_OnVs2005) + { + session_set_action(sess, "vs2005"); + vs200x_project_element(sess, prj, strm); + CHECK_EQUAL( + "<VisualStudioProject\n" + "\tProjectType=\"Visual C++\"\n" + "\tVersion=\"8.00\"\n" + "\tName=\"MyProject\"\n" + "\tProjectGUID=\"{AE2461B7-236F-4278-81D3-F0D476F9A4C0}\"\n" + "\tRootNamespace=\"MyProject\"\n" + "\tKeyword=\"Win32Proj\"\n" + "\t>\n", + buffer); + } + + TEST_FIXTURE(FxAction, VsProject_OnVs2008) + { + session_set_action(sess, "vs2008"); + vs200x_project_element(sess, prj, strm); + CHECK_EQUAL( + "<VisualStudioProject\n" + "\tProjectType=\"Visual C++\"\n" + "\tVersion=\"9.00\"\n" + "\tName=\"MyProject\"\n" + "\tProjectGUID=\"{AE2461B7-236F-4278-81D3-F0D476F9A4C0}\"\n" + "\tRootNamespace=\"MyProject\"\n" + "\tKeyword=\"Win32Proj\"\n" + "\tTargetFrameworkVersion=\"196613\"\n" + "\t>\n", + buffer); + } + + + /********************************************************************** + * Platforms tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs200x_Platforms) + { + session_set_action(sess, "vs2002"); + vs200x_project_platforms(sess, prj, strm); + CHECK_EQUAL( + "\t<Platforms>\n" + "\t\t<Platform\n" + "\t\t\tName=\"Win32\"/>\n" + "\t</Platforms>\n", + buffer); + } + + + /********************************************************************** + * Tool files tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, VsToolFiles_Defaults_OnVs2002) + { + session_set_action(sess, "vs2002"); + vs200x_project_tool_files(sess, prj, strm); + CHECK_EQUAL( + "\t<Configurations>\n", + buffer); + } + + TEST_FIXTURE(FxAction, VsToolFiles_Defaults_OnVs2003) + { + session_set_action(sess, "vs2003"); + vs200x_project_tool_files(sess, prj, strm); + CHECK_EQUAL( + "\t<Configurations>\n", + buffer); + } + + TEST_FIXTURE(FxAction, VsToolFiles_Defaults_OnVs2005) + { + session_set_action(sess, "vs2005"); + vs200x_project_tool_files(sess, prj, strm); + CHECK_EQUAL( + "\t<ToolFiles>\n" + "\t</ToolFiles>\n" + "\t<Configurations>\n", + buffer); + } + + TEST_FIXTURE(FxAction, VsToolFiles_Defaults_OnVs2008) + { + session_set_action(sess, "vs2008"); + vs200x_project_tool_files(sess, prj, strm); + CHECK_EQUAL( + "\t<ToolFiles>\n" + "\t</ToolFiles>\n" + "\t<Configurations>\n", + buffer); + } + + + + /********************************************************************** + * Configuration element tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs200x_Configuration) + { + session_set_action(sess, "vs2002"); + vs200x_project_config_element(sess, prj, strm); + CHECK_EQUAL( + "\t\t<Configuration\n" + "\t\t\tName=\"Debug|Win32\"\n" + "\t\t\tOutputDirectory=\"$(SolutionDir)$(ConfigurationName)\"\n" + "\t\t\tIntermediateDirectory=\"$(ConfigurationName)\"\n" + "\t\t\tConfigurationType=\"1\"\n" + "\t\t\tCharacterSet=\"2\">\n", + buffer); + } + + + /********************************************************************** + * Tool element tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs200x_VCALinkTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_alink_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCALinkTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCAppVerifierTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_app_verifier_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCAppVerifierTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCBscMakeTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_bsc_make_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCBscMakeTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCCustomBuildTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_custom_build_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCCustomBuildTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCFxCopTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_fx_cop_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCFxCopTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCManagedResourceCompilerTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_managed_resource_compiler_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCManagedResourceCompilerTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCManifestTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_manifest_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCManifestTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCMIDLTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_midl_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCMIDLTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCPreBuildEventTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_pre_build_event_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCPreBuildEventTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCPreLinkEventTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_pre_link_event_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCPreLinkEventTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCPostBuildEventTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_post_build_event_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCPostBuildEventTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCResourceCompilerTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_resource_compiler_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCResourceCompilerTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCWebDeploymentTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_web_deployment_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCWebDeploymentTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCWebServiceProxyGeneratorTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_web_service_proxy_generator_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCXDCMakeTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_xdc_make_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCXDCMakeTool\"/>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_VCXMLDataGeneratorTool) + { + session_set_action(sess, "vs2002"); + vs200x_project_vc_xml_data_generator_tool(sess, prj, strm); + CHECK_EQUAL( + "\t\t\t<Tool\n" + "\t\t\t\tName=\"VCXMLDataGeneratorTool\"/>\n", + buffer); + } + + + /********************************************************************** + * References section tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, VsReferences_Defaults_OnVs2002) + { + session_set_action(sess, "vs2002"); + vs200x_project_references(sess, prj, strm); + CHECK_EQUAL( + "\t</Configurations>\n", + buffer); + } + + TEST_FIXTURE(FxAction, VsReferences_Defaults_OnVs2003) + { + session_set_action(sess, "vs2003"); + vs200x_project_references(sess, prj, strm); + CHECK_EQUAL( + "\t</Configurations>\n" + "\t<References>\n" + "\t</References>\n", + buffer); + } + + TEST_FIXTURE(FxAction, VsReferences_Defaults_OnVs2005) + { + session_set_action(sess, "vs2005"); + vs200x_project_references(sess, prj, strm); + CHECK_EQUAL( + "\t</Configurations>\n" + "\t<References>\n" + "\t</References>\n", + buffer); + } + + TEST_FIXTURE(FxAction, VsReferences_Defaults_OnVs2008) + { + session_set_action(sess, "vs2008"); + vs200x_project_references(sess, prj, strm); + CHECK_EQUAL( + "\t</Configurations>\n" + "\t<References>\n" + "\t</References>\n", + buffer); + } + + + /********************************************************************** + * Files section tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs200x_Files_OnNoFiles) + { + session_set_action(sess, "vs2002"); + vs200x_project_files(sess, prj, strm); + CHECK_EQUAL( + "\t<Files>\n" + "\t</Files>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_Files_OnSingleCppFile) + { + session_set_action(sess, "vs2002"); + char* values[] = { "Hello.cpp", 0 }; + SetField(prj, ProjectFiles, values); + vs200x_project_files(sess, prj, strm); + CHECK_EQUAL( + "\t<Files>\n" + "\t\t<File\n" + "\t\t\tRelativePath=\".\\Hello.cpp\">\n" + "\t\t</File>\n" + "\t</Files>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_Files_OnUpperDirectory) + { + session_set_action(sess, "vs2002"); + char* values[] = { "../../Hello.cpp", 0 }; + SetField(prj, ProjectFiles, values); + vs200x_project_files(sess, prj, strm); + CHECK_EQUAL( + "\t<Files>\n" + "\t\t<File\n" + "\t\t\tRelativePath=\"..\\..\\Hello.cpp\">\n" + "\t\t</File>\n" + "\t</Files>\n", + buffer); + } + + TEST_FIXTURE(FxAction, Vs200x_Files_OnGroupedCppFile) + { + session_set_action(sess, "vs2002"); + char* values[] = { "Src/Hello.cpp", 0 }; + SetField(prj, ProjectFiles, values); + vs200x_project_files(sess, prj, strm); + CHECK_EQUAL( + "\t<Files>\n" + "\t\t<Filter\n" + "\t\t\tName=\"Src\"\n" + "\t\t\tFilter=\"\">\n" + "\t\t\t<File\n" + "\t\t\t\tRelativePath=\".\\Src\\Hello.cpp\">\n" + "\t\t\t</File>\n" + "\t\t</Filter>\n" + "\t</Files>\n", + buffer); + } + + + /********************************************************************** + * Globals section tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Vs200x_Globals) + { + session_set_action(sess, "vs2002"); + vs200x_project_globals(sess, prj, strm); + CHECK_EQUAL( + "\t<Globals>\n" + "\t</Globals>\n" + "</VisualStudioProject>\n", + buffer); + } +} diff --git a/src/actions/vs200x/tests/vs200x_tests.cpp b/src/actions/vs200x/tests/vs200x_tests.cpp new file mode 100644 index 0000000..a41a071 --- /dev/null +++ b/src/actions/vs200x/tests/vs200x_tests.cpp @@ -0,0 +1,56 @@ +/** + * \file vs200x_tests.cpp + * \brief Automated tests for VS200x support functions. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "actions/tests/action_tests.h" +extern "C" { +#include "actions/vs200x/vs200x.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Language GUID tests + **********************************************************************/ + + TEST(ToolGuid_ReturnsCorrectGUID_OnC) + { + const char* result = vs200x_tool_guid("c"); + CHECK_EQUAL("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942", result); + } + + TEST(ToolGuid_ReturnsCorrectGUID_OnCpp) + { + const char* result = vs200x_tool_guid("c++"); + CHECK_EQUAL("8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942", result); + } + + TEST(ToolGuid_ReturnsCorrectGUID_OnCSharp) + { + const char* result = vs200x_tool_guid("c#"); + CHECK_EQUAL("FAE04EC0-301F-11D3-BF4B-00C04F79EFBC", result); + } + + + /********************************************************************** + * Language file extensions + **********************************************************************/ + + TEST_FIXTURE(FxAction, ProjectExtension_IsVcproj_ForC) + { + project_set_language(prj, "c"); + const char* result = vs200x_project_file_extension(prj); + CHECK_EQUAL(".vcproj", result); + } + + TEST_FIXTURE(FxAction, ProjectExtension_IsVcproj_ForCpp) + { + project_set_language(prj, "c++"); + const char* result = vs200x_project_file_extension(prj); + CHECK_EQUAL(".vcproj", result); + } +} diff --git a/src/actions/vs200x/tests/vs200x_xml_tests.cpp b/src/actions/vs200x/tests/vs200x_xml_tests.cpp new file mode 100644 index 0000000..9616b99 --- /dev/null +++ b/src/actions/vs200x/tests/vs200x_xml_tests.cpp @@ -0,0 +1,120 @@ +/** + * \file vs200x_xml_tests.cpp + * \brief Automated tests for Visual Studio XML output functions. + * \author Copyright (c) 2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "actions/tests/action_tests.h" +extern "C" { +#include "actions/vs200x/vs200x.h" +} + + +SUITE(action) +{ + /********************************************************************** + * Element end tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2002) + { + session_set_action(sess, "vs2002"); + vs200x_element_end(sess, strm, 0, "/>"); + CHECK_EQUAL("/>\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2003) + { + session_set_action(sess, "vs2003"); + vs200x_element_end(sess, strm, 0, "/>"); + CHECK_EQUAL("/>\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2005) + { + session_set_action(sess, "vs2005"); + vs200x_element_end(sess, strm, 0, "/>"); + CHECK_EQUAL("\n/>\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2008) + { + session_set_action(sess, "vs2008"); + vs200x_element_end(sess, strm, 0, "/>"); + CHECK_EQUAL("\n/>\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2002) + { + session_set_action(sess, "vs2002"); + vs200x_element_end(sess, strm, 0, ">"); + CHECK_EQUAL(">\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2003) + { + session_set_action(sess, "vs2003"); + vs200x_element_end(sess, strm, 0, ">"); + CHECK_EQUAL(">\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2005) + { + session_set_action(sess, "vs2005"); + vs200x_element_end(sess, strm, 0, ">"); + CHECK_EQUAL("\n\t>\n", buffer); + } + + TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2008) + { + session_set_action(sess, "vs2008"); + vs200x_element_end(sess, strm, 0, ">"); + CHECK_EQUAL("\n\t>\n", buffer); + } + + + /********************************************************************** + * Attribute tests + **********************************************************************/ + + TEST_FIXTURE(FxAction, Attribute_OnLevel0) + { + session_set_action(sess, "vs2002"); + vs200x_attribute(strm, 0, "ProjectType", "Visual C++"); + CHECK_EQUAL("\nProjectType=\"Visual C++\"", buffer); + } + + TEST_FIXTURE(FxAction, Attribute_OnLevel3) + { + session_set_action(sess, "vs2002"); + vs200x_attribute(strm, 3, "ProjectType", "Visual C++"); + CHECK_EQUAL("\n\t\t\tProjectType=\"Visual C++\"", buffer); + } + + TEST_FIXTURE(FxAction, Attribute_IsEscaped) + { + session_set_action(sess, "vs2002"); + vs200x_attribute(strm, 1, "PreprocessorSymbols", "DEBUG;MSG=\"Hello\";TRACE"); + CHECK_EQUAL("\n\tPreprocessorSymbols=\"DEBUG;MSG="Hello";TRACE\"", buffer); + } + + TEST_FIXTURE(FxAction, AttributeList_OnLevel0) + { + const char* values[] = { "VALUE0", "VALUE1", "VALUE2", NULL }; + Strings strs = strings_create_from_array(values); + vs200x_list_attribute(strm, 0, "Values", strs); + CHECK_EQUAL("\nValues=\"VALUE0;VALUE1;VALUE2\"", buffer); + strings_destroy(strs); + } + + TEST_FIXTURE(FxAction, AttributeList_IsEscaped) + { + const char* values[] = { "VALUE0", "VALUE1=\"Hello\"", "VALUE2", NULL }; + Strings strs = strings_create_from_array(values); + vs200x_list_attribute(strm, 0, "Values", strs); + CHECK_EQUAL("\nValues=\"VALUE0;VALUE1="Hello";VALUE2\"", buffer); + strings_destroy(strs); + } + +} diff --git a/src/actions/vs200x/vs2002.c b/src/actions/vs200x/vs2002.c new file mode 100644 index 0000000..8abc23b --- /dev/null +++ b/src/actions/vs200x/vs2002.c @@ -0,0 +1,85 @@ +/** + * \file vs2002.c + * \brief Visual Studio 2002 project file generation action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <stdlib.h> +#include "premake.h" +#include "actions/actions.h" +#include "vs200x.h" +#include "vs200x_solution.h" +#include "vs200x_project.h" + + +/** The project features supported by this action */ +static SessionFeatures Features = +{ + { "c", "c++", NULL }, +}; + + +/** The VS2002 solution writing process, for session_enumerate_objects() */ +static SessionSolutionCallback SolutionCallbacks[] = +{ + vs200x_solution_create, + vs2002_solution_signature, + vs2002_solution_projects, + vs2002_solution_configuration, + vs2002_solution_dependencies, + vs2002_solution_project_configuration, + vs2002_solution_extensibility, + NULL +}; + +/** The VS2002 project writing process, for session_enumerate_objects() */ +static SessionProjectCallback ProjectCallbacks[] = +{ + vs200x_project_create, + vs200x_project_encoding, + vs200x_project_element, + vs200x_project_platforms, + vs200x_project_tool_files, + session_enumerate_configurations, + vs200x_project_references, + vs200x_project_files, + vs200x_project_globals, + NULL +}; + +/** The VS2002 configuration writing process, for session_enumerate_configurations() */ +static SessionProjectCallback ConfigCallbacks[] = +{ + vs200x_project_config_element, + vs200x_project_vc_cl_compiler_tool, + vs200x_project_vc_custom_build_tool, + vs200x_project_vc_linker_tool, + vs200x_project_vc_midl_tool, + vs200x_project_vc_post_build_event_tool, + vs200x_project_vc_pre_build_event_tool, + vs200x_project_vc_pre_link_event_tool, + vs200x_project_vc_resource_compiler_tool, + vs200x_project_vc_web_service_proxy_generator_tool, + vs200x_project_vc_web_deployment_tool, + vs200x_project_config_end, + NULL +}; + + +/** + * The Visual Studio 2002 action handler. + * \param sess The active session object. + * \returns OKAY if successful. + */ +int vs2002_action(Session sess) +{ + /* make sure I can support all of the features used in the session */ + if (session_validate(sess, &Features) != OKAY) + { + return !OKAY; + } + + stream_writeline(Console, "Generating project files for Visual Studio 2002..."); + return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); +} + diff --git a/src/actions/vs200x/vs2002_solution.c b/src/actions/vs200x/vs2002_solution.c new file mode 100644 index 0000000..7274eb7 --- /dev/null +++ b/src/actions/vs200x/vs2002_solution.c @@ -0,0 +1,169 @@ +/** + * \file vs2002_solution.c + * \brief Visual Studio 2002 solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <assert.h> +#include <stdlib.h> +#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(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; +} + + +/** + * 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(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, z = OKAY; + + 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_file_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, "\\"); + + z |= stream_writeline(strm, "Project(\"{%s}\") = \"%s\", \"%s\", \"{%s}\"", tool_id, prj_name, prj_file, prj_id); + z |= stream_writeline(strm, "EndProject"); + } + + return z; +} + + +/** + * 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/actions/vs200x/vs2003.c b/src/actions/vs200x/vs2003.c new file mode 100644 index 0000000..db83666 --- /dev/null +++ b/src/actions/vs200x/vs2003.c @@ -0,0 +1,84 @@ +/** + * \file vs2003.c + * \brief Visual Studio 2003 project file generation action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <stdlib.h> +#include "premake.h" +#include "actions/actions.h" +#include "vs200x.h" +#include "vs200x_solution.h" +#include "vs200x_project.h" + + +/** The project features supported by this action */ +static SessionFeatures Features = +{ + { "c", "c++", NULL }, +}; + + +/** The VS2003 solution writing process, for session_enumerate_objects() */ +static SessionSolutionCallback SolutionCallbacks[] = +{ + vs200x_solution_create, + vs2003_solution_signature, + vs2002_solution_projects, + vs2003_solution_configuration, + vs2002_solution_project_configuration, + vs2002_solution_extensibility, + NULL +}; + +/** The VS2003 project writing process, for session_enumerate_objects() */ +static SessionProjectCallback ProjectCallbacks[] = +{ + vs200x_project_create, + vs200x_project_encoding, + vs200x_project_element, + vs200x_project_platforms, + vs200x_project_tool_files, + session_enumerate_configurations, + vs200x_project_references, + vs200x_project_files, + vs200x_project_globals, + NULL +}; + +/** The VS2003 configuration writing process, for session_enumerate_configurations() */ +static SessionProjectCallback ConfigCallbacks[] = +{ + vs200x_project_config_element, + vs200x_project_vc_cl_compiler_tool, + vs200x_project_vc_custom_build_tool, + vs200x_project_vc_linker_tool, + vs200x_project_vc_midl_tool, + vs200x_project_vc_post_build_event_tool, + vs200x_project_vc_pre_build_event_tool, + vs200x_project_vc_pre_link_event_tool, + vs200x_project_vc_resource_compiler_tool, + vs200x_project_vc_web_service_proxy_generator_tool, + vs200x_project_vc_xml_data_generator_tool, + vs200x_project_vc_web_deployment_tool, + vs200x_project_config_end, + NULL +}; + + +/** + * The Visual Studio 2003 action handler. + * \param sess The active session object. + * \returns OKAY if successful. + */ +int vs2003_action(Session sess) +{ + /* make sure I can support all of the features used in the session */ + if (session_validate(sess, &Features) != OKAY) + { + return !OKAY; + } + + stream_writeline(Console, "Generating project files for Visual Studio 2003..."); + return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); +} diff --git a/src/actions/vs200x/vs2003_solution.c b/src/actions/vs200x/vs2003_solution.c new file mode 100644 index 0000000..1c1517c --- /dev/null +++ b/src/actions/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 <assert.h> +#include <stdlib.h> +#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(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/actions/vs200x/vs2005.c b/src/actions/vs200x/vs2005.c new file mode 100644 index 0000000..47e835c --- /dev/null +++ b/src/actions/vs200x/vs2005.c @@ -0,0 +1,92 @@ +/** + * \file vs2005.c + * \brief Visual Studio 2005 project file generation action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <stdlib.h> +#include "premake.h" +#include "actions/actions.h" +#include "vs200x.h" +#include "vs200x_solution.h" +#include "vs200x_project.h" + + +/** The project features supported by this action */ +static SessionFeatures Features = +{ + { "c", "c++", NULL }, +}; + + +/** The VS2005 solution writing process, for session_enumerate_objects() */ +static SessionSolutionCallback SolutionCallbacks[] = +{ + vs200x_solution_create, + vs2005_solution_signature, + vs2002_solution_projects, + vs2005_solution_platforms, + vs2005_solution_project_platforms, + vs2005_solution_properties, + NULL +}; + +/** The VS2005 project writing process, for session_enumerate_objects() */ +static SessionProjectCallback ProjectCallbacks[] = +{ + vs200x_project_create, + vs200x_project_encoding, + vs200x_project_element, + vs200x_project_platforms, + vs200x_project_tool_files, + session_enumerate_configurations, + vs200x_project_references, + vs200x_project_files, + vs200x_project_globals, + NULL +}; + +/** The VS2005 configuration writing process, for session_enumerate_configurations() */ +static SessionProjectCallback ConfigCallbacks[] = +{ + vs200x_project_config_element, + vs200x_project_vc_pre_build_event_tool, + vs200x_project_vc_custom_build_tool, + vs200x_project_vc_xml_data_generator_tool, + vs200x_project_vc_web_service_proxy_generator_tool, + vs200x_project_vc_midl_tool, + vs200x_project_vc_cl_compiler_tool, + vs200x_project_vc_managed_resource_compiler_tool, + vs200x_project_vc_resource_compiler_tool, + vs200x_project_vc_pre_link_event_tool, + vs200x_project_vc_linker_tool, + vs200x_project_vc_alink_tool, + vs200x_project_vc_manifest_tool, + vs200x_project_vc_xdc_make_tool, + vs200x_project_vc_bsc_make_tool, + vs200x_project_vc_fx_cop_tool, + vs200x_project_vc_app_verifier_tool, + vs200x_project_vc_web_deployment_tool, + vs200x_project_vc_post_build_event_tool, + vs200x_project_config_end, + NULL +}; + + +/** + * The Visual Studio 2005 action handler. + * \param sess The active session object. + * \returns OKAY if successful. + */ +int vs2005_action(Session sess) +{ + /* make sure I can support all of the features used in the session */ + if (session_validate(sess, &Features) != OKAY) + { + return !OKAY; + } + + stream_writeline(Console, "Generating project files for Visual Studio 2005..."); + return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); +} + diff --git a/src/actions/vs200x/vs2005_solution.c b/src/actions/vs200x/vs2005_solution.c new file mode 100644 index 0000000..6f589ea --- /dev/null +++ b/src/actions/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 <assert.h> +#include <stdlib.h> +#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(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(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/actions/vs200x/vs2008.c b/src/actions/vs200x/vs2008.c new file mode 100644 index 0000000..9af42ad --- /dev/null +++ b/src/actions/vs200x/vs2008.c @@ -0,0 +1,91 @@ +/** + * \file vs2008.c + * \brief Visual Studio 2008 project file generation action. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <stdlib.h> +#include "premake.h" +#include "actions/actions.h" +#include "vs200x.h" +#include "vs200x_solution.h" +#include "vs200x_project.h" + + +/** The project features supported by this action */ +static SessionFeatures Features = +{ + { "c", "c++", NULL }, +}; + + +/** The VS2008 solution writing process, for session_enumerate_objects() */ +static SessionSolutionCallback SolutionCallbacks[] = +{ + vs200x_solution_create, + vs2008_solution_signature, + vs2002_solution_projects, + vs2005_solution_platforms, + vs2005_solution_project_platforms, + vs2005_solution_properties, + NULL +}; + +/** The VS2008 project writing process, for session_enumerate_objects() */ +static SessionProjectCallback ProjectCallbacks[] = +{ + vs200x_project_create, + vs200x_project_encoding, + vs200x_project_element, + vs200x_project_platforms, + vs200x_project_tool_files, + session_enumerate_configurations, + vs200x_project_references, + vs200x_project_files, + vs200x_project_globals, + NULL +}; + +/** The VS2008 configuration writing process, for session_enumerate_configurations() */ +static SessionProjectCallback ConfigCallbacks[] = +{ + vs200x_project_config_element, + vs200x_project_vc_pre_build_event_tool, + vs200x_project_vc_custom_build_tool, + vs200x_project_vc_xml_data_generator_tool, + vs200x_project_vc_web_service_proxy_generator_tool, + vs200x_project_vc_midl_tool, + vs200x_project_vc_cl_compiler_tool, + vs200x_project_vc_managed_resource_compiler_tool, + vs200x_project_vc_resource_compiler_tool, + vs200x_project_vc_pre_link_event_tool, + vs200x_project_vc_linker_tool, + vs200x_project_vc_alink_tool, + vs200x_project_vc_manifest_tool, + vs200x_project_vc_xdc_make_tool, + vs200x_project_vc_bsc_make_tool, + vs200x_project_vc_fx_cop_tool, + vs200x_project_vc_app_verifier_tool, + vs200x_project_vc_post_build_event_tool, + vs200x_project_config_end, + NULL +}; + + +/** + * The Visual Studio 2008 action handler. + * \param sess The active session object. + * \returns OKAY if successful. + */ +int vs2008_action(Session sess) +{ + /* make sure I can support all of the features used in the session */ + if (session_validate(sess, &Features) != OKAY) + { + return !OKAY; + } + + stream_writeline(Console, "Generating project files for Visual Studio 2008..."); + return session_enumerate_objects(sess, SolutionCallbacks, ProjectCallbacks, ConfigCallbacks); +} + diff --git a/src/actions/vs200x/vs2008_solution.c b/src/actions/vs200x/vs2008_solution.c new file mode 100644 index 0000000..856bd51 --- /dev/null +++ b/src/actions/vs200x/vs2008_solution.c @@ -0,0 +1,29 @@ +/** + * \file vs2008_solution.c + * \brief Visual Studio 2008 solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "vs200x_solution.h" + + +/** + * Write the Visual Studio 2008 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 vs2008_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 10.00"); + z |= stream_writeline(strm, "# Visual Studio 2008"); + return z; +} diff --git a/src/actions/vs200x/vs200x.c b/src/actions/vs200x/vs200x.c new file mode 100644 index 0000000..91b4cfb --- /dev/null +++ b/src/actions/vs200x/vs200x.c @@ -0,0 +1,190 @@ +/** + * \file vs200x.c + * \brief General purpose Visual Studio support functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include "premake.h" +#include "vs200x.h" +#include "base/buffers.h" +#include "base/cstr.h" +#include "base/error.h" + + +/** + * Write an XML attribute, adjusting for the differing Visual Studio formats. + * \param strm The output stream, the attribute will be written here. + * \param indent_size How far to indent (with tabs) the attribute. + * \param name The attribute name. + * \param value The attribute value; may contain printf-style formatting codes. + * \returns OKAY if successful. + */ +int vs200x_attribute(Stream strm, int indent_size, const char* name, const char* value, ...) +{ + va_list args; + char* buffer; + int z = OKAY; + + z |= stream_writeline(strm, ""); + z |= stream_write_n(strm, "\t", indent_size); + z |= stream_write(strm, "%s=\"", name); + + buffer = buffers_next(); + va_start(args, value); + vsprintf(buffer, value, args); + z |= stream_write_escaped(strm, buffer); + va_end(args); + + z |= stream_write(strm, "\""); + return z; +} + + +/** + * Write an XML attribute containing a list of values, adjusting for the differing Visual Studio formats. + * \param strm The output stream, the attribute will be written here. + * \param indent_size How far to indent (with tabs) the attribute. + * \param name The attribute name. + * \param values The attribute list value. + * \returns OKAY if successful. + */ +int vs200x_list_attribute(Stream strm, int indent_size, const char* name, Strings values) +{ + int z = OKAY; + + z |= stream_writeline(strm, ""); + z |= stream_write_n(strm, "\t", indent_size); + z |= stream_write(strm, "%s=", name); + z |= stream_write_strings(strm, values, "\"", "", "", ";", "\"", stream_write_escaped); + return z; +} + + +/** + * Write the ending part of an XML tag, adjust for the differing Visual Studio formats. + * \param sess The current execution session. + * \param strm The output stream. + * \param level The XML element nesting level. + * \param markup The end tag markup. + * \returns OKAY if successful. + */ +int vs200x_element_end(Session sess, Stream strm, int level, const char* markup) +{ + int z; + int version = vs200x_get_target_version(sess); + if (version >= 2005) + { + z = stream_writeline(strm, ""); + if (markup[0] == '>') + { + level++; + } + z |= stream_write_n(strm, "\t", level); + z |= stream_writeline(strm, "%s", markup); + } + else + { + z = stream_writeline(strm, markup); + } + return z; +} + + +/** + * Return the Visual Studio version appropriate version of the string for a false + * value. Before 2005 this was "FALSE", after it is "false". + */ +const char* vs200x_false(Session sess) +{ + int version = vs200x_get_target_version(sess); + return (version < 2005) ? "FALSE" : "false"; +} + + +/** + * Converts the session action string to a Visual Studio version number. + * \param sess The current execution session. + * \returns The Visual Studio version number corresponding to the current action. + */ +int vs200x_get_target_version(Session sess) +{ + const char* action = session_get_action(sess); + if (cstr_eq(action, "vs2002")) + { + return 2002; + } + else if (cstr_eq(action, "vs2003")) + { + return 2003; + } + else if (cstr_eq(action, "vs2005")) + { + return 2005; + } + else if (cstr_eq(action, "vs2008")) + { + return 2008; + } + else + { + assert(0); + return 0; + } +} + + +/** + * Return the appropriate file extension for a particular project. + * \param prj The project object. + * \returns The appropriate project file extension, based on the project settings. + */ +const char* vs200x_project_file_extension(Project prj) +{ + const char* language = project_get_language(prj); + if (cstr_eq(language, "c") || cstr_eq(language, "c++")) + { + return ".vcproj"; + } + else + { + error_set("unsupported language '%s'", language); + return NULL; + } +} + + +/** + * 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; + } +} + + +/** + * Return the Visual Studio version appropriate version of the string for a true + * value. Before 2005 this was "TRUE", after it is "true". + */ +const char* vs200x_true(Session sess) +{ + int version = vs200x_get_target_version(sess); + return (version < 2005) ? "TRUE" : "true"; +} diff --git a/src/actions/vs200x/vs200x.h b/src/actions/vs200x/vs200x.h new file mode 100644 index 0000000..b99c2f5 --- /dev/null +++ b/src/actions/vs200x/vs200x.h @@ -0,0 +1,21 @@ +/** + * \file vs200x.h + * \brief General purpose Visual Studio support functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_VS200X_H) +#define PREMAKE_VS200X_H + +#include "session/session.h" + +int vs200x_attribute(Stream strm, int indent_size, const char* name, const char* value, ...); +int vs200x_list_attribute(Stream strm, int indent_size, const char* name, Strings values); +int vs200x_element_end(Session sess, Stream strm, int level, const char* markup); +const char* vs200x_false(Session sess); +int vs200x_get_target_version(Session sess); +const char* vs200x_project_file_extension(Project prj); +const char* vs200x_tool_guid(const char* language); +const char* vs200x_true(Session sess); + +#endif + diff --git a/src/actions/vs200x/vs200x_config.c b/src/actions/vs200x/vs200x_config.c new file mode 100644 index 0000000..3e94305 --- /dev/null +++ b/src/actions/vs200x/vs200x_config.c @@ -0,0 +1,64 @@ +/** + * \file vs200x_config.c + * \brief Visual Studio 200x configuration generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include "premake.h" +#include "vs200x.h" +#include "vs200x_config.h" + + +int vs200x_config_character_set(Session sess, Stream strm) +{ + int version = vs200x_get_target_version(sess); + return vs200x_attribute(strm, 3, "CharacterSet", version > 2003 ? "1" : "2"); +} + + +/** + * Write out the list of preprocessor symbols as defined by the configuration. + * This entry is only written if there are values to write. + */ +int vs200x_config_defines(Session sess, Stream strm, Project prj) +{ + Strings values = project_get_config_values(prj, BlockDefines); + UNUSED(sess); + if (strings_size(values) > 0) + { + return vs200x_list_attribute(strm, 4, "PreprocessorDefinitions", values); + } + return OKAY; +} + + +int vs200x_config_detect_64bit_portability(Session sess, Stream strm, Project prj) +{ + int version = vs200x_get_target_version(sess); + UNUSED(prj); + if (version < 2008) + { + return vs200x_attribute(strm, 4, "Detect64BitPortabilityProblems", vs200x_true(sess)); + } + return OKAY; +} + + +int vs200x_config_runtime_type_info(Session sess, Stream strm, Project prj) +{ + int version = vs200x_get_target_version(sess); + UNUSED(prj); + if (version < 2005) + { + return vs200x_attribute(strm, 4, "RuntimeTypeInfo", vs200x_true(sess)); + } + return OKAY; +} + + +int vs200x_config_use_precompiled_header(Session sess, Stream strm, Project prj) +{ + int version = vs200x_get_target_version(sess); + UNUSED(prj); + return vs200x_attribute(strm, 4, "UsePrecompiledHeader", (version > 2003) ? "0" : "2"); +} diff --git a/src/actions/vs200x/vs200x_config.h b/src/actions/vs200x/vs200x_config.h new file mode 100644 index 0000000..53172e9 --- /dev/null +++ b/src/actions/vs200x/vs200x_config.h @@ -0,0 +1,17 @@ +/** + * \file vs200x_config.h + * \brief Visual Studio 200x configuration generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_VS200X_CONFIG_H) +#define PREMAKE_VS200X_CONFIG_H + +#include "session/session.h" + +int vs200x_config_character_set(Session sess, Stream strm); +int vs200x_config_defines(Session sess, Stream strm, Project prj); +int vs200x_config_detect_64bit_portability(Session sess, Stream strm, Project prj); +int vs200x_config_runtime_type_info(Session sess, Stream strm, Project prj); +int vs200x_config_use_precompiled_header(Session sess, Stream strm, Project prj); + +#endif diff --git a/src/actions/vs200x/vs200x_project.c b/src/actions/vs200x/vs200x_project.c new file mode 100644 index 0000000..0c48255 --- /dev/null +++ b/src/actions/vs200x/vs200x_project.c @@ -0,0 +1,475 @@ +/** + * \file vs200x_project.c + * \brief Visual Studio multiple-version project generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <stdlib.h> +#include <string.h> +#include "premake.h" +#include "vs200x.h" +#include "vs200x_project.h" +#include "vs200x_config.h" +#include "actions/support/sourcetree.h" +#include "base/cstr.h" +#include "base/path.h" + + +/** + * Write the opening [Configuration] element and attributes. + */ +int vs200x_project_config_element(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + const char* cfg_name = project_get_configuration_filter(prj); + z |= stream_write(strm, "\t\t<Configuration"); + z |= vs200x_attribute(strm, 3, "Name", "%s|Win32", cfg_name); + z |= vs200x_attribute(strm, 3, "OutputDirectory", "$(SolutionDir)$(ConfigurationName)"); + z |= vs200x_attribute(strm, 3, "IntermediateDirectory", "$(ConfigurationName)"); + z |= vs200x_attribute(strm, 3, "ConfigurationType", "1"); + z |= vs200x_config_character_set(sess, strm); + z |= vs200x_element_end(sess, strm, 2, ">"); + return z; +} + + +/** + * Write the closing [Configuration] element. + */ +int vs200x_project_config_end(Session sess, Project prj, Stream strm) +{ + UNUSED(sess); + UNUSED(prj); + return stream_writeline(strm, "\t\t</Configuration>"); +} + + +/** + * Create a new output stream for a project, and make it active for subsequent writes. + */ +int vs200x_project_create(Session sess, Project prj, Stream strm) +{ + /* create the project file */ + const char* extension = vs200x_project_file_extension(prj); + const char* filename = project_get_filename(prj, NULL, extension); + 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 the root [VisualStudioProject] element and attributes. + */ +int vs200x_project_element(Session sess, Project prj, Stream strm) +{ + int version, z; + const char* prj_ver; + const char* prj_name = project_get_name(prj); + const char* prj_guid = project_get_guid(prj); + + version = vs200x_get_target_version(sess); + switch (version) + { + default: + prj_ver = "7.00"; break; + case 2003: + prj_ver = "7.10"; break; + case 2005: + prj_ver = "8.00"; break; + case 2008: + prj_ver = "9.00"; break; + } + + z = stream_write(strm, "<VisualStudioProject"); + z |= vs200x_attribute(strm, 1, "ProjectType", "Visual C++"); + z |= vs200x_attribute(strm, 1, "Version", prj_ver); + z |= vs200x_attribute(strm, 1, "Name", prj_name); + z |= vs200x_attribute(strm, 1, "ProjectGUID", "{%s}", prj_guid); + if (version > 2003) + { + z |= vs200x_attribute(strm, 1, "RootNamespace", prj_name); + } + z |= vs200x_attribute(strm, 1, "Keyword", "Win32Proj"); + if (version > 2005) + { + z |= vs200x_attribute(strm, 1, "TargetFrameworkVersion", "196613"); + } + z |= vs200x_element_end(sess, strm, 0, ">"); + return z; +} + + +/** + * Write the file encoding at the start of the project file. + */ +int vs200x_project_encoding(Session sess, Project prj, Stream strm) +{ + int z; + UNUSED(sess); + UNUSED(prj); + + stream_set_newline(strm, "\r\n"); + z = stream_writeline(strm, "<?xml version=\"1.0\" encoding=\"Windows-1252\"?>"); + return z; +} + + +/** + * Write an individual file entry to the project file; callback for sourcetree_walk(). + * \param sess The current execution session context. + * \param prj The current project; contains the file being enumerated. + * \param strm The active output stream; for writing the file markup. + * \param filename The name of the file to process. + * \param state One of the ActionSourceStates, enabling file grouping. + * \returns OKAY if successful. + */ +int vs200x_project_file(Session sess, Project prj, Stream strm, const char* filename, int state) +{ + const char* name; + const char* ptr; + int depth, z = OKAY; + + /* figure out the grouping depth, skipping over any leading dot directories */ + depth = 2; + + ptr = filename; + while (cstr_starts_with(ptr, "../")) + { + ptr += 3; + } + + ptr = strchr(ptr, '/'); + while (ptr != NULL) + { + depth++; + ptr = strchr(ptr + 1, '/'); + } + + /* group name is just the last bit of the path */ + name = path_filename(filename); + + /* use the Windows path separator */ + filename = path_translate(filename, "\\"); + + switch (state) + { + case GroupStart: + if (strlen(filename) > 0 && !cstr_eq(name, "..")) + { + z |= stream_write_n(strm, "\t", depth); + z |= stream_write(strm, "<Filter"); + z |= vs200x_attribute(strm, depth + 1, "Name", name); + z |= vs200x_attribute(strm, depth + 1, "Filter", ""); + z |= vs200x_element_end(sess, strm, depth, ">"); + } + break; + + case GroupEnd: + if (strlen(filename) > 0 && !cstr_eq(name, "..")) + { + z |= stream_write_n(strm, "\t", depth); + z |= stream_writeline(strm, "</Filter>"); + } + break; + + case SourceFile: + z |= stream_write_n(strm, "\t", depth); + z |= stream_write(strm, "<File"); + ptr = (filename[0] == '.') ? "" : ".\\"; + z |= vs200x_attribute(strm, depth + 1, "RelativePath", "%s%s", ptr, filename); + z |= vs200x_element_end(sess, strm, depth, ">"); + z |= stream_write_n(strm, "\t", depth); + z |= stream_writeline(strm, "</File>"); + break; + } + + UNUSED(prj); + return z; +} + + +/** + * Write out the [Files] element. + */ +int vs200x_project_files(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + z |= stream_writeline(strm, "\t<Files>"); + z |= sourcetree_walk(sess, prj, strm, vs200x_project_file); + z |= stream_writeline(strm, "\t</Files>"); + return z; +} + + +/** + * Write out the [Globals] element. + */ +int vs200x_project_globals(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + UNUSED(sess); + UNUSED(prj); + z |= stream_writeline(strm, "\t<Globals>"); + z |= stream_writeline(strm, "\t</Globals>"); + z |= stream_writeline(strm, "</VisualStudioProject>"); + return z; +} + + +/** + * Write out the platforms section of a project file. + */ +int vs200x_project_platforms(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + UNUSED(prj); + z |= stream_writeline(strm, "\t<Platforms>"); + z |= stream_write(strm, "\t\t<Platform"); + z |= vs200x_attribute(strm, 3, "Name", "Win32"); + z |= vs200x_element_end(sess, strm, 2, "/>"); + z |= stream_writeline(strm, "\t</Platforms>"); + return OKAY; +} + + +/** + * Write out the [References] element and attributes. + */ +int vs200x_project_references(Session sess, Project prj, Stream strm) +{ + int z; + UNUSED(prj); + z = stream_writeline(strm, "\t</Configurations>"); + if (vs200x_get_target_version(sess) > 2002) + { + z |= stream_writeline(strm, "\t<References>"); + z |= stream_writeline(strm, "\t</References>"); + } + return z; +} + + +/** + * Write out the [ToolFiles] section of a Visual Studio project. + */ +int vs200x_project_tool_files(Session sess, Project prj, Stream strm) +{ + int version, z = OKAY; + UNUSED(prj); + + version = vs200x_get_target_version(sess); + if (version > 2003) + { + z |= stream_writeline(strm, "\t<ToolFiles>"); + z |= stream_writeline(strm, "\t</ToolFiles>"); + } + z |= stream_writeline(strm, "\t<Configurations>"); + return z; +} + + +/** + * Common function to write an empty [Tool] element. + */ +static int vs200x_project_vc_empty_tool(Session sess, Project prj, Stream strm, const char* name) +{ + int z; + UNUSED(prj); + z = stream_write(strm, "\t\t\t<Tool"); + z |= vs200x_attribute(strm, 4, "Name", name); + z |= vs200x_element_end(sess, strm, 3, "/>"); + return z; +} + + +/** + * Write the VCALinkTool [Tool] element and attributes. + */ +int vs200x_project_vc_alink_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCALinkTool"); +} + + +/** + * Write the VCAppVerifierTool [Tool] element and attributes. + */ +int vs200x_project_vc_app_verifier_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCAppVerifierTool"); +} + + +/** + * Write the VCBscMakeTool [Tool] element and attributes. + */ +int vs200x_project_vc_bsc_make_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCBscMakeTool"); +} + + +/** + * Write the VCCLCompilerTool [Tool] element and attributes. + */ +int vs200x_project_vc_cl_compiler_tool(Session sess, Project prj, Stream strm) +{ + int z = OKAY; + z |= stream_write(strm, "\t\t\t<Tool"); + z |= vs200x_attribute(strm, 4, "Name", "VCCLCompilerTool"); + z |= vs200x_attribute(strm, 4, "Optimization", "0"); + z |= vs200x_config_defines(sess, strm, prj); + z |= vs200x_attribute(strm, 4, "MinimalRebuild", vs200x_true(sess)); + z |= vs200x_attribute(strm, 4, "BasicRuntimeChecks", "3"); + z |= vs200x_attribute(strm, 4, "RuntimeLibrary", "3"); + z |= vs200x_config_runtime_type_info(sess, strm, prj); + z |= vs200x_config_use_precompiled_header(sess, strm, prj); + z |= vs200x_attribute(strm, 4, "WarningLevel", "3"); + z |= vs200x_config_detect_64bit_portability(sess, strm, prj); + z |= vs200x_attribute(strm, 4, "DebugInformationFormat", "4"); + z |= vs200x_element_end(sess, strm, 3, "/>"); + return z; +} + + +/** + * Write the VCCustomBuildTool [Tool] element and attributes. + */ +int vs200x_project_vc_custom_build_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCCustomBuildTool"); +} + + +/** + * Write the VCFxCopTool [Tool] element and attributes. + */ +int vs200x_project_vc_fx_cop_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCFxCopTool"); +} + + +/** + * Write the VCLinkerTool [Tool] element and attributes. + */ +int vs200x_project_vc_linker_tool(Session sess, Project prj, Stream strm) +{ + int z; + UNUSED(prj); + z = stream_write(strm, "\t\t\t<Tool"); + z |= vs200x_attribute(strm, 4, "Name", "VCLinkerTool"); + z |= vs200x_attribute(strm, 4, "LinkIncremental", "2"); + z |= vs200x_attribute(strm, 4, "GenerateDebugInformation", vs200x_true(sess)); + z |= vs200x_attribute(strm, 4, "SubSystem", "1"); + z |= vs200x_attribute(strm, 4, "EntryPointSymbol", "mainCRTStartup"); + z |= vs200x_attribute(strm, 4, "TargetMachine", "1"); + z |= vs200x_element_end(sess, strm, 3, "/>"); + return z; +} + + +/** + * Write the VCManagedResourceCompilerTool [Tool] element and attributes. + */ +int vs200x_project_vc_managed_resource_compiler_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCManagedResourceCompilerTool"); +} + + +/** + * Write the VCManifestTool [Tool] element and attributes. + */ +int vs200x_project_vc_manifest_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCManifestTool"); +} + + +/** + * Write the VCMIDLTool [Tool] element and attributes. + */ +int vs200x_project_vc_midl_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCMIDLTool"); +} + + +/** + * Write the VCPreBuildEventTool [Tool] element and attributes. + */ +int vs200x_project_vc_pre_build_event_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCPreBuildEventTool"); +} + + +/** + * Write the VCPreLinkEventTool [Tool] element and attributes. + */ +int vs200x_project_vc_pre_link_event_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCPreLinkEventTool"); +} + + +/** + * Write the VCPostBuildEventTool [Tool] element and attributes. + */ +int vs200x_project_vc_post_build_event_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCPostBuildEventTool"); +} + + +/** + * Write the VCResourceCompiler [Tool] element and attributes. + */ +int vs200x_project_vc_resource_compiler_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCResourceCompilerTool"); +} + + +/** + * Write the VCWebDeploymentTool [Tool] element and attributes. + */ +int vs200x_project_vc_web_deployment_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCWebDeploymentTool"); +} + + +/** + * Write the VCWebServiceProxyGeneratorTool [Tool] element and attributes. + */ +int vs200x_project_vc_web_service_proxy_generator_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCWebServiceProxyGeneratorTool"); +} + + +/** + * Write the VCXDCMakeTool [Tool] element and attributes. + */ +int vs200x_project_vc_xdc_make_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCXDCMakeTool"); +} + + +/** + * Write the VCXMLDataGeneratorTool [Tool] element and attributes. + */ +int vs200x_project_vc_xml_data_generator_tool(Session sess, Project prj, Stream strm) +{ + return vs200x_project_vc_empty_tool(sess, prj, strm, "VCXMLDataGeneratorTool"); +} diff --git a/src/actions/vs200x/vs200x_project.h b/src/actions/vs200x/vs200x_project.h new file mode 100644 index 0000000..a4950f9 --- /dev/null +++ b/src/actions/vs200x/vs200x_project.h @@ -0,0 +1,41 @@ +/** + * \file vs200x_project.h + * \brief Visual Studio 200x project generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_VS200X_PROJECT_H) +#define PREMAKE_VS200X_PROJECT_H + +#include "session/session.h" + +int vs200x_project_config_element(Session sess, Project prj, Stream strm); +int vs200x_project_config_end(Session sess, Project prj, Stream strm); +int vs200x_project_create(Session sess, Project prj, Stream strm); +int vs200x_project_element(Session sess, Project prj, Stream strm); +int vs200x_project_encoding(Session sess, Project prj, Stream strm); +int vs200x_project_file(Session sess, Project prj, Stream strm, const char* filename, int state); +int vs200x_project_files(Session sess, Project prj, Stream strm); +int vs200x_project_globals(Session sess, Project prj, Stream strm); +int vs200x_project_platforms(Session sess, Project prj, Stream strm); +int vs200x_project_references(Session sess, Project prj, Stream strm); +int vs200x_project_tool_files(Session sess, Project prj, Stream strm); +int vs200x_project_vc_alink_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_app_verifier_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_bsc_make_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_cl_compiler_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_custom_build_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_fx_cop_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_midl_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_linker_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_managed_resource_compiler_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_manifest_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_pre_build_event_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_pre_link_event_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_post_build_event_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_resource_compiler_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_web_deployment_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_web_service_proxy_generator_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_xdc_make_tool(Session sess, Project prj, Stream strm); +int vs200x_project_vc_xml_data_generator_tool(Session sess, Project prj, Stream strm); + +#endif diff --git a/src/actions/vs200x/vs200x_solution.c b/src/actions/vs200x/vs200x_solution.c new file mode 100644 index 0000000..6578bd4 --- /dev/null +++ b/src/actions/vs200x/vs200x_solution.c @@ -0,0 +1,33 @@ +/** + * \file vs200x_solution.c + * \brief Visual Studio multiple-version solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ + +#include <stdlib.h> +#include "premake.h" +#include "vs200x.h" +#include "vs200x_solution.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; +} diff --git a/src/actions/vs200x/vs200x_solution.h b/src/actions/vs200x/vs200x_solution.h new file mode 100644 index 0000000..18683c4 --- /dev/null +++ b/src/actions/vs200x/vs200x_solution.h @@ -0,0 +1,30 @@ +/** + * \file vs200x_solution.h + * \brief Visual Studio 200x solution generation functions. + * \author Copyright (c) 2002-2008 Jason Perkins and the Premake project + */ +#if !defined(PREMAKE_VS200X_SOLUTION_H) +#define PREMAKE_VS200X_SOLUTION_H + +#include "session/session.h" + +int vs2002_solution_configuration(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); + +int vs2008_solution_signature(Session sess, Solution sln, Stream strm); + +int vs200x_solution_create(Session sess, Solution sln, Stream strm); + +#endif |