First integration of new Lua-based architecture

This commit is contained in:
starkos 2008-10-31 18:38:05 +00:00
parent 2dbd283813
commit 608551f8f4
380 changed files with 4505 additions and 20587 deletions

88
BUILD.txt Normal file
View File

@ -0,0 +1,88 @@
PREMAKE BUILD INSTRUCTIONS
As of version 4.0, Premake is written in a mix of C and Lua. This mix
makes it smaller, enables the templating features, and easier the
whole thing easier to maintain. The trade-off is a couple of wrinkles
in the build process.
If you downloaded a source code package from SourceForge, you can just
build using the default "Release" configuration and go. The information
in this file is primarily for people who got the code from Subversion,
or developers who want to make changes to the Premake code.
GENERATING THE PROJECT FILES
If you downloaded a source code package from SourceForge, the project
files are already included and you can skip ahead to the next section.
If you downloaded the sources from Subversion, you'll need to generate
new projects files before you can build.
In order to generate the project files, you need a working version of
Premake, either 3.x or 4.x versions, installed on your system. You can
get it as source code or a prebuilt binary from the SourceForge
download page.
Once you have a working Premake installed, generate the project files
in the normal way. For Premake 4.x, type a command like:
premake4 gmake -- for GNU makefiles using GCC
premake4 vs2005 -- for a Visual Studio 2005 solution
For Premake 3.x, use the old command line format:
premake --target gnu
premake --target vs2005
Use the "--help" option to see all available targets.
RELEASE AND DEBUG BUILDS
Premake can be built in either "release" or "debug" modes. You can
choose which configuration to build with the CONFIG argument:
make CONFIG=Debug -- build in debug mode
make CONFIG=Release -- build in release mode
(IDEs like Visual Studio provide their own mechanism for switching
build configurations).
In release mode (the default) you can build and run Premake like any
other C application. In debug mode, Premake reads the Lua scripts from
the disk at runtime, enabling compile-less code/test iterations. But
it needs some help to find the scripts.
You can specify the location of the scripts in one of two ways. You
can use the /scripts command line argument, like so:
premake4 /scripts=~/Code/premake4/src gmake
Or by setting a PREMAKE_PATH environment variable.
PREMAKE_PATH=~/Code/premake4/src
As you can see, you need to specify the location of the Premake "src"
directory, the one containing "_premake_main.lua".
COMPILING SCRIPTS
If you make changes to the core Lua scripts, you can integrate them
into the release build using the "compile" command:
premake4 compile -- for Premake 4.x
premake --compile -- for Premake 3.x
This command compiles all of the scripts listed in _manifest.lua into
bytecode and embeds them into src/host/bytecode.c. The next release
build will include the updated scripts.
CONFUSED?
I'll be glad to help you out. Stop by the main project website where
you leave a note in the forums (the preferred approach), join the
mailing list, or contact me directly.
http://industriousone.com/premake

View File

@ -5,241 +5,5 @@ This version is a complete rewrite of Premake.
- New, more readable syntax for project information
- Better validation of command-line arguments
- Standardized path handling across all project settings
- Template system allows script-based custom generators
- Upgraded to Lua 5.1.2
3.5
--------------------
- Prevent creation of import libraries on OS X
- Improved handling of dylibs on OS X
- Patch 1771977: Ability to compile C source as C++ in Code::Blocks (Ryan Pusztai)
- Patch 1771168: luaL_getn speed optimization (Richard O'Grady)
- Bug 1804810: out-implib not present in linux gnu compler toolchain
- Bug 1806949: .Net reference paths are broken when bindir is specified
- Bug 1806960: Make clean does not remove .mdb files
- Bug 1831389: Makefiles stored in subdirs contain no targets on first run
3.4
--------------------
- Added `no-pch` flag to suppress precompiled headers
- Added App.config support to GNU makefiles
- Add os.mkdir() to script environment
- Makefile now creates target directory before copying .NET references
- Feature 1520182: Enhanced file-handling functions
- Bug 531878: Problems with relative paths
- Bug 1723867: Config-specific post-build on GNU target (Benoit Miller)
- Bug 1596826: XML targets doesn't escape xml entities
- Bug 1600155: Core dump due to newpackage() and matchfiles()
- Bug 1608895: resgen command shown
- Bug 1639730: Output filename is not set
- Bug 1729227: non-portable executable with relative library path
- Bug 1559951: default clean rule removes package dir
- Patch 1733674: PCH support for Code::Block targets (Ryan Pusztai)
- Patch 1746563: Ability to specify GUID for VS targets (Ryan Pusztai)
- Patch 1754867: Creating import lib of different name (Ryan Pusztai)
3.3
--------------------
- Added support for prebuild, prelink, and postbuild commands
- Added `target` global variable to script environment
- Added build flag `no-edit-and-continue`
- Added build flags `native-wchar` and `no-native-wchar`
- Added build flag `no-manifest`
- Added build flag `seh-exceptions` (VS2005 only)
- Added `resdefines`, `respaths`, and `resoptions`
- Added `prebuildcommands`, `prelinkcommands`, and `postbuildcommands`
- Added `pchheader` and `pchsource` (Visual Studio only)
- Feature 1337547: Package-level bindir and libdir
- Bug 1565755: Generated makefiles do not work with MSYS
- Bug 1587955: Target path ignored for libs
- Bug 1574725: Static library extension for "gnu" target
- Bug 1522861: Fixed by using "ar -rcs" instead of "ar -cr && ranlib"
- Bug 1656816: Mkdir set wrong directory rights
- Bug 1655595: Compile/build problem on FreeBSD
- Bug: "gnu" clean rule doesn't work in cmd.exe
- Improved behavior of Linux findlib()
- Updated Code::Blocks support to latest project version (major="1" minor="6")
- Patch 1681666: GNU targets always show the console if kind = 'winexe'
3.2
--------------------
- Added support for Code::Blocks
- Updated MonoDevelop support
- Upgraded Lua to 5.0.3
- Added new matchdirs() to Lua script environment
- Expose list of packages as _PACKAGES global in Lua
- Turn off edit-and-continue in release builds with symbols
- Bug 1559873: libpaths inserts extra space after -L
3.1
--------------------
- Added support for Visual Studio 2005
- Added support for Windows resources to GNU make target
- Added path handling functions to Lua environment
- Added matchrecursive() for recursive file searches
- Added os.fileexists() function to Lua environment
- Added os.appendfile() function to Lua environment
- Changed `monoresgen` to `resgen` to keep up with Mono project
- Added `mono2` .NET compiler set for Mono .NET 2.0 support
- Feature 1096677: exclude files from matchfiles (package.excludes)
- Bug 1439463: VS2003 RTTI problem
- Bug 1439446: GNU Makefile problem under Mingw32
- Bug 1422068: package.path="." causes bad makefiles
- Bug 1431530: makefile target fails when project path specified
3.0
--------------------
- Upgraded Lua interpreter to version 5.0.1
- The options table now stores simple values, rather than tables
- Completed MonoDevelop support
- Improved .NET resource handling for GNU generator
- Added unit test suite
- Merged Scott Graham unicode build flag patch
- Removed package.warninglevel in favor of extra-warnings flag
- Added package.targetprefix
- Overhauled structure of generated GNU makefiles
- Added --os command line option
- Fixed bug 1268588: Use gcc to link C packages
- Fixed bug 1363306: GNU C# should copy referenced DLLs
2.4
--------------------
- Added chdir() to Lua script environment
- Merged Thomas Harning's patch for .NET resources on GNU
- Fixed bug 1194702: Can't put multiple packages in same directory
- Fixed bug in GNU shared library builds (doh!)
- Added target 'vs2002' to replace 'vs7'
2.3
--------------------
- Added 'project.config[]' with 'bindir' and 'libdir'
- Merged Scott Graham's "warninglevel" patch.
- Fixed bug 1153484: Import lib in wrong directory.
- Fixed bug 1013352: Stack overflow with large projects.
- Fixed bug 945406: package.files, bad value = crash
2.2
--------------------
- Worked around VS.NET bug for .NET assemblies > 64K.
- Added --very-verbose flag to GNU generator.
- GNU generator now supports assembly sources.
2.1
--------------------
- File extension of generated binaries can now be set
with config.targetextension.
- Windows targets now handle .def files for DLLs.
2.0
--------------------
- Can now specify build actions per file
- Include paths are now passed to VC7 resource compiler
- Removed _WIN32 define from Cygwin makefiles
- Added package.objdir to set intermediates directory
- Added rmdir() to Lua script environment
- A big bag of bug fixes
1.9
--------------------
- Made verbose mode even more verbose.
- posix.c now builds properly as C.
- Fixed package dependency generation for GNU and VS2003.
- Display Lua version number in usage text.
- Fixed VS link between *.aspx and *.aspx.cs files.
- Fixed VS link between *.resx and *.cs files.
- Fixed *.d file generation for gcc 2.9x.
- Unified various help options under '--help'.
- Bin and Lib paths can now be arbitrarily long.
- linkoptions are now applied in VC6 and VC7 projects.
1.8
--------------------
- Added support for ASP.NET projects.
- Fixed a bug in VC6 support for static libraries.
- matchfiles() now uses package path instead of script path.
- Added --verbose option.
- No longer apply no-rtti and no-exceptions to *.c files.
1.7
--------------------
- Location of generated project files can now be specified with
the project.path variable.
- Inter-package dependencies are fixed for GNU makefiles.
- No longer need to execute in same directory as project script.
- Added "c" language specifier.
- Added support for .resx and .config files to C# projects.
- Added support for full assembly names in .NET references.
- Fixed handling of paths in package.target variable.
- Improved support for SharpDevelop.
- Started support for OS X.
- Added support for Digital Mars compiler.
1.6
--------------------
- VS7 generator crashed if a package was built before one of its
dependencies. Now immediately assigns UUID before processing.
- Added support for Visual Studio 2003 and SharpDevelop.
- Added binaries directory as a reference path for VS7.
1.5
--------------------
- Added initial support for building static libraries.
- Added "no-main" flag, prevents overriding WinMain() on
Windows builds.
- Added "--no-rtti" and "no-exceptions" build flags to
disable those C++ features.
- Display error message when project has no packages.
- Moved VC7 *.pdb files into intermediates directory.
1.4
--------------------
- Bug fixes to the path manipulation routines.
- GNU makefiles are regenerated when premake scripts change.
1.3
--------------------
- Added support for the Cygwin environment.
- Added "static-runtime" build flag to statically link against C/C++
standard runtime libraries.
- Bug fixes to Visual Studio 6 and 7 generators and path reversing
algorithm.
1.2
--------------------
- Standardized format of command-line options.
- Can now handle custom command-line options in script.
- Added new function findlib().
- Added new C++ build flag "managed" for writing C++ .NET code.
- Can now use open-source C# compilers in VS6 generator.
- Several bug fixes to the VS7 generator.
1.1
--------------------
- Added support for custom build configurations. Added "optimize",
"optimize-size", "optimize-speed", and "no-symbols" flags to control
build settings.
- Added matchfiles() to select files using wildcards.
- Added "unsafe" flag for C# projects.
- Added newpackage() function for creating new package objects inline,
instead of creating separate scripts.
- Changed include() to dopackage() and option() to addoption(). The old
versions have been kept for compatibility, but will be deprecated
eventually.
- Major cleanup of the source code.
1.0
--------------------
- Fixed a bug related to the reference paths in VS7 C# projects.
- Display a warning message if a reference path can't be found.
- Automatically create bin and lib directories if they do not exist.
- GNU C# projects will now properly use the configured library paths.
- Added --with-mono and --with-pnet options.
- VS7 C# projects will now properly use the configured library paths.
- Switched to Lua (http://www.lua.org/) for project script parsing.
- Add support for custom project options.
- Changed 'type' to 'kind' to avoid conflict with Lua function of the same name.
- Changed 'conexe' to 'exe' because I liked it better.
- Changed 'library' to 'dll' for C# projects to keep things consistent.
0.9
--------------------
- Initial public release.

View File

@ -8,24 +8,8 @@ A build configuration tool
See their website at http://www.lua.org/
BUILDING PREMAKE
See the file BUILD.txt for instructions on building Premake.
Until an official release is made you will need to use an existing
Premake 3.x executable to generate the project files. Grab a binary
or source package from the project site at:
http://premake.sourceforge.net/
Then use it to create the project files for your particular toolset.
$ cd premake-4.0
$ premake --target vs2005 # For Visual Studio 2005 files
$ premake --target gnu # For GNU makefile
Run `premake --help` for a complete list of supported toolsets.
SUPPORT
For questions, comments, or more information, visit the project
website at http://industriousone.com/premake

View File

@ -1,10 +1,7 @@
project.name = "Premake4"
-- Project options
addoption("no-tests", "Build without automated tests")
project.configs = { "Release", "Debug" }
-- Output directories
project.config["Debug"].bindir = "bin/debug"
@ -21,140 +18,114 @@ project.name = "Premake4"
function doclean(cmd, arg)
docommand(cmd, arg)
os.rmdir("bin")
os.rmdir("doc")
end
-- Release code
REPOS = "https://premake.svn.sourceforge.net/svnroot/premake"
TRUNK = "/trunk"
TAGS = "/tags/4.0-dev/"
-- Functions copied from Premake4; can drop them once I'm self-hosting
function dorelease(cmd, arg)
if (not arg) then
error "You must specify a version"
end
path = { }
-------------------------------------------------------------------
-- Make sure everything is good before I start
-------------------------------------------------------------------
print("")
print("PRE-FLIGHT CHECKLIST")
print(" * is README up-to-date?")
print(" * is CHANGELOG up-to-date?")
print(" * did you test build with GCC?")
print(" * did you test build with Doxygen?")
print(" * are 'svn' (all) and '7z' (Windows) available?")
print("")
print("Press [Enter] to continue or [^C] to quit.")
io.stdin:read("*l")
-------------------------------------------------------------------
-- Set up environment
-------------------------------------------------------------------
local version = arg
os.mkdir("release")
local folder = "premake4-"..version
local trunk = REPOS..TRUNK
local branch = REPOS..TAGS..version
-------------------------------------------------------------------
-- Build and run all automated tests on working copy
-------------------------------------------------------------------
print("Building tests on working copy...")
os.execute("premake --target gnu >release/release.log")
result = os.execute("make CONFIG=Release >release/release.log")
if (result ~= 0) then
error("Test build failed; see release.log for details")
end
-------------------------------------------------------------------
-- Look for a release branch in SVN, and create one from trunk if necessary
-------------------------------------------------------------------
print("Checking for release branch...")
os.chdir("release")
result = os.execute(string.format("svn ls %s >release.log 2>&1", branch))
if (result ~= 0) then
print("Creating release branch...")
result = os.execute(string.format('svn copy %s %s -m "Creating release branch for %s" >release.log', trunk, branch, version))
if (result ~= 0) then
error("Failed to create release branch at "..branch)
end
end
-------------------------------------------------------------------
-- Checkout a local copy of the release branch
-------------------------------------------------------------------
print("Getting source code from release branch...")
os.execute(string.format("svn co %s %s >release.log", branch, folder))
if (not os.fileexists(folder.."/README.txt")) then
error("Unable to checkout from repository at "..branch)
end
-------------------------------------------------------------------
-- Embed version numbers into the files
-------------------------------------------------------------------
-- (embed version #s)
-- (check into branch)
-------------------------------------------------------------------
-- Build the release binary for this platform
-------------------------------------------------------------------
print("Building release version...")
os.chdir(folder)
os.execute("premake --clean --no-tests --target gnu >../release.log")
if (windows) then
os.execute("make CONFIG=Release >../release.log")
os.chdir("bin/release")
result = os.execute(string.format("7z a -tzip ..\\..\\..\\premake4-win32-%s.zip premake4.exe >../release.log", version))
elseif (macosx) then
os.execute('TARGET_ARCH="-arch i386 -arch ppc" make CONFIG=Release >../release.log')
os.chdir("bin/release")
result = os.execute(string.format("tar czvf ../../../premake4-macosx-%s.tar.gz premake4 >../release.log", version))
else
os.execute("make CONFIG=Release >../release.log")
os.chdir("bin/release")
result = os.execute(string.format("tar czvf ../../../premake4-linux-%s.tar.gz premake4 >../release.log", version))
end
if (result ~= 0) then
error("Failed to build binary package; see release.log for details")
end
os.chdir("../../..")
-------------------------------------------------------------------
-- Build the source code package
-------------------------------------------------------------------
if (macosx) then
result = os.execute(string.format("zip -r9 premake4-src-%s.zip %s/* >release.log", version, folder))
if (result ~= 0) then
error("Failed to build source code package; see release.log for details")
end
end
-------------------------------------------------------------------
-- Clean up
-------------------------------------------------------------------
print("Cleaning up...")
os.rmdir(folder)
os.remove("release.log")
-------------------------------------------------------------------
-- Next steps
-------------------------------------------------------------------
if (windows) then
print("DONE - now run release script under Linux")
elseif (linux) then
print("DONE - now run release script under Mac OS X")
else
print("DONE - really this time")
end
function string.findlast(s, pattern, plain)
local curr = 0
repeat
local next = s:find(pattern, curr + 1, plain)
if (next) then curr = next end
until (not next)
if (curr > 0) then
return curr
end
end
function path.getbasename(p)
local fn = path.getname(p)
local i = fn:findlast(".", true)
if (i) then
return fn:sub(1, i - 1)
else
return fn
end
end
function path.getname(p)
local i = p:findlast("/", true)
if (i) then
return p:sub(i + 1)
else
return p
end
end
-- Compile scripts to bytecodes
function dumpfile(out, filename)
local func = loadfile(filename)
local dump = string.dump(func)
local len = string.len(dump)
out:write("\t\"")
for i=1,len do
out:write(string.format("\\%03o", string.byte(dump, i)))
end
out:write("\",\n")
return len
end
function dumptmpl(out, filename)
local f = io.open(filename)
local tmpl = f:read("*a")
f:close()
local name = path.getbasename(filename)
local dump = "_TEMPLATES."..name.."=premake.template.loadstring('"..name.."',[["..tmpl.."]])"
local len = string.len(dump)
out:write("\t\"")
for i=1,len do
out:write(string.format("\\%03o", string.byte(dump, i)))
end
out:write("\",\n")
return len
end
function docompile(cmd, arg)
local sizes = { }
scripts, templates, actions = dofile("src/_manifest.lua")
local out = io.open("src/host/bytecode.c", "w+b")
out:write("/* Precompiled bytecodes for built-in Premake scripts */\n")
out:write("/* To regenerate this file, run `premake --compile` (Premake 3.x) */\n\n")
out:write("const char* builtin_bytecode[] = {\n")
for i,fn in ipairs(scripts) do
print(fn)
s = dumpfile(out, "src/"..fn)
table.insert(sizes, s)
end
for i,fn in ipairs(templates) do
print(fn)
s = dumptmpl(out, "src/"..fn)
table.insert(sizes, s)
end
for i,fn in ipairs(actions) do
print(fn)
s = dumpfile(out, "src/"..fn)
table.insert(sizes, s)
end
out:write("};\n\n");
out:write("int builtin_sizes[] = {\n")
for i,v in ipairs(sizes) do
out:write("\t"..v..",\n")
end
out:write("\t0\n};\n");
out:close()
print("Done.")
end

View File

@ -1,21 +1,139 @@
---------------------------------------------------------------------------
-- Premake4 solution script for Premake4
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project
---------------------------------------------------------------------------
--
-- Premake 4.x build configuration script
--
solution "Premake4"
configurations { "Debug", "Release" }
configurations { "Release", "Debug" }
project "Premake4"
targetname "premake4"
language "C"
kind "ConsoleExe"
flags { "No64BitChecks", "ExtraWarnings", "FatalWarnings" }
includedirs { "src/host/lua-5.1.2/src" }
language "c"
defines { "_CRT_SECURE_NO_WARNINGS" }
files { "**.h", "**.c" }
files
{
"src/**.h", "src/**.c", "src/**.lua", "src/**.tmpl",
"tests/**.lua"
}
excludes
{
"src/premake.lua",
"src/host/lua-5.1.2/src/lua.c",
"src/host/lua-5.1.2/src/luac.c",
"src/host/lua-5.1.2/src/print.c",
"src/host/lua-5.1.2/**.lua",
"src/host/lua-5.1.2/etc/*.c"
}
configuration "Debug"
defines { "_DEBUG" }
targetdir "bin/debug"
defines "_DEBUG"
flags { "Symbols" }
configuration "Release"
defines { "NDEBUG" }
targetdir "bin/release"
defines "NDEBUG"
flags { "OptimizeSize", "NoFramePointer" }
configuration "vs.*"
defines { "_CRT_SECURE_NO_WARNINGS" }
--
-- A more thorough cleanup
--
function onclean()
os.rmdir("bin")
os.rmdir("obj") -- get rid of this once "clean" is working properly
end
--
-- "Compile" action compiles scripts to bytecode and embeds into a static
-- data buffer in src/host/bytecode.c.
--
local function dumpfile(out, fname)
local func = loadfile(fname)
local dump = string.dump(func)
local len = string.len(dump)
out:write("\t\"")
for i=1,len do
out:write(string.format("\\%03o", string.byte(dump, i)))
end
out:write("\",\n")
return len
end
local function dumptmpl(out, fname)
local f = io.open(fname)
local tmpl = f:read("*a")
f:close()
local name = path.getbasename(fname)
local dump = "_TEMPLATES."..name.."=premake.template.loadstring('"..name.."',[["..tmpl.."]])"
local len = string.len(dump)
out:write("\t\"")
for i=1,len do
out:write(string.format("\\%03o", string.byte(dump, i)))
end
out:write("\",\n")
return len
end
local function docompile()
local sizes = { }
scripts, templates, actions = dofile("src/_manifest.lua")
local out = io.open("src/host/bytecode.c", "w+b")
out:write("/* Precompiled bytecodes for built-in Premake scripts */\n")
out:write("/* To regenerate this file, run `premake --compile` (Premake 3.x) */\n\n")
out:write("const char* builtin_bytecode[] = {\n")
for i,fn in ipairs(scripts) do
print(fn)
s = dumpfile(out, "src/"..fn)
table.insert(sizes, s)
end
for i,fn in ipairs(templates) do
print(fn)
s = dumptmpl(out, "src/"..fn)
table.insert(sizes, s)
end
for i,fn in ipairs(actions) do
print(fn)
s = dumpfile(out, "src/"..fn)
table.insert(sizes, s)
end
out:write("};\n\n");
out:write("int builtin_sizes[] = {\n")
for i,v in ipairs(sizes) do
out:write("\t"..v..",\n")
end
out:write("\t0\n};\n");
out:close()
print("Done.")
end
premake.actions["compile"] = {
description = "Compile scripts to bytecode and embed in bytecode.c",
execute = docompile,
}

50
src/_manifest.lua Normal file
View File

@ -0,0 +1,50 @@
--
-- _manifest.lua
-- Manage the list of built-in Premake scripts.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project
--
-- The master list of built-in scripts. Order is important! If you want to
-- build a new script into Premake, add it to this list.
local scripts =
{
"base/path.lua",
"base/string.lua",
"base/table.lua",
"base/os.lua",
"base/globals.lua",
"base/premake.lua",
"base/template.lua",
"base/project.lua",
"base/functions.lua",
"base/gcc.lua",
-- this one must be last
"_premake_main.lua"
}
-- The list of templates
local templates =
{
"actions/make/make_solution.tmpl",
"actions/make/make_cpp_project.tmpl",
"actions/vstudio/vs2002_solution.tmpl",
}
-- The list of built in actions
local actions =
{
"actions/clean/_clean.lua",
"actions/make/_make.lua",
"actions/vstudio/_vstudio.lua",
}
return scripts, templates, actions

132
src/_premake_main.lua Normal file
View File

@ -0,0 +1,132 @@
--
-- _premake_main.lua
-- Script-side entry point for the main program logic.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project
--
local shorthelp = "Type 'premake4 --help' for help"
local versionhelp = "premake4 (Premake Build Script Generator) %s"
local scriptfile = "premake4.lua"
--
-- Display the help text
--
local function showhelp()
actions = { }
for name,_ in pairs(premake.actions) do table.insert(actions, name) end
table.sort(actions)
printf("Premake %s, a build script generator", _PREMAKE_VERSION)
printf(_PREMAKE_COPYRIGHT)
printf("%s %s", _VERSION, _COPYRIGHT)
printf("")
printf("Usage: premake4 [options] action [arguments]")
printf("")
printf("ACTIONS")
printf("")
for _,name in ipairs(actions) do
printf(" %-17s %s", name, premake.actions[name].description)
end
printf("")
printf("OPTIONS")
printf("")
printf(" --file=name Process the specified Premake script file")
printf(" --help Display this information")
printf(" --scripts=path Search for additional scripts on the given path")
printf(" --version Display version information")
printf("")
printf("For additional information, see http://industriousone.com/premake")
end
--
-- Script-side program entry point.
--
function _premake_main(scriptpath)
-- if running off the disk (in debug mode), load everything
-- listed in _manifest.lua; the list divisions make sure
-- everything gets initialized in the proper order.
if (scriptpath) then
-- core code first
local s, t, a = dofile(scriptpath .. "/_manifest.lua")
for i = 1, #s - 1 do
dofile(scriptpath.."/"..s[i])
end
-- then the templates
for _,v in ipairs(t) do
local n = path.getbasename(v)
_TEMPLATES[n] = premake.template.loadfile(scriptpath.."/"..v)
end
-- finally the actions
for _,v in ipairs(a) do
dofile(scriptpath.."/"..v)
end
end
-- If there is a project script available, run it to get the
-- project information, available options and actions, etc.
local fname = _OPTIONS["file"] or scriptfile
if (os.isfile(fname)) then
dofile(fname)
end
-- Process special options like /version and /help
if (_OPTIONS["version"]) then
printf(versionhelp, _PREMAKE_VERSION)
return 1
end
if (_OPTIONS["help"]) then
showhelp()
return 1
end
-- If no action was specified, show a short help message
if (not _ACTION) then
print(shorthelp)
return 1
end
-- If there wasn't a project script I've got to bail now
if (not os.isfile(fname)) then
error("No Premake script ("..scriptfile..") found!", 2)
end
-- Prep the session, and then hand off control to the action
local action = premake.actions[name]
if (not premake.actions[_ACTION]) then
error("Error: No such action '".._ACTION.."'", 0)
end
ok, err = premake.checktools()
if (not ok) then error("Error: " .. err, 0) end
ok, err = premake.project.checkall()
if (not ok) then error("Error: " .. err, 0) end
premake.doaction(_ACTION)
return 0
end

View File

@ -1,27 +0,0 @@
/**
* \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"
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);
ActionInfo 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 }
};

View File

@ -1,46 +0,0 @@
/**
* \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 "objects/session.h"
/**
* Callback signature for Premake action handlers, which will get triggered
* if user specifies that action on the command line for processing.
* \param sess The current execution session context.
* \returns OKAY If successful.
*/
typedef int (*ActionCallback)(Session sess);
/**
* Describe a Premake action, including the handler function and the metadata
* required to list it in the user help.
*/
typedef struct struct_ActionInfo
{
const char* name;
const char* description;
ActionCallback callback;
} ActionInfo;
/* the list of built-in Premake actions */
extern ActionInfo Actions[];
#endif
/** @} */

View File

@ -0,0 +1,76 @@
--
-- _clean.lua
-- The "clean" action: removes all generated files.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project
--
clean = { }
--
-- Remove configuration specific files
--
function clean.config(cfg)
-- remove the target binary
os.remove(cfg.target)
-- if there is an import library, remove that too
os.remove(premake.project.gettargetfile(cfg, "implib", "StaticLib", "linux"))
os.remove(premake.project.gettargetfile(cfg, "implib", "StaticLib", "windows"))
-- remove object directory
-- os.rmdir(cfg.objdir)
end
--
-- Remove files created by an object's templates.
--
function clean.templatefiles(this, templates)
if (templates) then
for _,tmpl in ipairs(templates) do
local fname = premake.getoutputname(this, tmpl[1])
os.remove(fname)
end
end
end
--
-- For each registered action, walk all of the objects in the session and
-- remove the files created by their templates.
--
function clean.all()
-- remove all template-driven files
for _,action in pairs(premake.actions) do
for _,sln in ipairs(_SOLUTIONS) do
clean.templatefiles(sln, action.solutiontemplates)
for prj in premake.project.projects(sln) do
clean.templatefiles(prj, action.projecttemplates)
for cfg in premake.project.configs(prj) do
clean.config(cfg)
end
end
end
end
-- project custom clean-up
if (type(onclean) == "function") then
onclean()
end
end
--
-- Register the "clean" action.
--
premake.actions["clean"] = {
description = "Remove all binaries and generated files",
execute = clean.all,
}

View File

@ -0,0 +1,93 @@
--
-- _make.lua
-- Define the makefile action(s).
-- Copyright (c) 2008 Jason Perkins and the Premake project
--
make = { }
--
-- Escape a string so it can be written to a makefile.
--
function make.esc(value)
if (type(value) == "table") then
local result = { }
for _,v in ipairs(value) do
table.insert(result, make.esc(v))
end
return result
else
local result = value:gsub(" ", "\\ ")
return result
end
end
--
-- Get the makefile file name for a solution or a project. If this object is the
-- only one writing to a location then I can use "Makefile". If more than one object
-- writes to the same location I use name + ".make" to keep it unique.
--
function make.getmakefilename(this, searchprjs)
-- how many projects/solutions use this location?
local count = 0
for _,sln in ipairs(_SOLUTIONS) do
if (sln.location == this.location) then count = count + 1 end
if (searchprjs) then
for _,prj in ipairs(sln.projects) do
if (prj.location == this.location) then count = count + 1 end
end
end
end
if (count == 1) then
return "Makefile"
else
return this.name .. ".make"
end
end
--
-- Returns a list of object names, properly escaped to be included in the makefile.
--
function make.getnames(tbl)
local result = table.extract(tbl, "name")
for k,v in pairs(result) do
result[k] = make.esc(v)
end
return result
end
--
-- Register the "gmake" action
--
premake.actions["gmake"] = {
shortname = "GNU Make",
description = "GNU makefiles for POSIX, MinGW, and Cygwin",
valid_kinds = { "ConsoleExe", "WindowedExe", "StaticLib", "SharedLib" },
valid_languages = { "C", "C++" },
valid_tools = {
cc = { "gcc" },
csc = { "mcs" },
},
solutiontemplates =
{
{ function(this) return make.getmakefilename(this, false) end, _TEMPLATES.make_solution },
},
projecttemplates =
{
{ function(this) return make.getmakefilename(this, true) end, _TEMPLATES.make_cpp_project },
},
}

View File

@ -1,88 +0,0 @@
/**
* \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);
}

View File

@ -1,46 +0,0 @@
/**
* \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(Project prj, Stream strm)
{
int z = OKAY;
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;
}

View File

@ -1,187 +0,0 @@
/**
* \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/buffers.h"
#include "base/cstr.h"
#include "base/error.h"
#include "base/path.h"
/**
* Escapes spaces in a string value, so it can be safely written to the makefile.
* \param value The string value to escape.
* \returns The same string value, with spaces escaped.
*/
const char* make_escape(const char* value)
{
char* buffer = buffers_next();
const char* src = value;
char* dst = buffer;
while (*src != '\0')
{
if (*src == ' ')
{
*(dst++) = '\\';
}
*(dst++) = *(src++);
}
*dst = '\0';
return buffer;
}
/**
* 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.
* 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(Project prj)
{
const char* my_path;
int si, sn, in_conflict = 0;
Session sess = project_get_session(prj);
/* get the default filename for this project */
my_path = project_get_filename(prj, "Makefile", "");
/* see if any other solution wants to use this same path */
sn = session_num_solutions(sess);
for (si = 0; si < sn && !in_conflict; ++si)
{
const char* their_path;
int pi, pn;
Solution sln = session_get_solution(sess, si);
their_path = solution_get_filename(sln, "Makefile", "");
if (cstr_eq(my_path, their_path))
{
in_conflict = 1;
}
/* check any projects contained by this solution */
pn = solution_num_projects(sln);
for (pi = 0; pi < pn && !in_conflict; ++pi)
{
Project prj2 = solution_get_project(sln, pi);
if (prj != prj2)
{
their_path = project_get_filename(prj2, "Makefile", "");
if (cstr_eq(my_path, their_path))
{
in_conflict = 1;
}
}
}
}
/* if a conflict was detected use an alternate name */
if (in_conflict)
{
my_path = project_get_filename(prj, NULL, ".make");
}
/* 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.
* 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(Solution sln)
{
const char* my_path;
int i, n;
Session sess = solution_get_session(sln);
/* get the default file name for this solution */
my_path = solution_get_filename(sln, "Makefile", "");
/* 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)
{
const char* their_path = solution_get_filename(them, "Makefile", "");
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;
}
/**
* Write a string value to a stream, escape any space characters it contains.
* \param strm The output stream.
* \param value The string value to escape.
* \returns OKAY if successful.
*/
int make_write_escaped(Stream strm, const char* value)
{
const char* escaped = make_escape(value);
return stream_write(strm, escaped);
}

View File

@ -1,18 +0,0 @@
/**
* \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 "objects/project.h"
const char* make_escape(const char* value);
const char* make_get_obj_filename(const char* filename);
const char* make_get_project_makefile(Project prj);
Strings make_get_project_names(Solution sln);
const char* make_get_solution_makefile(Solution sln);
int make_write_escaped(Stream strm, const char* value);
#endif

View File

@ -0,0 +1,99 @@
# <%= premake.actions[_ACTION].shortname %> project makefile autogenerated by Premake
ifndef CONFIG
CONFIG=<%= make.esc(this.configurations[1]) %>
endif
<% for cfg in premake.project.configs(this) do %>
ifeq ($(CONFIG),<%= make.esc(cfg.name)%>)
TARGETDIR = <%= make.esc(path.getdirectory(cfg.target)) %>
TARGET = $(TARGETDIR)/<%= make.esc(path.getname(cfg.target)) %>
OBJDIR = <%= make.esc(premake.project.getobjdir(cfg)) %>
DEFINES += <%= premake.tools[_OPTIONS.cc].make_defines(cfg) %>
INCLUDES += <%= premake.tools[_OPTIONS.cc].make_includes(cfg) %>
CPPFLAGS += <%= premake.tools[_OPTIONS.cc].make_cppflags(cfg) %> $(DEFINES) $(INCLUDES)
CFLAGS += $(CPPFLAGS) $(ARCH) <%= premake.tools[_OPTIONS.cc].make_cflags(cfg) %> <%= table.concat(cfg.buildoptions, " ") %>
CXXFLAGS += $(CFLAGS) <%= premake.tools[_OPTIONS.cc].make_cxxflags(cfg) %>
LDFLAGS += <%= premake.tools[_OPTIONS.cc].make_ldflags(cfg) %> <%= table.concat(cfg.linkoptions, " ") %>
RESFLAGS += $(DEFINES) $(INCLUDES) <%= table.concat(cfg.resoptions, " ") %>
LDDEPS += <%= table.concat(premake.project.getlibraries(cfg, premake.project.getdependencies(cfg))) %>
endif
<% end %>
OBJECTS := \
<% for _, file in ipairs(this.files) do %>
<% if path.iscppfile(file) then %>
$(OBJDIR)/<%= make.esc(path.getbasename(file)) %>.o \
<% end %>
<% end %>
RESOURCES := \
<% for _, file in ipairs(this.files) do %>
<% if path.isresourcefile(file) then %>
$(OBJDIR)/<%= make.esc(path.getbasename(file)) %>.res \
<% end %>
<% end %>
SHELLTYPE := msdos
ifeq (,$(ComSpec)$(COMSPEC))
SHELLTYPE := posix
endif
ifeq (/bin,$(findstring /bin,$(SHELL)))
SHELLTYPE := posix
endif
ifeq (posix,$(SHELLTYPE))
MKDIR := mkdir -p
PATHSEP := /
else
MKDIR := mkdir
PATHSEP := \\
endif
SYS_TARGET := $(subst /,$(PATHSEP),$(TARGET))
SYS_TARGETDIR := $(subst /,$(PATHSEP),$(TARGETDIR))
SYS_OBJDIR := $(subst /,$(PATHSEP),$(OBJDIR))
.PHONY: clean
<% if os.is("MacOSX") and this.kind == "WindowedExe" then %>
all: $(TARGET) $(dir $(TARGETDIR))PkgInfo $(dir $(TARGETDIR))Info.plist
$(dir $(TARGETDIR))PkgInfo:
$(dir $(TARGETDIR))Info.plist:
<% end %>
$(TARGET): $(TARGETDIR) $(OBJDIR) $(OBJECTS) $(LDDEPS) $(RESOURCES)
@echo Linking <%= this.name %>
@$(CXX) -o $@ $(LDFLAGS) $(ARCH) $(OBJECTS) $(RESOURCES)
$(TARGETDIR):
@echo Creating $@
@$(MKDIR) $(SYS_TARGETDIR)
$(OBJDIR):
@echo Creating $@
@$(MKDIR) $(SYS_OBJDIR)
clean:
@echo Cleaning <%= this.name %>
ifeq (posix,$(SHELLTYPE))
@rm -f $(TARGET)
@rm -rf $(OBJDIR)
else
@if exist $(SYS_TARGET) del $(SYS_TARGET)
@if exist $(SYS_OBJDIR) rmdir /s /q $(SYS_OBJDIR)
endif
<% for _, file in ipairs(this.files) do %>
<% if path.iscppfile(file) then %>
$(OBJDIR)/<%= make.esc(path.getbasename(file)) %>.o: <%= make.esc(file) %>
@echo $(notdir $<)
@<%= premake.tools[_OPTIONS.cc].make_file_rule(file) %>
<% end %>
<% end %>
-include $(OBJECTS:%.o=%.d)

View File

@ -1,329 +0,0 @@
/**
* \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(Project prj, Stream strm)
{
int z = OKAY;
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(Project prj, Stream strm)
{
const char* cfg_name = project_get_config(prj);
return stream_writeline(strm, "ifeq ($(CONFIG),%s)", cfg_name);
}
/**
* Write the CFLAGS configuration variable.
*/
int make_project_config_cflags(Project prj, Stream strm)
{
int z = OKAY;
z |= stream_write(strm, " CFLAGS += $(CPPFLAGS) $(ARCHFLAGS)");
/* debugging symbols */
if (project_has_flag(prj, "Symbols"))
{
z |= stream_write(strm, " -g");
}
/* optimizations */
if (project_has_flag(prj, "Optimize"))
{
z |= stream_write(strm, " -O2");
}
else if (project_has_flag(prj, "OptimizeSize"))
{
z |= stream_write(strm, " -Os");
}
else if (project_has_flag(prj, "OptimizeSpeed"))
{
z |= stream_write(strm, " -O3");
}
z |= stream_writeline(strm, "");
return z;
}
/**
* Write the CPPFLAGS configuration variable.
*/
int make_project_config_cppflags(Project prj, Stream strm)
{
int z = OKAY;
Strings values = project_get_config_values(prj, BlockDefines);
z |= stream_write(strm, " CPPFLAGS += -MMD");
z |= stream_write_strings(strm, values, "", " -D \"", "\"", "", "", NULL);
z |= stream_writeline(strm, "");
return z;
}
/**
* Write the CXXFLAGS configuration variable.
*/
int make_project_config_cxxflags(Project prj, Stream strm)
{
UNUSED(prj);
return stream_writeline(strm, " CXXFLAGS += $(CFLAGS)");
}
/**
* Write the opening conditional for a configuration block.
*/
int make_project_config_end(Project prj, Stream strm)
{
int z = OKAY;
UNUSED(prj);
z |= stream_writeline(strm, "endif");
z |= stream_writeline(strm, "");
return z;
}
/**
* Write the LDDEPS configuration variable.
*/
int make_project_config_lddeps(Project prj, Stream strm)
{
UNUSED(prj);
return stream_writeline(strm, " LDDEPS :=");
}
/**
* Write the LDFLAGS configuration variable.
*/
int make_project_config_ldflags(Project prj, Stream strm)
{
UNUSED(prj);
return stream_writeline(strm, " LDFLAGS +=");
}
/**
* Write the OBJDIR configuration variable.
*/
int make_project_config_objdir(Project prj, Stream strm)
{
const char* cfg_name = project_get_config(prj);
return stream_writeline(strm, " OBJDIR := obj/%s", make_escape(cfg_name));
}
/**
* Write the OUTDIR configuration variable.
*/
int make_project_config_outdir(Project prj, Stream strm)
{
UNUSED(prj);
return stream_writeline(strm, " OUTDIR := .");
}
/**
* Write the OUTFILE configuration variable.
*/
int make_project_config_outfile(Project prj, Stream strm)
{
const char* outfile = project_get_outfile(prj);
return stream_writeline(strm, " OUTFILE := $(OUTDIR)/%s", make_escape(outfile));
}
/**
* Write the RESFLAGS configuration variable.
*/
int make_project_config_resflags(Project prj, Stream strm)
{
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(Project prj, Stream strm)
{
/* create the makefile */
const char* filename = make_get_project_makefile(prj);
strm = stream_create_file(filename);
if (!strm)
{
return !OKAY;
}
/* make the stream active for the functions that come after */
session_set_active_stream(project_get_session(prj), strm);
return OKAY;
}
/**
* Include the auto-generated dependencies into the project makefile.
*/
int make_project_include_dependencies(Project prj, Stream strm)
{
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(Project prj, Stream strm)
{
int z = OKAY;
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(Project prj, Stream strm)
{
Strings files;
int i, n, z;
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 \\", make_escape(obj_name));
}
}
z |= stream_writeline(strm, "");
return z;
}
/**
* Write the .PHONY rule for a project.
*/
int make_project_phony_rule(Project prj, Stream strm)
{
int z = OKAY;
UNUSED(prj);
z |= stream_writeline(strm, ".PHONY: clean");
z |= stream_writeline(strm, "");
return z;
}
/**
* Write the RESOURCES project variable.
*/
int make_project_resources(Project prj, Stream strm)
{
int z = OKAY;
UNUSED(prj);
z |= stream_writeline(strm, "RESOURCES := \\");
z |= stream_writeline(strm, "");
return z;
}
/**
* Write the project makefile signature.
*/
int make_project_signature(Project prj, Stream strm)
{
int z = OKAY;
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(Project prj, Stream strm)
{
Strings files;
int i, n, z = OKAY;
files = project_get_files(prj);
n = strings_size(files);
for (i = 0; i < n; ++i)
{
const char* filename = make_escape(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(Project prj, Stream strm)
{
int z = OKAY;
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;
}

View File

@ -1,35 +0,0 @@
/**
* \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 "objects/session.h"
int gmake_project_shell_detect(Project prj, Stream strm);
int make_project_clean_rules(Project prj, Stream strm);
int make_project_config_conditional(Project prj, Stream strm);
int make_project_config_cflags(Project prj, Stream strm);
int make_project_config_cppflags(Project prj, Stream strm);
int make_project_config_cxxflags(Project prj, Stream strm);
int make_project_config_end(Project prj, Stream strm);
int make_project_config_lddeps(Project prj, Stream strm);
int make_project_config_ldflags(Project prj, Stream strm);
int make_project_config_objdir(Project prj, Stream strm);
int make_project_config_outdir(Project prj, Stream strm);
int make_project_config_outfile(Project prj, Stream strm);
int make_project_config_resflags(Project prj, Stream strm);
int make_project_create(Project prj, Stream strm);
int make_project_include_dependencies(Project prj, Stream strm);
int make_project_mkdir_rules(Project prj, Stream strm);
int make_project_objects(Project prj, Stream strm);
int make_project_phony_rule(Project prj, Stream strm);
int make_project_resources(Project prj, Stream strm);
int make_project_signature(Project prj, Stream strm);
int make_project_source_rules(Project prj, Stream strm);
int make_project_target(Project prj, Stream strm);
#endif

View File

@ -1,190 +0,0 @@
/**
* \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/env.h"
#include "base/error.h"
#include "base/path.h"
static const char* make_solution_project_rule(Solution sln, Project prj);
/**
* Write the GNU solution makefile clean rules.
*/
int make_solution_clean_rule(Solution sln, Stream strm)
{
int i, n, z;
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(sln, prj);
z |= stream_writeline(strm, "%s clean", rule);
}
return z;
}
/**
* Write the makefile "all" rule.
*/
int make_solution_all_rule(Solution sln, Stream strm)
{
int z;
Strings prj_names = make_get_project_names(sln);
z = stream_writeline_strings(strm, prj_names, "all:", " ", "", "", "", make_write_escaped);
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.
*/
int make_solution_create(Solution sln, Stream strm)
{
/* create the makefile */
const char* filename = make_get_solution_makefile(sln);
strm = stream_create_file(filename);
if (!strm)
{
return !OKAY;
}
/* make the stream active for the functions that come after */
session_set_active_stream(solution_get_session(sln), strm);
return OKAY;
}
/**
* Write makefile rules to set a default build configuration.
*/
int make_solution_default_config(Solution sln, Stream strm)
{
int z = OKAY;
const char* 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.
*/
int make_solution_phony_rule(Solution sln, Stream strm)
{
int z = OKAY;
Strings prj_names = make_get_project_names(sln);
z |= stream_writeline_strings(strm, prj_names, ".PHONY: all clean", " ", "", "", "", make_write_escaped);
z |= stream_writeline(strm, "");
strings_destroy(prj_names);
return z;
}
/**
* Build the makefile rule to call an individual project.
*/
const char* make_solution_project_rule(Solution sln, Project prj)
{
char* buffer = buffers_next();
/* project file paths are specified relative to the solution */
const char* sln_file_dir = solution_get_location(sln);
const char* prj_file = make_get_project_makefile(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_file_dir, prj_file_dir);
/* build the rule */
strcpy(buffer, "\t@$(MAKE)");
if (!cstr_eq(".", prj_file_dir))
{
strcat(buffer, " --no-print-directory -C ");
strcat(buffer, make_escape(prj_file_dir));
}
if (!cstr_eq("Makefile", prj_file_name))
{
strcat(buffer, " -f ");
strcat(buffer, make_escape(prj_file_name));
}
return buffer;
}
/**
* Write the solution makefile project entries.
*/
int make_solution_projects(Solution sln, Stream strm)
{
int i, n, z = OKAY;
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(sln, prj);
z |= stream_writeline(strm, "%s:", make_escape(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.
*/
int make_solution_signature(Solution sln, Stream strm)
{
const char* file_type;
Strings config_names;
int z;
if (cstr_eq(env_get_action(), "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, "# ", " ", "", ",", "", NULL);
z |= stream_writeline(strm, "");
return z;
}

View File

@ -1,19 +0,0 @@
/**
* \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 "objects/session.h"
int make_solution_clean_rule(Solution sln, Stream strm);
int make_solution_all_rule(Solution sln, Stream strm);
int make_solution_create(Solution sln, Stream strm);
int make_solution_default_config(Solution sln, Stream strm);
int make_solution_phony_rule(Solution sln, Stream strm);
int make_solution_projects(Solution sln, Stream strm);
int make_solution_signature(Solution sln, Stream strm);
#endif

View File

@ -0,0 +1,32 @@
# <%= premake.actions[_ACTION].shortname %> solution makefile autogenerated by Premake
# Usage: make [ CONFIG=config_name ]
# Where {config_name} is one of: <%= table.implode(this.configurations, '"', '"', ', ') %>.
ifndef CONFIG
CONFIG=<%= make.esc(this.configurations[1]) %>
endif
export CONFIG
PROJECTS := <%= table.concat(make.esc(table.extract(this.projects, "name")), " ") %>
.PHONY: all clean $(PROJECTS)
all: $(PROJECTS)
<% for _,prj in ipairs(this.projects) do %>
<% for cfg in premake.project.configs(prj) do %>
ifeq ($(CONFIG),<%= make.esc(cfg.name)%>)
DEPENDENCIES := <%= table.concat(make.esc(premake.project.getdependencies(cfg)), " ") %>
endif
<% end %>
<%= make.esc(prj.name) %>: ${DEPENDENCIES}
@echo ==== Building <%= prj.name %> ====
@${MAKE} --no-print-directory -C <%=make.esc(path.getrelative(this.location, prj.location))%> -f <%=make.esc(make.getmakefilename(prj, true))%>
<% end %>
clean:
<% for _,prj in ipairs(this.projects) do %>
@${MAKE} --no-print-directory -C <%=make.esc(path.getrelative(this.location, prj.location))%> -f <%=make.esc(make.getmakefilename(prj, true))%> clean
<% end %>

View File

@ -1,182 +0,0 @@
/**
* \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 "base/env.h"
}
SUITE(action)
{
/**********************************************************************
* CPPFLAGS tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeCppFlags_Defaults)
{
make_project_config_cppflags(prj, strm);
CHECK_EQUAL(
" CPPFLAGS += -MMD\n",
buffer);
}
TEST_FIXTURE(FxAction, MakeCppFlags_WithDefines)
{
const char* defines[] = { "DEFINE0", "DEFINE1", NULL};
SetConfigField(prj, BlockDefines, defines);
make_project_config_cppflags(prj, strm);
CHECK_EQUAL(
" CPPFLAGS += -MMD -D \"DEFINE0\" -D \"DEFINE1\"\n",
buffer);
}
/**********************************************************************
* CFLAGS tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_Config_CFlags)
{
make_project_config_cflags(prj, strm);
CHECK_EQUAL(
" CFLAGS += $(CPPFLAGS) $(ARCHFLAGS)\n",
buffer);
}
TEST_FIXTURE(FxAction, MakeProject_Config_WithSymbols)
{
const char* flags[] = { "Symbols", NULL };
SetConfigField(prj, BlockFlags, flags);
make_project_config_cflags(prj, strm);
CHECK_EQUAL(
" CFLAGS += $(CPPFLAGS) $(ARCHFLAGS) -g\n",
buffer);
}
TEST_FIXTURE(FxAction, MakeProject_Config_WithOptimize)
{
const char* flags[] = { "Optimize", NULL };
SetConfigField(prj, BlockFlags, flags);
make_project_config_cflags(prj, strm);
CHECK_EQUAL(
" CFLAGS += $(CPPFLAGS) $(ARCHFLAGS) -O2\n",
buffer);
}
TEST_FIXTURE(FxAction, MakeProject_Config_WithOptimizeSize)
{
const char* flags[] = { "OptimizeSize", NULL };
SetConfigField(prj, BlockFlags, flags);
make_project_config_cflags(prj, strm);
CHECK_EQUAL(
" CFLAGS += $(CPPFLAGS) $(ARCHFLAGS) -Os\n",
buffer);
}
TEST_FIXTURE(FxAction, MakeProject_Config_WithOptimizeSpeed)
{
const char* flags[] = { "OptimizeSpeed", NULL };
SetConfigField(prj, BlockFlags, flags);
make_project_config_cflags(prj, strm);
CHECK_EQUAL(
" CFLAGS += $(CPPFLAGS) $(ARCHFLAGS) -O3\n",
buffer);
}
/**********************************************************************
* CXXFLAGS tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_Config_CxxFlags)
{
make_project_config_cxxflags(prj, strm);
CHECK_EQUAL(
" CXXFLAGS += $(CFLAGS)\n",
buffer);
}
/**********************************************************************
* LDDEPS tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_Config_LdDeps)
{
make_project_config_lddeps(prj, strm);
CHECK_EQUAL(
" LDDEPS :=\n",
buffer);
}
/**********************************************************************
* LDFLAGS tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_Config_LdFlags)
{
make_project_config_ldflags(prj, strm);
CHECK_EQUAL(
" LDFLAGS +=\n",
buffer);
}
/**********************************************************************
* OBJDIR tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_Config_ObjDir)
{
make_project_config_objdir(prj, strm);
CHECK_EQUAL(
" OBJDIR := obj/Debug\\ DLL\n",
buffer);
}
/**********************************************************************
* OUTFILE tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_Config_OutFile)
{
env_set_os(MacOSX);
make_project_config_outfile(prj, strm);
CHECK_EQUAL(
" OUTFILE := $(OUTDIR)/My\\ Project\n",
buffer);
}
/**********************************************************************
* OUTDIR tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_Config_OutDir)
{
make_project_config_outdir(prj, strm);
CHECK_EQUAL(
" OUTDIR := .\n",
buffer);
}
/**********************************************************************
* RESFLAGS tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_Config_ResFlags)
{
make_project_config_resflags(prj, strm);
CHECK_EQUAL(
" RESFLAGS +=\n",
buffer);
}
}

View File

@ -1,186 +0,0 @@
/**
* \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 "base/env.h"
}
SUITE(action)
{
/**********************************************************************
* Signature tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_SignatureIsCorrect_OnGmake)
{
env_set_action("gmake");
make_project_signature(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(prj, strm);
CHECK_EQUAL(
"ifeq ($(CONFIG),Debug DLL)\n",
buffer);
}
TEST_FIXTURE(FxAction, MakeProject_Config_End)
{
make_project_config_end(prj, strm);
CHECK_EQUAL(
"endif\n"
"\n",
buffer);
}
/**********************************************************************
* Object file list tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_Objects_ConvertsFileExtension)
{
const char* files[] = { "Hello.cpp", "Good Bye.cpp", NULL };
SetField(prj, ProjectFiles, files);
make_project_objects(prj, strm);
CHECK_EQUAL(
"OBJECTS := \\\n"
"\t$(OBJDIR)/Hello.o \\\n"
"\t$(OBJDIR)/Good\\ Bye.o \\\n"
"\n",
buffer);
}
/**********************************************************************
* Resource file list tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_Resources)
{
make_project_resources(prj, strm);
CHECK_EQUAL(
"RESOURCES := \\\n"
"\n",
buffer);
}
/**********************************************************************
* .PHONY rule tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_PhonyRule)
{
make_project_phony_rule(prj, strm);
CHECK_EQUAL(
".PHONY: clean\n"
"\n",
buffer);
}
/**********************************************************************
* Output target tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_OutputTarget)
{
make_project_target(prj, strm);
CHECK_EQUAL(
"$(OUTFILE): $(OUTDIR) $(OBJDIR) $(OBJECTS) $(LDDEPS) $(RESOURCES)\n"
"\t@echo Linking My Project\n"
"\t@$(CXX) -o $@ $(LDFLAGS) $(ARCHFLAGS) $(OBJECTS) $(RESOURCES)\n"
"\n",
buffer);
}
/**********************************************************************
* Directory creation rules
**********************************************************************/
TEST_FIXTURE(FxAction, MakeProject_MkdirRules)
{
make_project_mkdir_rules(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(prj, strm);
CHECK_EQUAL(
"clean:\n"
"\t@echo Cleaning My Project\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)
{
const char* files[] = { "Good Bye.cpp", NULL };
SetField(prj, ProjectFiles, files);
make_project_source_rules(prj, strm);
CHECK_EQUAL(
"$(OBJDIR)/Good\\ Bye.o: Good\\ Bye.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(prj, strm);
CHECK_EQUAL(
"-include $(OBJECTS:%.o=%.d)\n",
buffer);
}
}

View File

@ -1,123 +0,0 @@
/**
* \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"
#include "base/env.h"
}
SUITE(action)
{
/**********************************************************************
* Signature tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeSolution_SignatureIsCorrect_OnGmake)
{
env_set_action("gmake");
make_solution_signature(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 DLL, Release DLL\n"
"\n",
buffer);
}
/**********************************************************************
* Default configuration tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeSolution_DefaultConfigIsCorrect)
{
make_solution_default_config(sln, strm);
CHECK_EQUAL(
"ifndef CONFIG\n"
" CONFIG=Debug DLL\n"
"endif\n"
"export CONFIG\n"
"\n",
buffer);
}
/**********************************************************************
* Phony rule tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeSolution_PhonyRuleIsCorrect)
{
make_solution_phony_rule(sln, strm);
CHECK_EQUAL(
".PHONY: all clean My\\ Project\n"
"\n",
buffer);
}
/**********************************************************************
* All rule tests
**********************************************************************/
TEST_FIXTURE(FxAction, MakeSolution_AllRuleIsCorrect)
{
make_solution_all_rule(sln, strm);
CHECK_EQUAL(
"all: My\\ Project\n"
"\n",
buffer);
}
/**********************************************************************
* Project entry tests
**********************************************************************/
TEST_FIXTURE(FxAction, Make_ProjectEntry_InSameDirectory)
{
project_set_location(prj, solution_get_location(sln));
make_solution_projects(sln, strm);
CHECK_EQUAL(
"My\\ Project:\n"
"\t@echo ==== Building My Project ====\n"
"\t@$(MAKE) -f My\\ Project.make\n"
"\n",
buffer);
}
TEST_FIXTURE(FxAction, Make_ProjectEntry_InDifferentDirectory)
{
project_set_location(prj, "Root Folder/Solution Folder/My Project");
make_solution_projects(sln, strm);
CHECK_EQUAL(
"My\\ Project:\n"
"\t@echo ==== Building My Project ====\n"
"\t@$(MAKE) --no-print-directory -C My\\ Project\n"
"\n",
buffer);
}
/**********************************************************************
* Clean rule tests
**********************************************************************/
TEST_FIXTURE(FxAction, Gmake_CleanRule_IsCorrect)
{
project_set_location(prj, solution_get_location(sln));
make_solution_clean_rule(sln, strm);
CHECK_EQUAL(
"clean:\n"
"\t@$(MAKE) -f My\\ Project.make clean\n",
buffer);
}
}

View File

@ -1,98 +0,0 @@
/**
* \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_location(sln, ".");
return sln;
}
Project AddProject(const char* name)
{
Project prj = project_create();
solution_add_project(sln1, prj);
project_set_name(prj, name);
project_set_location(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(sln1);
CHECK_EQUAL("./MySolution/Makefile", result);
}
TEST_FIXTURE(FxMake, GetSolutionMakefile_ReturnsDotMake_OnSharedLocation)
{
const char* result = make_get_solution_makefile(sln1);
CHECK_EQUAL("./MySolution1.make", result);
}
TEST_FIXTURE(FxMake, GetProjectMakefile_ReturnsMakefile_OnUniqueLocation)
{
project_set_location(prj1, "./MyProject");
const char* result = make_get_project_makefile(prj1);
CHECK_EQUAL("./MyProject/Makefile", result);
}
TEST_FIXTURE(FxMake, GetProjectMakefile_ReturnsDotMake_OnSharedWithSolution)
{
project_set_location(prj2, "./MyProject");
const char* result = make_get_project_makefile(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(prj1);
CHECK_EQUAL("./MyProject/MyProject1.make", result);
}
}

View File

@ -1,107 +0,0 @@
/**
* \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(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 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(Project prj, Stream strm, SourceTreeCallback handler)
{
return sourcetree_do(prj, strm, handler, "");
}
static int sourcetree_do(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(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(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(prj, strm, filename, SourceFile) != OKAY)
return !OKAY;
}
}
/* close the group */
buffer = buffers_next();
strcpy(buffer, group);
cstr_trim(buffer, '/');
handler(prj, strm, buffer, GroupEnd);
return OKAY;
}

View File

@ -1,37 +0,0 @@
/**
* \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 "objects/project.h"
/**
* State values for the source tree enumeration functions.
*/
enum SourceTreeState
{
GroupStart,
GroupEnd,
SourceFile
};
/**
* Per-file callback signature for action_source_tree.
* \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)(Project prj, Stream strm, const char* filename, int state);
int sourcetree_walk(Project prj, Stream strm, SourceTreeCallback handler);
#endif

View File

@ -1,78 +0,0 @@
/**
* \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 "objects/session.h"
}
struct FxAction
{
Session sess;
Stream strm;
Solution sln;
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, "My Solution");
solution_set_base_dir(sln, "Root Folder");
solution_set_location(sln, "Root Folder/Solution Folder");
solution_add_config(sln, "Debug DLL");
solution_add_config(sln, "Release DLL");
prj = project_create();
solution_add_project(sln, prj);
project_set_name(prj, "My Project");
project_set_base_dir(prj, "Root Folder");
project_set_location(prj, "Root Folder/Project Folder");
project_set_guid(prj, "AE2461B7-236F-4278-81D3-F0D476F9A4C0");
project_set_language(prj, "c++");
project_set_config(prj, "Debug DLL");
}
~FxAction()
{
stream_destroy(strm);
session_destroy(sess);
}
void SetField(Project prj, ProjectField index, const char** values)
{
Strings strs = strings_create();
for (const char** value = values; (*value) != NULL; ++value)
{
strings_add(strs, *value);
}
project_set_values(prj, index, strs);
}
void SetConfigField(Project prj, BlockField index, const char** values)
{
Strings strs = strings_create();
for (const 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);
}
};

View File

@ -1,108 +0,0 @@
/**
* \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(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(sln, strm);
CHECK_EQUAL(
"Project(\"{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}\") = \"My Project\", \"..\\Project Folder\\My Project.vcproj\", \"{AE2461B7-236F-4278-81D3-F0D476F9A4C0}\"\n"
"EndProject\n",
buffer);
}
/**********************************************************************
* Solution configuration tests
**********************************************************************/
TEST_FIXTURE(FxAction, Vs2002_SolutionConfiguration_IsCorrect)
{
vs2002_solution_configuration(sln, strm);
CHECK_EQUAL(
"Global\n"
"\tGlobalSection(SolutionConfiguration) = preSolution\n"
"\t\tConfigName.0 = Debug DLL\n"
"\t\tConfigName.1 = Release DLL\n"
"\tEndGlobalSection\n",
buffer);
}
/**********************************************************************
* Project dependencies tests
**********************************************************************/
TEST_FIXTURE(FxAction, Vs2002_ProjectDependencies_IsCorrect)
{
vs2002_solution_dependencies(sln, strm);
CHECK_EQUAL(
"\tGlobalSection(ProjectDependencies) = postSolution\n"
"\tEndGlobalSection\n",
buffer);
}
/**********************************************************************
* Project configuration tests
**********************************************************************/
TEST_FIXTURE(FxAction, Vs2002_ProjectConfiguration_IsCorrect)
{
vs2002_solution_project_configuration(sln, strm);
CHECK_EQUAL(
"\tGlobalSection(ProjectConfiguration) = postSolution\n"
"\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug DLL.ActiveCfg = Debug DLL|Win32\n"
"\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug DLL.Build.0 = Debug DLL|Win32\n"
"\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release DLL.ActiveCfg = Release DLL|Win32\n"
"\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release DLL.Build.0 = Release DLL|Win32\n"
"\tEndGlobalSection\n",
buffer);
}
/**********************************************************************
* Solution extensibility tests
**********************************************************************/
TEST_FIXTURE(FxAction, Vs2002_Extensibility_IsCorrect)
{
vs2002_solution_extensibility(sln, strm);
CHECK_EQUAL(
"\tGlobalSection(ExtensibilityGlobals) = postSolution\n"
"\tEndGlobalSection\n"
"\tGlobalSection(ExtensibilityAddIns) = postSolution\n"
"\tEndGlobalSection\n"
"EndGlobal\n",
buffer);
}
}

View File

@ -1,45 +0,0 @@
/**
* \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(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(sln, strm);
CHECK_EQUAL(
"Global\n"
"\tGlobalSection(SolutionConfiguration) = preSolution\n"
"\t\tDebug DLL = Debug DLL\n"
"\t\tRelease DLL = Release DLL\n"
"\tEndGlobalSection\n",
buffer);
}
}

View File

@ -1,80 +0,0 @@
/**
* \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(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(sln, strm);
CHECK_EQUAL(
"Global\n"
"\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n"
"\t\tDebug DLL|Win32 = Debug DLL|Win32\n"
"\t\tRelease DLL|Win32 = Release DLL|Win32\n"
"\tEndGlobalSection\n",
buffer);
}
/**********************************************************************
* Project Configuration Platforms tests
**********************************************************************/
TEST_FIXTURE(FxAction, ProjectPlatforms_IsCorrect)
{
vs2005_solution_project_platforms(sln, strm);
CHECK_EQUAL(
"\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n"
"\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug DLL|Win32.ActiveCfg = Debug DLL|Win32\n"
"\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Debug DLL|Win32.Build.0 = Debug DLL|Win32\n"
"\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release DLL|Win32.ActiveCfg = Release DLL|Win32\n"
"\t\t{AE2461B7-236F-4278-81D3-F0D476F9A4C0}.Release DLL|Win32.Build.0 = Release DLL|Win32\n"
"\tEndGlobalSection\n",
buffer);
}
/**********************************************************************
* Solution Project tests
**********************************************************************/
TEST_FIXTURE(FxAction, Properties_IsCorrect)
{
vs2005_solution_properties(sln, strm);
CHECK_EQUAL(
"\tGlobalSection(SolutionProperties) = preSolution\n"
"\t\tHideSolutionNode = FALSE\n"
"\tEndGlobalSection\n"
"EndGlobal\n",
buffer);
}
}

View File

@ -1,30 +0,0 @@
/**
* \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(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);
}
}

View File

@ -1,102 +0,0 @@
/**
* \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"
#include "base/env.h"
}
SUITE(action)
{
/**********************************************************************
* Default settings
**********************************************************************/
TEST_FIXTURE(FxAction, VCCLCompilerTool_Defaults_OnVs2002)
{
env_set_action("vs2002");
vs200x_project_vc_cl_compiler_tool(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=\"0\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, VCCLCompilerTool_Defaults_OnVs2005)
{
env_set_action("vs2005");
vs200x_project_vc_cl_compiler_tool(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=\"0\"\n"
"\t\t\t/>\n",
buffer);
}
TEST_FIXTURE(FxAction, VCCLCompilerTool_Defaults_OnVs2008)
{
env_set_action("vs2008");
vs200x_project_vc_cl_compiler_tool(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=\"0\"\n"
"\t\t\t/>\n",
buffer);
}
/**********************************************************************
* Defines tests
**********************************************************************/
TEST_FIXTURE(FxAction, VCCLCompilerTool_WithDefines)
{
env_set_action("vs2002");
const char* defines[] = { "DEFINE0", "DEFINE1", NULL };
SetConfigField(prj, BlockDefines, defines);
vs200x_project_vc_cl_compiler_tool(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=\"0\"/>\n",
buffer);
}
}

View File

@ -1,192 +0,0 @@
/**
* \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"
#include "base/env.h"
}
SUITE(action)
{
/*************************************************************************
* Character set tests
*************************************************************************/
TEST_FIXTURE(FxAction, VsCharacterSet_Defaults_OnVs2002)
{
env_set_action("vs2002");
vs200x_config_character_set(strm);
CHECK_EQUAL("\n\t\t\tCharacterSet=\"2\"", buffer);
}
TEST_FIXTURE(FxAction, VsCharacterSet_Defaults_OnVs2003)
{
env_set_action("vs2003");
vs200x_config_character_set(strm);
CHECK_EQUAL("\n\t\t\tCharacterSet=\"2\"", buffer);
}
TEST_FIXTURE(FxAction, VsCharacterSet_Defaults_OnVs2005)
{
env_set_action("vs2005");
vs200x_config_character_set(strm);
CHECK_EQUAL("\n\t\t\tCharacterSet=\"1\"", buffer);
}
TEST_FIXTURE(FxAction, VsCharacterSet_Defaults_OnVs2008)
{
env_set_action("vs2008");
vs200x_config_character_set(strm);
CHECK_EQUAL("\n\t\t\tCharacterSet=\"1\"", buffer);
}
/*************************************************************************
* Debug information tests
*************************************************************************/
TEST_FIXTURE(FxAction, VsDebugFormat_Is0_OnNoSymbols)
{
env_set_action("vs2002");
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"0\"", buffer);
}
TEST_FIXTURE(FxAction, VsDebugFormat_Is4_OnSymbols)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"4\"", buffer);
}
TEST_FIXTURE(FxAction, VsDebugFormat_Is3_OnSymbolsAndManaged)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", "Managed", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"3\"", buffer);
}
TEST_FIXTURE(FxAction, VsDebugFormat_Is3_OnSymbolsAndOptimize)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", "Optimize", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"3\"", buffer);
}
TEST_FIXTURE(FxAction, VsDebugFormat_Is3_OnSymbolsAndOptimizeSize)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", "OptimizeSize", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"3\"", buffer);
}
TEST_FIXTURE(FxAction, VsDebugFormat_Is3_OnSymbolsAndOptimizeSpeed)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", "OptimizeSpeed", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"3\"", buffer);
}
TEST_FIXTURE(FxAction, VsDebugFormat_Is3_OnSymbolsAndNoEditAndContinue)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", "NoEditAndContinue", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_debug_information_format(prj, strm);
CHECK_EQUAL("\n\t\t\t\tDebugInformationFormat=\"3\"", buffer);
}
TEST_FIXTURE(FxAction, VCDebugInfo_IsOff_WithNoSymbols)
{
env_set_action("vs2002");
vs200x_config_generate_debug_information(prj, strm);
CHECK_EQUAL("\n\t\t\t\tGenerateDebugInformation=\"FALSE\"", buffer);
}
TEST_FIXTURE(FxAction, VCDebugInfo_IsOn_WithSymbols)
{
env_set_action("vs2002");
const char* flags[] = { "Symbols", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_generate_debug_information(prj, strm);
CHECK_EQUAL(
"\n\t\t\t\tGenerateDebugInformation=\"TRUE\""
"\n\t\t\t\tProgramDatabaseFile=\"$(OutDir)/My Project.pdb\"",
buffer);
}
/*************************************************************************
* Defines tests
*************************************************************************/
TEST_FIXTURE(FxAction, VsDefines_Empty_OnNoSymbols)
{
env_set_action("vs2002");
vs200x_config_defines(prj, strm);
CHECK_EQUAL("", buffer);
}
TEST_FIXTURE(FxAction, VsDefines_SemiSplitList)
{
env_set_action("vs2002");
const char* values[] = { "DEFINE0", "DEFINE1", "DEFINE2", NULL };
SetConfigField(prj, BlockDefines, values);
vs200x_config_defines(prj, strm);
CHECK_EQUAL("\n\t\t\t\tPreprocessorDefinitions=\"DEFINE0;DEFINE1;DEFINE2\"", buffer);
}
/*************************************************************************
* Optimization tests
*************************************************************************/
TEST_FIXTURE(FxAction, VsOptimization_Is0_OnNoOptimization)
{
env_set_action("vs2002");
vs200x_config_optimization(prj, strm);
CHECK_EQUAL("\n\t\t\t\tOptimization=\"0\"", buffer);
}
TEST_FIXTURE(FxAction, VsOptimization_Is1_OnOptimizeSize)
{
env_set_action("vs2002");
const char* flags[] = { "OptimizeSize", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_optimization(prj, strm);
CHECK_EQUAL("\n\t\t\t\tOptimization=\"1\"", buffer);
}
TEST_FIXTURE(FxAction, VsOptimization_Is2_OnOptimizeSpeed)
{
env_set_action("vs2002");
const char* flags[] = { "OptimizeSpeed", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_optimization(prj, strm);
CHECK_EQUAL("\n\t\t\t\tOptimization=\"2\"", buffer);
}
TEST_FIXTURE(FxAction, VsOptimization_Is2_OnOptimize)
{
env_set_action("vs2002");
const char* flags[] = { "Optimize", NULL };
SetConfigField(prj, BlockFlags, flags);
vs200x_config_optimization(prj, strm);
CHECK_EQUAL("\n\t\t\t\tOptimization=\"3\"", buffer);
}
}

View File

@ -1,81 +0,0 @@
/**
* \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"
#include "base/env.h"
}
SUITE(action)
{
/**********************************************************************
* Default settings
**********************************************************************/
TEST_FIXTURE(FxAction, VCLinkerTool_Defaults_OnVs2002)
{
env_set_action("vs2002");
vs200x_project_vc_linker_tool(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=\"FALSE\"\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)
{
env_set_action("vs2003");
vs200x_project_vc_linker_tool(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=\"FALSE\"\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)
{
env_set_action("vs2005");
vs200x_project_vc_linker_tool(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=\"false\"\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)
{
env_set_action("vs2008");
vs200x_project_vc_linker_tool(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=\"false\"\n"
"\t\t\t\tSubSystem=\"1\"\n"
"\t\t\t\tEntryPointSymbol=\"mainCRTStartup\"\n"
"\t\t\t\tTargetMachine=\"1\"\n"
"\t\t\t/>\n",
buffer);
}
}

View File

@ -1,468 +0,0 @@
/**
* \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"
#include "base/env.h"
}
SUITE(action)
{
/**********************************************************************
* Encoding tests
**********************************************************************/
TEST_FIXTURE(FxAction, Vs200x_Encoding)
{
vs200x_project_encoding(prj, strm);
CHECK_EQUAL(
"<?xml version=\"1.0\" encoding=\"Windows-1252\"?>\r\n",
buffer);
}
/**********************************************************************
* Project element tests
**********************************************************************/
TEST_FIXTURE(FxAction, VsProject_OnVs2002)
{
env_set_action("vs2002");
vs200x_project_element(prj, strm);
CHECK_EQUAL(
"<VisualStudioProject\n"
"\tProjectType=\"Visual C++\"\n"
"\tVersion=\"7.00\"\n"
"\tName=\"My Project\"\n"
"\tProjectGUID=\"{AE2461B7-236F-4278-81D3-F0D476F9A4C0}\"\n"
"\tKeyword=\"Win32Proj\">\n",
buffer);
}
TEST_FIXTURE(FxAction, VsProject_OnVs2003)
{
env_set_action("vs2003");
vs200x_project_element(prj, strm);
CHECK_EQUAL(
"<VisualStudioProject\n"
"\tProjectType=\"Visual C++\"\n"
"\tVersion=\"7.10\"\n"
"\tName=\"My Project\"\n"
"\tProjectGUID=\"{AE2461B7-236F-4278-81D3-F0D476F9A4C0}\"\n"
"\tKeyword=\"Win32Proj\">\n",
buffer);
}
TEST_FIXTURE(FxAction, VsProject_OnVs2005)
{
env_set_action("vs2005");
vs200x_project_element(prj, strm);
CHECK_EQUAL(
"<VisualStudioProject\n"
"\tProjectType=\"Visual C++\"\n"
"\tVersion=\"8.00\"\n"
"\tName=\"My Project\"\n"
"\tProjectGUID=\"{AE2461B7-236F-4278-81D3-F0D476F9A4C0}\"\n"
"\tRootNamespace=\"MyProject\"\n"
"\tKeyword=\"Win32Proj\"\n"
"\t>\n",
buffer);
}
TEST_FIXTURE(FxAction, VsProject_OnVs2008)
{
env_set_action("vs2008");
vs200x_project_element(prj, strm);
CHECK_EQUAL(
"<VisualStudioProject\n"
"\tProjectType=\"Visual C++\"\n"
"\tVersion=\"9.00\"\n"
"\tName=\"My Project\"\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)
{
env_set_action("vs2002");
vs200x_project_platforms(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)
{
env_set_action("vs2002");
vs200x_project_tool_files(prj, strm);
CHECK_EQUAL(
"\t<Configurations>\n",
buffer);
}
TEST_FIXTURE(FxAction, VsToolFiles_Defaults_OnVs2003)
{
env_set_action("vs2003");
vs200x_project_tool_files(prj, strm);
CHECK_EQUAL(
"\t<Configurations>\n",
buffer);
}
TEST_FIXTURE(FxAction, VsToolFiles_Defaults_OnVs2005)
{
env_set_action("vs2005");
vs200x_project_tool_files(prj, strm);
CHECK_EQUAL(
"\t<ToolFiles>\n"
"\t</ToolFiles>\n"
"\t<Configurations>\n",
buffer);
}
TEST_FIXTURE(FxAction, VsToolFiles_Defaults_OnVs2008)
{
env_set_action("vs2008");
vs200x_project_tool_files(prj, strm);
CHECK_EQUAL(
"\t<ToolFiles>\n"
"\t</ToolFiles>\n"
"\t<Configurations>\n",
buffer);
}
/**********************************************************************
* Configuration element tests
**********************************************************************/
TEST_FIXTURE(FxAction, Vs200x_Configuration)
{
env_set_action("vs2002");
vs200x_project_config_element(prj, strm);
CHECK_EQUAL(
"\t\t<Configuration\n"
"\t\t\tName=\"Debug DLL|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)
{
env_set_action("vs2002");
vs200x_project_vc_alink_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCALinkTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCAppVerifierTool)
{
env_set_action("vs2002");
vs200x_project_vc_app_verifier_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCAppVerifierTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCBscMakeTool)
{
env_set_action("vs2002");
vs200x_project_vc_bsc_make_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCBscMakeTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCCustomBuildTool)
{
env_set_action("vs2002");
vs200x_project_vc_custom_build_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCCustomBuildTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCFxCopTool)
{
env_set_action("vs2002");
vs200x_project_vc_fx_cop_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCFxCopTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCManagedResourceCompilerTool)
{
env_set_action("vs2002");
vs200x_project_vc_managed_resource_compiler_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCManagedResourceCompilerTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCManifestTool)
{
env_set_action("vs2002");
vs200x_project_vc_manifest_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCManifestTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCMIDLTool)
{
env_set_action("vs2002");
vs200x_project_vc_midl_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCMIDLTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCPreBuildEventTool)
{
env_set_action("vs2002");
vs200x_project_vc_pre_build_event_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCPreBuildEventTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCPreLinkEventTool)
{
env_set_action("vs2002");
vs200x_project_vc_pre_link_event_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCPreLinkEventTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCPostBuildEventTool)
{
env_set_action("vs2002");
vs200x_project_vc_post_build_event_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCPostBuildEventTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCResourceCompilerTool)
{
env_set_action("vs2002");
vs200x_project_vc_resource_compiler_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCResourceCompilerTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCWebDeploymentTool)
{
env_set_action("vs2002");
vs200x_project_vc_web_deployment_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCWebDeploymentTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCWebServiceProxyGeneratorTool)
{
env_set_action("vs2002");
vs200x_project_vc_web_service_proxy_generator_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCWebServiceProxyGeneratorTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCXDCMakeTool)
{
env_set_action("vs2002");
vs200x_project_vc_xdc_make_tool(prj, strm);
CHECK_EQUAL(
"\t\t\t<Tool\n"
"\t\t\t\tName=\"VCXDCMakeTool\"/>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_VCXMLDataGeneratorTool)
{
env_set_action("vs2002");
vs200x_project_vc_xml_data_generator_tool(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)
{
env_set_action("vs2002");
vs200x_project_references(prj, strm);
CHECK_EQUAL(
"\t</Configurations>\n",
buffer);
}
TEST_FIXTURE(FxAction, VsReferences_Defaults_OnVs2003)
{
env_set_action("vs2003");
vs200x_project_references(prj, strm);
CHECK_EQUAL(
"\t</Configurations>\n"
"\t<References>\n"
"\t</References>\n",
buffer);
}
TEST_FIXTURE(FxAction, VsReferences_Defaults_OnVs2005)
{
env_set_action("vs2005");
vs200x_project_references(prj, strm);
CHECK_EQUAL(
"\t</Configurations>\n"
"\t<References>\n"
"\t</References>\n",
buffer);
}
TEST_FIXTURE(FxAction, VsReferences_Defaults_OnVs2008)
{
env_set_action("vs2008");
vs200x_project_references(prj, strm);
CHECK_EQUAL(
"\t</Configurations>\n"
"\t<References>\n"
"\t</References>\n",
buffer);
}
/**********************************************************************
* Files section tests
**********************************************************************/
TEST_FIXTURE(FxAction, Vs200x_Files_OnNoFiles)
{
env_set_action("vs2002");
vs200x_project_files(prj, strm);
CHECK_EQUAL(
"\t<Files>\n"
"\t</Files>\n",
buffer);
}
TEST_FIXTURE(FxAction, Vs200x_Files_OnSingleCppFile)
{
env_set_action("vs2002");
const char* values[] = { "Hello.cpp", 0 };
SetField(prj, ProjectFiles, values);
vs200x_project_files(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)
{
env_set_action("vs2002");
const char* values[] = { "../../Hello.cpp", 0 };
SetField(prj, ProjectFiles, values);
vs200x_project_files(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)
{
env_set_action("vs2002");
const char* values[] = { "Src/Hello.cpp", 0 };
SetField(prj, ProjectFiles, values);
vs200x_project_files(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)
{
env_set_action("vs2002");
vs200x_project_globals(prj, strm);
CHECK_EQUAL(
"\t<Globals>\n"
"\t</Globals>\n"
"</VisualStudioProject>\n",
buffer);
}
}

View File

@ -1,56 +0,0 @@
/**
* \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);
}
}

View File

@ -1,121 +0,0 @@
/**
* \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"
#include "base/env.h"
}
SUITE(action)
{
/**********************************************************************
* Element end tests
**********************************************************************/
TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2002)
{
env_set_action("vs2002");
vs200x_element_end(strm, 0, "/>");
CHECK_EQUAL("/>\n", buffer);
}
TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2003)
{
env_set_action("vs2003");
vs200x_element_end(strm, 0, "/>");
CHECK_EQUAL("/>\n", buffer);
}
TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2005)
{
env_set_action("vs2005");
vs200x_element_end(strm, 0, "/>");
CHECK_EQUAL("\n/>\n", buffer);
}
TEST_FIXTURE(FxAction, ElementEnd_SlashBracket_Vs2008)
{
env_set_action("vs2008");
vs200x_element_end(strm, 0, "/>");
CHECK_EQUAL("\n/>\n", buffer);
}
TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2002)
{
env_set_action("vs2002");
vs200x_element_end(strm, 0, ">");
CHECK_EQUAL(">\n", buffer);
}
TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2003)
{
env_set_action("vs2003");
vs200x_element_end(strm, 0, ">");
CHECK_EQUAL(">\n", buffer);
}
TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2005)
{
env_set_action("vs2005");
vs200x_element_end(strm, 0, ">");
CHECK_EQUAL("\n\t>\n", buffer);
}
TEST_FIXTURE(FxAction, ElementEnd_Bracket_Vs2008)
{
env_set_action("vs2008");
vs200x_element_end(strm, 0, ">");
CHECK_EQUAL("\n\t>\n", buffer);
}
/**********************************************************************
* Attribute tests
**********************************************************************/
TEST_FIXTURE(FxAction, Attribute_OnLevel0)
{
env_set_action("vs2002");
vs200x_attribute(strm, 0, "ProjectType", "Visual C++");
CHECK_EQUAL("\nProjectType=\"Visual C++\"", buffer);
}
TEST_FIXTURE(FxAction, Attribute_OnLevel3)
{
env_set_action("vs2002");
vs200x_attribute(strm, 3, "ProjectType", "Visual C++");
CHECK_EQUAL("\n\t\t\tProjectType=\"Visual C++\"", buffer);
}
TEST_FIXTURE(FxAction, Attribute_IsEscaped)
{
env_set_action("vs2002");
vs200x_attribute(strm, 1, "PreprocessorSymbols", "DEBUG;MSG=\"Hello\";TRACE");
CHECK_EQUAL("\n\tPreprocessorSymbols=\"DEBUG;MSG=&quot;Hello&quot;;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=&quot;Hello&quot;;VALUE2\"", buffer);
strings_destroy(strs);
}
}

View File

@ -1,85 +0,0 @@
/**
* \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);
}

View File

@ -1,130 +0,0 @@
/**
* \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.
*/
int vs2002_solution_configuration(Solution sln, Stream strm)
{
int i, n, z;
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.
*/
int vs2002_solution_dependencies(Solution sln, Stream strm)
{
int z;
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.
*/
int vs2002_solution_extensibility(Solution sln, Stream strm)
{
int z;
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.
*/
int vs2002_solution_project_configuration(Solution sln, Stream strm)
{
int pi, pn, z;
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.
*/
int vs2002_solution_projects(Solution sln, Stream strm)
{
int i, n, z = OKAY;
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_relative(prj, prj_name, prj_ext);
const char* tool_id = vs200x_tool_guid(prj_lang);
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.
*/
int vs2002_solution_signature(Solution sln, Stream strm)
{
int z;
UNUSED(sln);
stream_set_newline(strm, "\r\n");
z = stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 7.00");
return z;
}

View File

@ -1,84 +0,0 @@
/**
* \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);
}

View File

@ -1,45 +0,0 @@
/**
* \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.
*/
int vs2003_solution_configuration(Solution sln, Stream strm)
{
int i, n, z;
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.
*/
int vs2003_solution_signature(Solution sln, Stream strm)
{
int z;
UNUSED(sln);
stream_set_newline(strm, "\r\n");
z = stream_writeline(strm, "Microsoft Visual Studio Solution File, Format Version 8.00");
return z;
}

View File

@ -1,92 +0,0 @@
/**
* \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);
}

View File

@ -1,90 +0,0 @@
/**
* \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.
*/
int vs2005_solution_platforms(Solution sln, Stream strm)
{
int i, n, z;
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.
*/
int vs2005_solution_project_platforms(Solution sln, Stream strm)
{
int pi, pn, z;
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.
*/
int vs2005_solution_properties(Solution sln, Stream strm)
{
int z;
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.
*/
int vs2005_solution_signature(Solution sln, Stream strm)
{
int z;
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;
}

View File

@ -1,91 +0,0 @@
/**
* \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);
}

View File

@ -1,24 +0,0 @@
/**
* \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.
*/
int vs2008_solution_signature(Solution sln, Stream strm)
{
int z;
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;
}

View File

@ -1,190 +0,0 @@
/**
* \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/env.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 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(Stream strm, int level, const char* markup)
{
int z, version;
version = vs200x_get_target_version();
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(void)
{
int version = vs200x_get_target_version();
return (version < 2005) ? "FALSE" : "false";
}
/**
* Converts the session action string to a Visual Studio version number.
* \returns The Visual Studio version number corresponding to the current action.
*/
int vs200x_get_target_version(void)
{
const char* action = env_get_action();
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(void)
{
int version = vs200x_get_target_version();
return (version < 2005) ? "TRUE" : "true";
}

View File

@ -1,22 +0,0 @@
/**
* \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 "objects/project.h"
#include "base/stream.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(Stream strm, int level, const char* markup);
const char* vs200x_false(void);
int vs200x_get_target_version(void);
const char* vs200x_project_file_extension(Project prj);
const char* vs200x_tool_guid(const char* language);
const char* vs200x_true(void);
#endif

View File

@ -1,120 +0,0 @@
/**
* \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(Stream strm)
{
return vs200x_attribute(strm, 3, "CharacterSet", vs200x_get_target_version() > 2003 ? "1" : "2");
}
int vs200x_config_debug_information_format(Project prj, Stream strm)
{
const char* value;
if (!project_has_flag(prj, "Symbols"))
{
value = "0";
}
else if (project_has_flag(prj, "Managed") ||
project_has_flag(prj, "Optimize") ||
project_has_flag(prj, "OptimizeSize") ||
project_has_flag(prj, "OptimizeSpeed") ||
project_has_flag(prj, "NoEditAndContinue"))
{
value = "3";
}
else
{
value = "4";
}
return vs200x_attribute(strm, 4, "DebugInformationFormat", value);
}
/**
* 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(Project prj, Stream strm)
{
Strings values = project_get_config_values(prj, BlockDefines);
if (strings_size(values) > 0)
{
return vs200x_list_attribute(strm, 4, "PreprocessorDefinitions", values);
}
return OKAY;
}
int vs200x_config_detect_64bit_portability(Stream strm)
{
if (vs200x_get_target_version() < 2008)
{
return vs200x_attribute(strm, 4, "Detect64BitPortabilityProblems", vs200x_true());
}
return OKAY;
}
int vs200x_config_generate_debug_information(Project prj, Stream strm)
{
int z = OKAY;
if (project_has_flag(prj, "Symbols"))
{
z |= vs200x_attribute(strm, 4, "GenerateDebugInformation", vs200x_true());
z |= vs200x_attribute(strm, 4, "ProgramDatabaseFile", "$(OutDir)/%s.pdb", project_get_name(prj));
}
else
{
z |= vs200x_attribute(strm, 4, "GenerateDebugInformation", vs200x_false());
}
return z;
}
int vs200x_config_optimization(Project prj, Stream strm)
{
const char* value;
if (project_has_flag(prj, "Optimize"))
{
value = "3";
}
else if (project_has_flag(prj, "OptimizeSize"))
{
value= "1";
}
else if (project_has_flag(prj, "OptimizeSpeed"))
{
value = "2";
}
else
{
value = "0";
}
return vs200x_attribute(strm, 4, "Optimization", value);
}
int vs200x_config_runtime_type_info(Stream strm)
{
if (vs200x_get_target_version() < 2005)
{
return vs200x_attribute(strm, 4, "RuntimeTypeInfo", vs200x_true());
}
return OKAY;
}
int vs200x_config_use_precompiled_header(Stream strm)
{
return vs200x_attribute(strm, 4, "UsePrecompiledHeader", vs200x_get_target_version() > 2003 ? "0" : "2");
}

View File

@ -1,18 +0,0 @@
/**
* \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
int vs200x_config_character_set(Stream strm);
int vs200x_config_debug_information_format(Project prj, Stream strm);
int vs200x_config_defines(Project prj, Stream strm);
int vs200x_config_detect_64bit_portability(Stream strm);
int vs200x_config_generate_debug_information(Project prj, Stream strm);
int vs200x_config_optimization(Project prj, Stream strm);
int vs200x_config_runtime_type_info(Stream strm);
int vs200x_config_use_precompiled_header(Stream strm);
#endif

View File

@ -1,472 +0,0 @@
/**
* \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(Project prj, Stream strm)
{
int z = OKAY;
const char* cfg_name = project_get_config(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(strm);
z |= vs200x_element_end(strm, 2, ">");
return z;
}
/**
* Write the closing [Configuration] element.
*/
int vs200x_project_config_end(Project prj, Stream strm)
{
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(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(project_get_session(prj), strm);
return OKAY;
}
/**
* Write the root [VisualStudioProject] element and attributes.
*/
int vs200x_project_element(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();
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", cstr_to_identifier(prj_name));
}
z |= vs200x_attribute(strm, 1, "Keyword", "Win32Proj");
if (version > 2005)
{
z |= vs200x_attribute(strm, 1, "TargetFrameworkVersion", "196613");
}
z |= vs200x_element_end(strm, 0, ">");
return z;
}
/**
* Write the file encoding at the start of the project file.
*/
int vs200x_project_encoding(Project prj, Stream strm)
{
int z;
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 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(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(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(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(Project prj, Stream strm)
{
int z = OKAY;
z |= stream_writeline(strm, "\t<Files>");
z |= sourcetree_walk(prj, strm, vs200x_project_file);
z |= stream_writeline(strm, "\t</Files>");
return z;
}
/**
* Write out the [Globals] element.
*/
int vs200x_project_globals(Project prj, Stream strm)
{
int z = OKAY;
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(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(strm, 2, "/>");
z |= stream_writeline(strm, "\t</Platforms>");
return OKAY;
}
/**
* Write out the [References] element and attributes.
*/
int vs200x_project_references(Project prj, Stream strm)
{
int z;
UNUSED(prj);
z = stream_writeline(strm, "\t</Configurations>");
if (vs200x_get_target_version() > 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(Project prj, Stream strm)
{
int z = OKAY;
UNUSED(prj);
if (vs200x_get_target_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(Project prj, Stream strm, const char* name)
{
int z = OKAY;
UNUSED(prj);
z |= stream_write(strm, "\t\t\t<Tool");
z |= vs200x_attribute(strm, 4, "Name", name);
z |= vs200x_element_end(strm, 3, "/>");
return z;
}
/**
* Write the VCALinkTool [Tool] element and attributes.
*/
int vs200x_project_vc_alink_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCALinkTool");
}
/**
* Write the VCAppVerifierTool [Tool] element and attributes.
*/
int vs200x_project_vc_app_verifier_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCAppVerifierTool");
}
/**
* Write the VCBscMakeTool [Tool] element and attributes.
*/
int vs200x_project_vc_bsc_make_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCBscMakeTool");
}
/**
* Write the VCCLCompilerTool [Tool] element and attributes.
*/
int vs200x_project_vc_cl_compiler_tool(Project prj, Stream strm)
{
int z = OKAY;
z |= stream_write(strm, "\t\t\t<Tool");
z |= vs200x_attribute(strm, 4, "Name", "VCCLCompilerTool");
z |= vs200x_config_optimization(prj, strm);
z |= vs200x_config_defines(prj, strm);
z |= vs200x_attribute(strm, 4, "MinimalRebuild", vs200x_true());
z |= vs200x_attribute(strm, 4, "BasicRuntimeChecks", "3");
z |= vs200x_attribute(strm, 4, "RuntimeLibrary", "3");
z |= vs200x_config_runtime_type_info(strm);
z |= vs200x_config_use_precompiled_header(strm);
z |= vs200x_attribute(strm, 4, "WarningLevel", "3");
z |= vs200x_config_detect_64bit_portability(strm);
z |= vs200x_config_debug_information_format(prj, strm);
z |= vs200x_element_end(strm, 3, "/>");
return z;
}
/**
* Write the VCCustomBuildTool [Tool] element and attributes.
*/
int vs200x_project_vc_custom_build_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCCustomBuildTool");
}
/**
* Write the VCFxCopTool [Tool] element and attributes.
*/
int vs200x_project_vc_fx_cop_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCFxCopTool");
}
/**
* Write the VCLinkerTool [Tool] element and attributes.
*/
int vs200x_project_vc_linker_tool(Project prj, Stream strm)
{
int z = OKAY;
z |= stream_write(strm, "\t\t\t<Tool");
z |= vs200x_attribute(strm, 4, "Name", "VCLinkerTool");
z |= vs200x_attribute(strm, 4, "LinkIncremental", "2");
z |= vs200x_config_generate_debug_information(prj, strm);
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(strm, 3, "/>");
return z;
}
/**
* Write the VCManagedResourceCompilerTool [Tool] element and attributes.
*/
int vs200x_project_vc_managed_resource_compiler_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCManagedResourceCompilerTool");
}
/**
* Write the VCManifestTool [Tool] element and attributes.
*/
int vs200x_project_vc_manifest_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCManifestTool");
}
/**
* Write the VCMIDLTool [Tool] element and attributes.
*/
int vs200x_project_vc_midl_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCMIDLTool");
}
/**
* Write the VCPreBuildEventTool [Tool] element and attributes.
*/
int vs200x_project_vc_pre_build_event_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCPreBuildEventTool");
}
/**
* Write the VCPreLinkEventTool [Tool] element and attributes.
*/
int vs200x_project_vc_pre_link_event_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCPreLinkEventTool");
}
/**
* Write the VCPostBuildEventTool [Tool] element and attributes.
*/
int vs200x_project_vc_post_build_event_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCPostBuildEventTool");
}
/**
* Write the VCResourceCompiler [Tool] element and attributes.
*/
int vs200x_project_vc_resource_compiler_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCResourceCompilerTool");
}
/**
* Write the VCWebDeploymentTool [Tool] element and attributes.
*/
int vs200x_project_vc_web_deployment_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCWebDeploymentTool");
}
/**
* Write the VCWebServiceProxyGeneratorTool [Tool] element and attributes.
*/
int vs200x_project_vc_web_service_proxy_generator_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCWebServiceProxyGeneratorTool");
}
/**
* Write the VCXDCMakeTool [Tool] element and attributes.
*/
int vs200x_project_vc_xdc_make_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCXDCMakeTool");
}
/**
* Write the VCXMLDataGeneratorTool [Tool] element and attributes.
*/
int vs200x_project_vc_xml_data_generator_tool(Project prj, Stream strm)
{
return vs200x_project_vc_empty_tool(prj, strm, "VCXMLDataGeneratorTool");
}

View File

@ -1,39 +0,0 @@
/**
* \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
int vs200x_project_config_element(Project prj, Stream strm);
int vs200x_project_config_end(Project prj, Stream strm);
int vs200x_project_create(Project prj, Stream strm);
int vs200x_project_element(Project prj, Stream strm);
int vs200x_project_encoding(Project prj, Stream strm);
int vs200x_project_file(Project prj, Stream strm, const char* filename, int state);
int vs200x_project_files(Project prj, Stream strm);
int vs200x_project_globals(Project prj, Stream strm);
int vs200x_project_platforms(Project prj, Stream strm);
int vs200x_project_references(Project prj, Stream strm);
int vs200x_project_tool_files(Project prj, Stream strm);
int vs200x_project_vc_alink_tool(Project prj, Stream strm);
int vs200x_project_vc_app_verifier_tool(Project prj, Stream strm);
int vs200x_project_vc_bsc_make_tool(Project prj, Stream strm);
int vs200x_project_vc_cl_compiler_tool(Project prj, Stream strm);
int vs200x_project_vc_custom_build_tool(Project prj, Stream strm);
int vs200x_project_vc_fx_cop_tool(Project prj, Stream strm);
int vs200x_project_vc_midl_tool(Project prj, Stream strm);
int vs200x_project_vc_linker_tool(Project prj, Stream strm);
int vs200x_project_vc_managed_resource_compiler_tool(Project prj, Stream strm);
int vs200x_project_vc_manifest_tool(Project prj, Stream strm);
int vs200x_project_vc_pre_build_event_tool(Project prj, Stream strm);
int vs200x_project_vc_pre_link_event_tool(Project prj, Stream strm);
int vs200x_project_vc_post_build_event_tool(Project prj, Stream strm);
int vs200x_project_vc_resource_compiler_tool(Project prj, Stream strm);
int vs200x_project_vc_web_deployment_tool(Project prj, Stream strm);
int vs200x_project_vc_web_service_proxy_generator_tool(Project prj, Stream strm);
int vs200x_project_vc_xdc_make_tool(Project prj, Stream strm);
int vs200x_project_vc_xml_data_generator_tool(Project prj, Stream strm);
#endif

View File

@ -1,29 +0,0 @@
/**
* \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.
*/
int vs200x_solution_create(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(solution_get_session(sln), strm);
return OKAY;
}

View File

@ -1,30 +0,0 @@
/**
* \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 "objects/solution.h"
int vs2002_solution_configuration(Solution sln, Stream strm);
int vs2002_solution_dependencies(Solution sln, Stream strm);
int vs2002_solution_extensibility(Solution sln, Stream strm);
int vs2002_solution_project_configuration(Solution sln, Stream strm);
int vs2002_solution_projects(Solution sln, Stream strm);
int vs2002_solution_signature(Solution sln, Stream strm);
int vs2003_solution_configuration(Solution sln, Stream strm);
int vs2003_solution_signature(Solution sln, Stream strm);
int vs2005_solution_platforms(Solution sln, Stream strm);
int vs2005_solution_project_platforms(Solution sln, Stream strm);
int vs2005_solution_properties(Solution sln, Stream strm);
int vs2005_solution_signature(Solution sln, Stream strm);
int vs2008_solution_signature(Solution sln, Stream strm);
int vs200x_solution_create(Solution sln, Stream strm);
#endif

View File

@ -0,0 +1,15 @@
--
-- _vstudio.lua
-- Define the Visual Studio 200x actions.
-- Copyright (c) 2008 Jason Perkins and the Premake project
--
-- premake.actions["vs2002"] = {
-- shortname = "Visual Studio 2002",
-- description = "Microsoft Visual Studio 2002",
--
-- solutiontemplates = {
-- { ".sln", _TEMPLATES.vs2002_solution },
-- },
-- }

View File

@ -0,0 +1,23 @@
<% eol = "\r\n" %>
Microsoft Visual Studio Solution File, Format Version 7.00
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppExe", "CppExe/CppExe.vcproj", "{AE61726D-187C-E440-BD07-2556188A6565}"
EndProject
Global
GlobalSection(SolutionConfiguration) = preSolution
ConfigName.0 = Debug
ConfigName.1 = Release
EndGlobalSection
GlobalSection(ProjectDependencies) = postSolution
EndGlobalSection
GlobalSection(ProjectConfiguration) = postSolution
{AE61726D-187C-E440-BD07-2556188A6565}.Debug.ActiveCfg = Debug|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Debug.Build.0 = Debug|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Release.ActiveCfg = Release|Win32
{AE61726D-187C-E440-BD07-2556188A6565}.Release.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
EndGlobalSection
GlobalSection(ExtensibilityAddIns) = postSolution
EndGlobalSection
EndGlobal

View File

@ -1,127 +0,0 @@
/**
* \file array.c
* \brief Dynamic array object.
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
*/
#include <assert.h>
#include <stdlib.h>
#include "premake.h"
#include "base/array.h"
#define ALLOCATION_SIZE (16)
DEFINE_CLASS(Array)
{
void** contents;
int size;
int capacity;
};
/**
* Create a new, empty array object.
* \returns A new array object.
*/
Array array_create()
{
Array arr = ALLOC_CLASS(Array);
arr->contents = NULL;
arr->size = 0;
arr->capacity = 0;
return arr;
}
/**
* Destroy an array object and release the associated memory.
* \param arr The array to destroy.
*/
void array_destroy(Array arr)
{
assert(arr);
if (arr->contents != NULL)
{
free(arr->contents);
}
free(arr);
}
/**
* Get the number of item in the array.
* \param arr The array to query.
* \returns The number elements currently in the array.
*/
int array_size(Array arr)
{
assert(arr);
return arr->size;
}
/**
* Add a new item to the end of the array, growing the array if necessary.
* \param arr The array object.
* \param item The item to add.
*/
void array_add(Array arr, void* item)
{
assert(arr);
assert(item);
if (arr->size == arr->capacity)
{
arr->capacity += ALLOCATION_SIZE;
arr->contents = (void**)realloc(arr->contents, sizeof(void*) * arr->capacity);
}
arr->contents[arr->size] = item;
arr->size++;
}
/**
* Retrieve the item at the specified index in the array.
* \param arr The array to query.
* \param index The index of the item to retrieve.
* \returns A pointer to the item.
*/
void* array_item(Array arr, int index)
{
assert(arr);
assert((index >= 0 && index < arr->size) || (index == 0 && arr->size == 0));
return arr->contents[index];
}
/**
* Store an item at a particular index in the array, overwriting any existing value.
* \param arr The array.
* \param index The index at which to store the item
* \param item The new item.
*/
void array_set(Array arr, int index, void* item)
{
assert(arr);
assert(index >= 0 && index < arr->size);
arr->contents[index] = item;
}
/**
* Append the contents of one array to another.
* \param dest The destination array.
* \param src The source array.
*/
void array_append(Array dest, Array src)
{
int i;
assert(dest);
assert(src);
for (i = 0; i < src->size; ++i)
{
array_add(dest, src->contents[i]);
}
}

View File

@ -1,27 +0,0 @@
/**
* \file array.h
* \brief Dynamic array object.
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
*
* \defgroup array Array
* \ingroup base
*
* A dynamic array class.
*
* @{
*/
#if !defined(PREMAKE_ARRAY_H)
#define PREMAKE_ARRAY_H
DECLARE_CLASS(Array);
Array array_create(void);
void array_destroy(Array arr);
int array_size(Array arr);
void array_add(Array arr, void* item);
void* array_item(Array arr, int index);
void array_set(Array arr, int index, void* item);
void array_append(Array dest, Array src);
#endif
/** @} */

View File

@ -1,12 +0,0 @@
/**
* \file base.h
* \brief Premake base library API.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*
* \defgroup base Base
*
* This component defines all of the base classes required by the higher-level
* functions of Premake.
*/
int base_tests();

View File

@ -1,85 +0,0 @@
/**
* \file buffers.c
* \brief Shared working buffer system.
* \author Copyright (c) 2007-2007 Jason Perkins and the Premake project
*
* \note I need to do a lot of string building operations in Premake. Rather than
* constantly creating, resizing, and releasing (and forgetting to release)
* dynamic string buffers, I use this shared buffer pool instead. Each request
* to buffer_next() returns the next buffer in the list. Pointers to the buffers
* can be safely passed around, and I don't need to remember to release anything
* when I'm done. The buffers should only be used for transient values, obviously.
* If you need to keep a value around for any length of time copy it to a string.
*
* \note The size and number of the buffers is arbitrary; I just picked some numbers
* that seemed big enough.
*/
#include <stdlib.h>
#include "premake.h"
#include "base/buffers.h"
/** The size of an individual buffer, in bytes. */
const int BUFFER_SIZE = 0x4000;
/** The number of buffers stored in the pool */
static const int NUM_BUFFERS = 128;
/** The pool of buffers */
static char** buffers = NULL;
/** The index of the next available buffer */
static int next = 0;
/**
* Clean up after the buffer system. Called by atexit().
*/
static void buffers_destroy(void)
{
if (buffers != NULL)
{
int i;
for (i = 0; i < NUM_BUFFERS; ++i)
{
free(buffers[i]);
}
free(buffers);
}
}
/**
* Initialize the buffer system.
*/
static void buffers_create(void)
{
int i;
buffers = (char**)malloc(sizeof(char*) * NUM_BUFFERS);
for (i = 0; i < NUM_BUFFERS; ++i)
{
buffers[i] = (char*)malloc(BUFFER_SIZE);
}
next = 0;
atexit(buffers_destroy);
}
/**
* Get a clean buffer.
* \returns An empty buffer.
*/
char * buffers_next()
{
/* if this is the first call, initialize the buffer system */
if (buffers == NULL)
buffers_create();
next++;
if (next == NUM_BUFFERS)
next = 0;
/* initialize new buffers to empty string */
buffers[next][0] = '\0';
return buffers[next];
}

View File

@ -1,25 +0,0 @@
/**
* \file buffers.h
* \brief Shared working buffer system.
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
*
* \defgroup buffers Buffers
* \ingroup base
*
* A shared working buffer collection. A buffer can be requested from the system, filled,
* and passed around for a short period of time. This system allows transient string values
* to be returned from functions and immediately used without having to resort to
* full-blown string objects, and the ownership issues that would entail.
*
* @{
*/
#if !defined(PREMAKE_BUFFER_H)
#define PREMAKE_BUFFER_H
extern const int BUFFER_SIZE;
char* buffers_next(void);
#endif
/** @} */

View File

@ -1,235 +0,0 @@
/**
* \file cstr.c
* \brief C string handling.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*/
#include <assert.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#include "premake.h"
#include "base/buffers.h"
#include "base/cstr.h"
#include "base/luastate.h"
/**
* Determines if the sequence appears anywhere in the target string.
* \param str The string to test.
* \param expected The sequence to search for.
* \returns True if the sequence is contained in the string.
*/
int cstr_contains(const char* str, const char* expected)
{
assert(str);
assert(expected);
return (strstr(str, expected) != NULL);
}
/**
* Determines if the string ends with a particular sequence.
* \param str The string to test.
* \param expected The sequence for which to look.
* \returns True if the string ends with the sequence, false otherwise.
*/
int cstr_ends_with(const char* str, const char* expected)
{
if (str != NULL && expected != NULL)
{
int str_len = strlen(str);
int exp_len = strlen(expected);
if (str_len >= exp_len)
{
const char* start = str + str_len - exp_len;
return (strcmp(start, expected) == 0);
}
}
return 0;
}
/**
* Compares two C strings for equality.
* \param str The string to compare.
* \param expected The value to compare against.
* \returns True if the strings match, zero otherwise.
*/
int cstr_eq(const char* str, const char* expected)
{
if (str != NULL && expected != NULL)
{
return (strcmp(str, expected) == 0);
}
return 0;
}
/**
* Performs a case-insensitive comparasion on two C strings for equality.
* \param str The string to compare.
* \param expected The value to compare against.
* \returns True if the strings match, zero otherwise.
*/
int cstr_eqi(const char* str, const char* expected)
{
if (str != NULL && expected != NULL)
{
while (*str && *expected)
{
if (tolower(*str) != tolower(*expected))
{
return 0;
}
str++;
expected++;
}
return (*str == *expected);
}
return 0;
}
/**
* Builds a string using printf-style formatting codes.
* \param format The format string, which may contain printf-style formatting codes.
* \returns The formatted string.
*/
char* cstr_format(const char* format, ...)
{
va_list args;
char* buffer = buffers_next();
va_start(args, format);
vsprintf(buffer, format, args);
va_end(args);
return buffer;
}
/**
* Compares a string value with a pattern, using the Lua pattern syntax, and
* returns true if there is a match.
*/
int cstr_matches_pattern(const char* str, const char* pattern)
{
lua_State* L;
char* buffer;
int i, escaped, top, result, is_my_state = 0;
assert(str);
assert(pattern);
/* convert pattern to match any case, each non-escaped letter A becomes [Aa] */
buffer = buffers_next();
i = 0;
escaped = 0;
while (*pattern != '\0')
{
if (isalpha(*pattern) && !escaped)
{
buffer[i++] = '[';
buffer[i++] = (char)toupper(*pattern);
buffer[i++] = (char)tolower(*pattern);
buffer[i++] = ']';
}
else
{
escaped = (*pattern == '%');
buffer[i++] = *pattern;
}
pattern++;
}
buffer[i] = '\0';
/* connect to Lua so I can call the match() function */
L = luastate_get_current();
is_my_state = (L == NULL);
if (is_my_state)
{
L = luastate_create();
}
top = lua_gettop(L);
/* retrieve the match() function and call it */
lua_getglobal(L, "string");
lua_getfield(L, -1, "match");
lua_pushstring(L, str);
lua_pushstring(L, buffer);
lua_call(L, 2, 1);
result = cstr_eq(str, lua_tostring(L,-1));
/* clean up and return the result */
lua_settop(L, top);
if (is_my_state)
{
luastate_destroy(L);
}
return result;
}
/**
* Determines if the given C string starts with a particular sequence.
* \param str The string to test.
* \param expected The sequence for which to look.
* \returns True if the string starts with the sequence, false otherwise.
*/
int cstr_starts_with(const char* str, const char* expected)
{
if (str != NULL && expected != NULL)
{
return (strncmp(str, expected, strlen(expected)) == 0);
}
return 0;
}
/**
* Removes spaces any other special characters from a string, converting it
* into a C/C++/C# safe identifier.
* \param str The string to process.
* \returns An identifier-safe string.
*/
char* cstr_to_identifier(const char* str)
{
char* buffer = buffers_next();
char* dst = buffer;
while (*str != '\0')
{
if (isalnum(*str) || *str == '_')
{
*(dst++) = *str;
}
str++;
}
*dst = '\0';
return buffer;
}
/**
* Remove a character from the end of a string, if present.
* \param str The string to trim.
* \param ch The character to trim.
*/
void cstr_trim(char* str, char ch)
{
int i;
assert(str);
i = strlen(str) - 1;
while (i >= 0 && str[i] == ch)
{
str[i] = '\0';
i--;
}
}

View File

@ -1,27 +0,0 @@
/**
* \file cstr.h
* \brief C string handling.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*
* \defgroup cstr C Strings
* \ingroup base
*
* Functions to handle C strings (zero-terminated byte arrays).
*
* @{
*/
#if !defined(PREMAKE_CSTR_H)
#define PREMAKE_CSTR_H
int cstr_contains(const char* str, const char* expected);
int cstr_ends_with(const char* str, const char* expected);
int cstr_eq(const char* str, const char* expected);
int cstr_eqi(const char* str, const char* expected);
char* cstr_format(const char* format, ...);
int cstr_matches_pattern(const char* str, const char* pattern);
int cstr_starts_with(const char* str, const char* expected);
char* cstr_to_identifier(const char* str);
void cstr_trim(char* str, char ch);
#endif
/** @} */

View File

@ -1,106 +0,0 @@
/**
* \file dir.c
* \brief Directory handling.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*/
#include <assert.h>
#include <string.h>
#include <sys/stat.h>
#include "premake.h"
#include "base/buffers.h"
#include "base/dir.h"
#include "base/error.h"
#include "base/path.h"
#include "platform/platform.h"
/**
* Create a directory, if it doesn't exist already.
* \returns OKAY if successful.
*/
int dir_create(const char* path)
{
char* parent;
assert(path);
if (dir_exists(path))
return OKAY;
/* make sure the parent directory exists */
parent = path_directory(path);
if (strlen(parent) > 0)
{
if (dir_create(parent) != OKAY)
return !OKAY;
}
if (platform_create_dir(path) != OKAY)
{
error_set("Unable to create directory %s", path);
return !OKAY;
}
return OKAY;
}
/**
* Determine if a particular directory exists on the filesystem.
* \returns True if the directory exists.
*/
int dir_exists(const char* path)
{
struct stat buf;
assert(path);
/* empty path is equivalent to ".", must be true */
if (strlen(path) == 0)
{
return 1;
}
if (stat(path, &buf) == 0)
{
return (buf.st_mode & S_IFDIR);
}
else
{
return 0;
}
}
/**
* Get the current working directory.
* \returns The current working directory, or NULL on error. Path separators
* are converted to forward slashes, regardless of platform.
*/
char* dir_get_current()
{
char* buffer = buffers_next();
int result = platform_dir_get_current(buffer, BUFFER_SIZE);
if (result == OKAY)
{
return path_translate(buffer, "/");
}
else
{
return NULL;
}
}
/**
* Set the current working directory.
* \param path The new working directory.
* \returns OKAY if successful.
*/
int dir_set_current(const char* path)
{
assert(path);
return platform_dir_set_current(path);
}

View File

@ -1,22 +0,0 @@
/**
* \file dir.h
* \brief Directory handling.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*
* \defgroup dir Directory Management
* \ingroup base
*
* Directory management functions.
*
* @{
*/
#if !defined(PREMAKE_DIR_H)
#define PREMAKE_DIR_H
int dir_create(const char* path);
int dir_exists(const char* path);
char* dir_get_current(void);
int dir_set_current(const char* path);
#endif
/** @} */

View File

@ -1,98 +0,0 @@
/**
* \file env.c
* \brief Manage the runtime environment state.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*/
#include <assert.h>
#include <stdlib.h>
#include "premake.h"
#include "env.h"
#include "platform/platform.h"
static enum OS CurrentOS = UnknownOS;
static const char* Action = NULL;
/**
* Retrieve the current action being targeted. Will return NULL if no action
* has been set.
*/
const char* env_get_action(void)
{
return Action;
}
/**
* Identify the target OS. This value will be set to the current OS by default,
* but can be overridden by calling env_set_os_by_name().
*/
enum OS env_get_os(void)
{
if (CurrentOS == UnknownOS)
{
#if defined(PLATFORM_BSD)
CurrentOS = BSD;
#elif defined(PLATFORM_LINUX)
CurrentOS = Linux;
#elif defined(PLATFORM_MACOSX)
CurrentOS = MacOSX;
#else
CurrentOS = Windows;
#endif
}
return CurrentOS;
}
/**
* Identify the target OS with a string name. This value will be set to the current
* OS by default, but can be overridden by calling env_set_os_by_name().
*/
const char* env_get_os_name(void)
{
switch (env_get_os())
{
case BSD:
return "BSD";
case Linux:
return "Linux";
case MacOSX:
return "MacOSX";
case Windows:
return "Windows";
default:
assert(0);
return 0;
}
}
/**
* Returns true if the current OS matches the one provided.
*/
int env_is_os(enum OS id)
{
return (env_get_os() == id);
}
/**
* Set the action being targeted in this run.
*/
void env_set_action(const char* action)
{
Action = action;
}
/**
* Override the default OS identification, allowing generation of project files
* targeted for other platforms (like cross-compiling).
*/
void env_set_os(enum OS id)
{
CurrentOS = id;
}

View File

@ -1,41 +0,0 @@
/**
* \file env.h
* \brief Manage the runtime environment state.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*
* \defgroup env Runtime Environment
* \ingroup base
*
* Manage the runtime environment state, getting and setting such values as
* the target action and the operating system.
*
* @{
*/
#if !defined(PREMAKE_ENV_H)
#define PREMAKE_ENV_H
/**
* The currently supported operating systems.
* \note If you add to this list, be sure to also update the detection
* and string translation logic.
*/
enum OS
{
UnknownOS,
BSD,
Linux,
MacOSX,
Windows
};
const char* env_get_action(void);
enum OS env_get_os(void);
const char* env_get_os_name(void);
int env_is_os(enum OS id);
void env_set_action(const char* action);
void env_set_os(enum OS id);
#endif
/** @} */

View File

@ -1,51 +0,0 @@
/**
* \file error.c
* \brief Application-wide error reporting.
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
*/
#include <assert.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include "premake.h"
#include "error.h"
static char error_message[8192] = { 0 };
/**
* Clear any existing error state.
*/
void error_clear(void)
{
error_message[0] = 0;
}
/**
* Returns the most recent error message set by error_set().
* \returns The error message, or NULL if no error message has been set.
*/
const char* error_get(void)
{
return (strlen(error_message) > 0) ? error_message : NULL;
}
/**
* Set the description of an error condition, which may be retrieved with session_get_error().
* The session uses a fixed length (around 8K) buffer for storing the error message, so make
* sure the final size of the formatted message will fall under that limit.
* \param message A description of the error condition.
*/
void error_set(const char* message, ...)
{
va_list args;
assert(message);
va_start(args, message);
vsprintf(error_message, message, args);
va_end(args);
}

View File

@ -1,21 +0,0 @@
/**
* \file error.h
* \brief Application-wide error reporting.
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
*
* \defgroup array Array
* \ingroup base
*
* Application-wide error reporting.
*
* @{
*/
#if !defined(PREMAKE_ERROR_H)
#define PREMAKE_ERROR_H
void error_clear(void);
const char* error_get(void);
void error_set(const char* message, ...);
#endif
/** @} */

View File

@ -1,31 +0,0 @@
/**
* \file file.c
* \brief File handling.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*/
#include <assert.h>
#include <sys/stat.h>
#include "premake.h"
#include "base.h"
/**
* Determine if a particular file exists on the filesystem.
* \returns True if the file exists.
*/
int file_exists(const char* path)
{
struct stat buf;
assert(path);
if (stat(path, &buf) == 0)
{
return ((buf.st_mode & S_IFDIR) == 0);
}
else
{
return 0;
}
}

View File

@ -1,19 +0,0 @@
/**
* \file file.h
* \brief File handling.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*
* \defgroup file File Management
* \ingroup base
*
* File management functions.
*
* @{
*/
#if !defined(PREMAKE_DIR_H)
#define PREMAKE_DIR_H
int file_exists(const char* path);
#endif
/** @} */

319
src/base/functions.lua Normal file
View File

@ -0,0 +1,319 @@
--
-- functions.lua
-- Implementations of the solution, project, and configuration APIs.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project
--
--
-- Validation lists for fields with constrained value sets.
--
local valid_flags =
{
"Dylib",
"ExtraWarnings",
"FatalWarnings",
"No64BitChecks",
"NoExceptions",
"NoFramePointer",
"NoImportLib",
"NoRTTI",
"Optimize",
"OptimizeSize",
"OptimizeSpeed",
"Symbols"
}
local valid_kinds =
{
"ConsoleExe",
"WindowedExe",
"StaticLib",
"SharedLib"
}
local valid_languages =
{
"C",
"C++",
}
--
-- These list fields should be initialized to an empty table.
--
premake.project.listfields =
{
"buildoptions",
"defines",
"excludes",
"files",
"flags",
"incdirs",
"libdirs",
"linkoptions",
"links",
"resoptions",
}
--
-- These fields should *not* be copied into configurations.
--
premake.project.nocopy =
{
"blocks",
"keywords",
"projects"
}
--
-- These fields should be converted from absolute paths into project
-- location relative before being returned in a configuration.
--
premake.project.locationrelative =
{
"basedir",
"excludes",
"files",
"incdirs",
"libdirs",
"objdir",
"targetdir",
}
--
-- Project API functions
--
function buildoptions(value)
return premake.project.setarray("config", "buildoptions", value)
end
function configuration(keywords)
local container, err = premake.project.getobject("container")
if (not container) then
error(err, 2)
end
local cfg = { }
table.insert(container.blocks, cfg)
premake.CurrentConfiguration = cfg
if (type(keywords) == "table") then
cfg.keywords = keywords
else
cfg.keywords = { keywords }
end
for _, name in ipairs(premake.project.listfields) do
cfg[name] = { }
end
return cfg
end
function configurations(value)
return premake.project.setarray("solution", "configurations", value)
end
function defines(value)
return premake.project.setarray("config", "defines", value)
end
function excludes(value)
return premake.project.setfilearray("container", "excludes", value)
end
function files(value)
return premake.project.setfilearray("container", "files", value)
end
function flags(value)
return premake.project.setarray("config", "flags", value, valid_flags)
end
function implibname(value)
return premake.project.setstring("config", "implibname", value)
end
function implibdir(value)
return premake.project.setstring("config", "implibdir", path.getabsolute(value))
end
function implibextension(value)
return premake.project.setstring("config", "implibextension", value)
end
function implibprefix(value)
return premake.project.setstring("config", "implibprefix", value)
end
function includedirs(value)
return premake.project.setdirarray("config", "incdirs", value)
end
function kind(value)
return premake.project.setstring("config", "kind", value, valid_kinds)
end
function language(value)
return premake.project.setstring("container", "language", value, valid_languages)
end
function libdirs(value)
return premake.project.setdirarray("config", "libdirs", value)
end
function linkoptions(value)
return premake.project.setarray("config", "linkoptions", value)
end
function links(value)
return premake.project.setarray("config", "links", value)
end
function location(value)
return premake.project.setstring("container", "location", path.getabsolute(value))
end
function objdir(value)
return premake.project.setstring("config", "objdir", path.getabsolute(value))
end
function project(name)
if (name) then
-- identify the parent solution
local sln
if (type(premake.CurrentContainer) == "project") then
sln = premake.CurrentContainer.solution
else
sln = premake.CurrentContainer
end
if (type(sln) ~= "solution") then
error("no active solution", 2)
end
-- see if this project has already been created
premake.CurrentContainer = sln.projects[name]
if (not premake.CurrentContainer) then
local prj = { }
premake.CurrentContainer = prj
-- add to master list keyed by both name and index
table.insert(sln.projects, prj)
sln.projects[name] = prj
-- attach a type
setmetatable(prj, {
__type = "project",
__cfgcache = { }
})
prj.solution = sln
prj.name = name
prj.basedir = os.getcwd()
prj.location = prj.basedir
prj.filter = { }
prj.blocks = { }
end
end
if (type(premake.CurrentContainer) == "project") then
-- add an empty, global configuration to the project
configuration { }
return premake.CurrentContainer
else
return nil
end
end
function resoptions(value)
return premake.project.setarray("config", "resoptions", value)
end
function solution(name)
if (name) then
premake.CurrentContainer = _SOLUTIONS[name]
if (not premake.CurrentContainer) then
local sln = { }
premake.CurrentContainer = sln
-- add to master list keyed by both name and index
table.insert(_SOLUTIONS, sln)
_SOLUTIONS[name] = sln
-- attach a type
setmetatable(sln, {
__type="solution"
})
sln.name = name
sln.location = os.getcwd()
sln.projects = { }
sln.blocks = { }
sln.configurations = { }
end
end
-- make the solution active and return it
if (type(premake.CurrentContainer) == "project") then
premake.CurrentContainer = premake.CurrentContainer.solution
end
if (premake.CurrentContainer) then
-- add an empty, global configuration
configuration { }
end
return premake.CurrentContainer
end
function targetname(value)
return premake.project.setstring("config", "targetname", value)
end
function targetdir(value)
return premake.project.setstring("config", "targetdir", path.getabsolute(value))
end
function targetextension(value)
return premake.project.setstring("config", "targetextension", value)
end
function targetprefix(value)
return premake.project.setstring("config", "targetprefix", value)
end

124
src/base/gcc.lua Normal file
View File

@ -0,0 +1,124 @@
--
-- gcc.lua
-- Provides GCC-specific configuration strings.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project
--
--
-- I don't know if this is the right breakdown or API to individual compilers
-- yet so treat it all as experimental. I won't know until I get the change
-- to implement a few different compilers across different toolset actions.
--
premake.tools.gcc = { }
premake.tools.gcc.cflags =
{
ExtraWarnings = "-Wall",
FatalWarning = "-Werror",
NoFramePointer = "-fomit-frame-pointer",
Optimize = "-O2",
OptimizeSize = "-Os",
OptimizeSpeed = "-O3",
Symbols = "-g",
}
premake.tools.gcc.cxxflags =
{
NoExceptions = "--no-exceptions",
NoRTTI = "--no-rtti",
}
function premake.tools.gcc.make_defines(cfg)
return table.implode(cfg.defines, '-D "', '"', ' ')
end
function premake.tools.gcc.make_includes(cfg)
return table.implode(cfg.incdirs, '-I "', '"', ' ')
end
function premake.tools.gcc.make_cppflags(cfg)
-- if $(ARCH) contains multiple targets, then disable the incompatible automatic
-- dependency generation. This allows building universal binaries on MacOSX, sorta.
return "$(if $(word 2, $(ARCH)), , -MMD)"
end
function premake.tools.gcc.make_cflags(cfg)
local flags = table.translate(cfg.flags, premake.tools.gcc.cflags)
if (cfg.kind == "SharedLib" and not os.is("windows")) then
table.insert(flags, "-fPIC")
end
return table.concat(flags, " ")
end
function premake.tools.gcc.make_cxxflags(cfg)
local flags = table.translate(cfg.flags, premake.tools.gcc.cxxflags)
return table.concat(flags, " ")
end
function premake.tools.gcc.make_ldflags(cfg)
local flags = { }
if (cfg.kind == "SharedLib") then
if (not os.is("macosx")) then
table.insert(flags, "-shared")
end
-- create import library for DLLs under Windows
if (os.is("windows") and not table.contains(cfg.flags, "NoImportLib")) then
table.insert(flags, '-Wl,--out-implib="' .. premake.project.gettargetfile(cfg, "implib", "StaticLib", "linux") .. '"')
end
end
if (os.is("windows") and cfg.kind == "WindowedExe") then
table.insert(flags, "-mwindows")
end
-- OS X has a bug, see http://lists.apple.com/archives/Darwin-dev/2006/Sep/msg00084.html
if (not table.contains(cfg.flags, "Symbols")) then
if (os.is("macosx")) then
table.insert(flags, "-Wl,-x")
else
table.insert(flags, "-s")
end
end
if (os.is("macosx") and table.contains(flags, "Dylib")) then
table.insert(flags, "-dynamiclib -flat_namespace")
end
-- need to split path from libraries to avoid runtime errors (see bug #1729227)
local dirs = { }
local names = { }
for _, link in ipairs(premake.project.getlibraries(cfg, cfg.links)) do
local dir = path.getdirectory(link)
local name = path.getbasename(link)
if (dir ~= "" and not table.contains(cfg.libdirs, dir) and not table.contains(dirs, dir)) then
table.insert(dirs, dir)
end
table.insert(names, name)
end
return table.concat(flags, " ") .. table.implode(cfg.libdirs, ' -L "', '"').. table.implode(dirs, ' -L "', '"') .. table.implode(names, ' -l "', '"')
end
function premake.tools.gcc.make_file_rule(file)
if (path.iscfile(file)) then
return "$(CC) $(CFLAGS) -o $@ -c $<"
else
return "$(CXX) $(CXXFLAGS) -o $@ -c $<"
end
end

126
src/base/globals.lua Normal file
View File

@ -0,0 +1,126 @@
--
-- globals.lua
-- Global tables and variables, replacements and extensions to Lua's global functions.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project
--
-- The list of defined solutions (which contain projects, etc.)
_SOLUTIONS = { }
-- The list of built-in output templates
_TEMPLATES = { }
-- A top-level namespace for support functions
premake = { }
-- The list of registered actions
premake.actions = { }
-- The list of tool interfaces
premake.tools = { }
--
-- A replacement for Lua's built-in dofile() function, this one sets the
-- current working directory to the script's location, enabling script-relative
-- referencing of other files and resources.
--
local builtin_dofile = dofile
function dofile(fname)
-- remember the current working directory; I'll restore it shortly
local oldcwd = os.getcwd()
-- if the file doesn't exist, check the search path
if (not os.isfile(fname)) then
local path = os.pathsearch(fname, _OPTIONS["scripts"], os.getenv("PREMAKE_PATH"))
if (path) then
fname = path.."/"..fname
end
end
-- use the absolute path to the script file, to avoid any file name
-- ambiguity if an error should arise
fname = path.getabsolute(fname)
-- switch the working directory to the new script location
local newcwd = path.getdirectory(fname)
os.chdir(newcwd)
-- run the chunk. How can I catch variable return values?
local a, b, c, d, e, f = builtin_dofile(fname)
-- restore the previous working directory when done
os.chdir(oldcwd)
return a, b, c, d, e, f
end
--
-- A shortcut for including another "premake4.lua" file, often used for projects.
--
function include(fname)
return dofile(fname .. "/premake4.lua")
end
--
-- Open an overload of the io.open() function, which will create any missing
-- subdirectories in the filename if "mode" is set to writeable.
--
local builtin_open = io.open
function io.open(fname, mode)
if (mode) then
if (mode:find("w")) then
local dir = path.getdirectory(fname)
ok, err = os.mkdir(dir)
if (not ok) then
error(err, 0)
end
end
end
return builtin_open(fname, mode)
end
--
-- A shortcut for printing formatted output.
--
function printf(msg, ...)
print(string.format(msg, unpack(arg)))
end
--
-- An extension to type() to identify project object types by reading the
-- "__type" field from the metatable.
--
local builtin_type = type
function type(t)
local mt = getmetatable(t)
if (mt) then
if (mt.__type) then
return mt.__type
end
end
return builtin_type(t)
end

View File

@ -1,109 +0,0 @@
/**
* \file guid.c
* \brief GUID creation and validation.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*/
#include <stdio.h>
#include <string.h>
#include "premake.h"
#include "guid.h"
#include "platform/platform.h"
#include "base/buffers.h"
static void stringify(char* src, char* dst, int count);
/**
* Create a new GUID, with the format "4E67EBCE-BC8B-4058-9AA9-48EE5E003683".
* \returns The new GUID.
*/
const char* guid_create()
{
char guid[16];
char* result = buffers_next();
/* get a GUID as an array of 16 bytes */
platform_create_guid(guid);
/* convert that array to a string in the usual format */
stringify(guid, result, 4);
result[8] = '-';
stringify(guid + 4, result + 9, 2);
result[13] = '-';
stringify(guid + 6, result + 14, 2);
result[18] = '-';
stringify(guid + 8, result + 19, 2);
result[23] = '-';
stringify(guid + 10, result + 24, 6);
result[36] = '\0';
return result;
}
/**
* Validate the format of a GUID, which should use the form "4E67EBCE-BC8B-4058-9AA9-48EE5E003683".
* \param value The guid to validate.
* \returns True if valid, zero otherwise.
*/
int guid_is_valid(const char* value)
{
int i, n;
/* make sure it is the right size */
if (strlen(value) != 36)
return 0;
/* check for dashes in the right places */
if (value[8] != '-' ||
value[13] != '-' ||
value[18] != '-' ||
value[23] != '-')
{
return 0;
}
/* make sure only [0-9A-F-] are present; count the number of dashes on the way */
n = 0;
for (i = 0; i < 36; ++i)
{
if (value[i] == '-')
{
++n;
}
else if ((value[i] < '0' || value[i] > '9') &&
(value[i] < 'A' || value[i] > 'F') &&
(value[i] < 'a' || value[i] > 'f'))
{
return 0;
}
}
/* make sure I've got the right number of dashes */
if (n != 4)
{
return 0;
}
return 1;
}
/**
* Convert an array of bytes to a string.
* \param src The source array of bytes.
* \param dst The destination string buffer.
* \param count The number of bytes to convert.
*/
static void stringify(char* src, char* dst, int count)
{
int i;
for (i = 0; i < count; ++i)
{
unsigned value = (unsigned char)src[i];
sprintf(dst, "%02X", value);
dst += 2;
}
}

View File

@ -1,20 +0,0 @@
/**
* \file guid.h
* \brief GUID creation and validation.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*
* \defgroup guid GUIDs
* \ingroup base
*
* GUID creation and validation functions.
*
* @{
*/
#if !defined(PREMAKE_GUID_H)
#define PREMAKE_GUID_H
const char* guid_create();
int guid_is_valid(const char* value);
#endif
/** @} */

View File

@ -1,44 +0,0 @@
/**
* \file luastate.c
* \brief An accessor for a Lua runtime state object.
* \author Copyright (c) 2008 Jason Perkins and the Premake project
*/
#include <assert.h>
#include "luastate.h"
static lua_State* Current = NULL;
/**
* Create a new Lua state object and set the current global state.
*/
lua_State* luastate_create(void)
{
Current = lua_open();
luaL_openlibs(Current);
return Current;
}
/**
* Destroy a Lua state object and clear the current global state.
*/
void luastate_destroy(lua_State* L)
{
assert(L);
lua_close(L);
if (Current == L) Current = NULL;
}
/**
* Return the current global Lua state, or NULL if there is no currently active state.
*/
lua_State* luastate_get_current(void)
{
return Current;
}

View File

@ -1,31 +0,0 @@
/**
* \file luastate.h
* \brief An accessor for a Lua runtime state object.
* \author Copyright (c) 2008 Jason Perkins and the Premake project
*
* \defgroup luastate Lua State
* \ingroup base
*
* A wrapper around a global Lua state object, allowing the state to be
* shared between the main scripting engine object and the cstr_matches_pattern()
* function (which is in turn used by the project object).
*
* @{
*/
#if !defined(PREMAKE_LUASTATE_H)
#define PREMAKE_LUASTATE_H
#define lua_c
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
lua_State* luastate_create(void);
void luastate_destroy(lua_State* L);
lua_State* luastate_get_current(void);
#endif
/** @} */

91
src/base/os.lua Normal file
View File

@ -0,0 +1,91 @@
--
-- os.lua
-- Additions to the OS namespace.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project
--
--
-- Check the current operating system; may be set with the /os command line flag.
--
function os.is(id)
local current = _OPTIONS["os"] or _OS
return (current:lower() == id:lower())
end
--
-- The os.matchdirs() and os.matchfiles() functions
--
local function domatch(result, mask, wantfiles)
local basedir = path.getdirectory(mask)
if (basedir == ".") then basedir = "" end
local m = os.matchstart(mask)
while (os.matchnext(m)) do
local fname = os.matchname(m)
local isfile = os.matchisfile(m)
if ((wantfiles and isfile) or (not wantfiles and not isfile)) then
table.insert(result, path.join(basedir, fname))
end
end
os.matchdone(m)
-- if the mask uses "**", recurse subdirectories
if (mask:find("**")) then
mask = path.getname(mask)
m = os.matchstart(path.join(basedir, "*"))
while (os.matchnext(m)) do
local dirname = os.matchname(m)
local submask = path.join(path.join(basedir, dirname), mask)
domatch(result, submask, wantfiles)
end
os.matchdone(m)
end
end
function os.matchdirs(...)
local result = { }
for _, mask in ipairs(arg) do
domatch(result, mask, false)
end
return result
end
function os.matchfiles(...)
local result = { }
for _, mask in ipairs(arg) do
domatch(result, mask, true)
end
return result
end
--
-- An overload of the os.mkdir() function, which will create any missing
-- subdirectories along the path.
--
local builtin_mkdir = os.mkdir
function os.mkdir(p)
local dir = ""
for part in p:gmatch("[^/]+") do
dir = dir .. part
if (part ~= "" and not path.isabsolute(part) and not os.isdir(dir)) then
local ok, err = builtin_mkdir(dir)
if (not ok) then
return nil, err
end
end
dir = dir .. "/"
end
return true
end

View File

@ -1,353 +0,0 @@
/**
* \file path.c
* \brief Path handling.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#include "premake.h"
#include "base/path.h"
#include "platform/platform.h"
#include "base/buffers.h"
#include "base/cstr.h"
#include "base/dir.h"
static char* CppFileExtensions[] = { ".cc", ".cpp", ".cxx", ".c", ".s", NULL };
/**
* Create an absolute path from a relative one.
* \param path The relative path to convert.
* \returns An absolute version of the relative path.
*/
char* path_absolute(const char* path)
{
char* source;
char* result;
assert(path);
/* normalize the target path */
source = path_translate(path, "/");
if (strlen(source) == 0)
strcpy(source, ".");
/* If the directory is already absolute I don't have to do anything */
if (path_is_absolute(source))
return source;
/* start from the current location */
result = dir_get_current();
/* split up the supplied relative path and tackle it bit by bit */
while (source)
{
char* end = strchr(source, '/');
if (end)
*end = 0;
if (cstr_eq(source, ".."))
{
char* up = strrchr(result, '/');
if (up)
*up = 0;
}
else if (!cstr_eq(source, "."))
{
strcat(result, "/");
strcat(result, source);
}
source = end ? end + 1 : NULL;
}
return result;
}
/**
* Assemble a complete file path from its component parts.
* \param dir The directory portion of the path.
* \param filename The file name portion of the path.
* \param ext The extension portion of the path.
* \returns The assembled file path.
*/
char* path_assemble(const char* dir, const char* filename, const char* ext)
{
char* buffer;
assert(dir);
assert(filename);
assert(ext);
buffer = path_join(dir, filename);
if (ext)
{
strcat(buffer, ext);
}
return buffer;
}
/**
* Returns the base name in a path: the filename, without the directory or
* file extension.
* \param path The path to split.
* \returns The base name part of the path.
*/
char* path_basename(const char* path)
{
char* buffer = path_filename(path);
char* ptr = strrchr(buffer, '.');
if (ptr)
{
*ptr = '\0';
}
return buffer;
}
/**
* Retrieve the directory portion of a path.
* \param path The path to split.
* \returns The directory portion of the path. Returns an empty string ("") if
* the path does not contain any directory information.
*/
char* path_directory(const char* path)
{
char* ptr;
char* buffer = buffers_next();
assert(path);
strcpy(buffer, path);
ptr = strrchr(buffer, '/');
if (ptr)
*ptr = '\0';
else
*buffer = '\0';
return buffer;
}
/**
* Retrieve the file extension portion of a path. If the path has multiple
* dots in the filename (ie. filename.my.ext) only the last bit (.ext) will
* be returned. The dot is included in the extension.
* \param path The path to split.
* \returns The extension portion of the path, or an empty string if no extension is present.
*/
char* path_extension(const char* path)
{
char* ptr;
char* buffer = buffers_next();
assert(path);
strcpy(buffer, path);
ptr = strrchr(buffer, '.');
return (ptr) ? ptr : "";
}
/**
* Retrieve the fileame (filename.ext) portion of a path.
* \param path The path to split.
* \returns The filename portion of the path. Returns an empty string ("") if
* the path is empty.
*/
char* path_filename(const char* path)
{
char* ptr;
char* buffer = buffers_next();
assert(path);
ptr = strrchr(path, '/');
if (ptr)
{
strcpy(buffer, ptr + 1);
}
else
{
strcpy(buffer, path);
}
return buffer;
}
/**
* Determine is a path is absolute (rooted at base of filesystem).
* \param path The path to check.
* \returns True if the path is absolute.
*/
int path_is_absolute(const char* path)
{
assert(path);
if (path[0] == '/' || path[0] == '\\')
return 1;
if (path[1] == ':')
return 1;
return 0;
}
/**
* Returns true if the path represents a C++ source code file; by checking
* the file extension.
* \param path The path to check.
* \returns True if the path uses a known C++ file extension.
*/
int path_is_cpp_source(const char* path)
{
int i;
char* ext = path_extension(path);
if (cstr_eq(ext, ""))
{
return 0;
}
for (i = 0; CppFileExtensions[i] != NULL; ++i)
{
if (cstr_eqi(CppFileExtensions[i], ext))
return 1;
}
return 0;
}
/**
* Join two paths togethers.
* \param leading The leading path.
* \param trailing The trailing path.
* \returns A unified path.
* \note If the trailing path is absolute, that will be the return value.
* A join is only performed if the trailing path is relative.
*/
char* path_join(const char* leading, const char* trailing)
{
char* buffer = buffers_next();
/* treat nulls like empty paths */
leading = (leading != NULL) ? leading : "";
if (!trailing)
{
strcpy(buffer, leading);
return buffer;
}
if (!leading || path_is_absolute(trailing))
{
strcpy(buffer, trailing);
return buffer;
}
if (leading)
{
strcat(buffer, leading);
}
if (strlen(buffer) > 0 && !cstr_ends_with(buffer, "/"))
{
strcat(buffer, "/");
}
strcat(buffer, trailing);
return buffer;
}
/**
* \brief Compute the relative path between two locations.
* \param base The base path.
* \param target The target path.
* \returns A relative path from the base to the target.
*/
char* path_relative(const char* base, const char* target)
{
int start, i;
char* result;
/* normalize the two paths */
char* full_base = path_absolute(base);
char* full_targ = path_absolute(target);
strcat(full_base, "/");
strcat(full_targ, "/");
/* trim off the common directories from the start */
for (start = 0, i = 0; full_base[i] && full_targ[i] && full_base[i] == full_targ[i]; ++i)
{
if (full_base[i] == '/')
start = i + 1;
}
/* same directory? */
if (full_base[i] == 0 && full_targ[i] == 0)
return ".";
/* build a connecting path */
result = buffers_next();
if (strlen(full_base) - start > 0)
{
strcpy(result, "../");
for (i = start; full_base[i]; ++i)
{
if (full_base[i] == '/' && full_base[i + 1])
strcat(result, "../");
}
}
if (strlen(full_targ) - start > 0)
{
strcat(result, full_targ + start);
}
/* remove the trailing slash */
result[strlen(result) - 1] = 0;
if (strlen(result) == 0)
strcpy(result, ".");
return result;
}
/**
* Replace all path separator characters in a path.
* \param path The path to translate.
* \param sep The desired separator, or NULL for the platform's native separator.
* \returns The translated path.
*/
char* path_translate(const char* path, const char* sep)
{
char* ptr;
char* buffer;
assert(path);
buffer = buffers_next();
if (sep == NULL)
{
#if defined(PLATFORM_WINDOWS)
sep = "\\";
#else
sep = "/";
#endif
}
strcpy(buffer, path);
for (ptr = buffer; *ptr; ++ptr)
{
if (*ptr == '/' || *ptr == '\\')
*ptr = *sep;
}
return buffer;
}

View File

@ -1,29 +0,0 @@
/**
* \file path.h
* \brief Path handling.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*
* \defgroup path Path
* \ingroup base
*
* Path manipulation functions.
*
* @{
*/
#if !defined(PREMAKE_PATH_H)
#define PREMAKE_PATH_H
char* path_absolute(const char* path);
char* path_assemble(const char* dir, const char* filename, const char* ext);
char* path_basename(const char* path);
char* path_directory(const char* path);
char* path_extension(const char* path);
char* path_filename(const char* path);
int path_is_absolute(const char* path);
int path_is_cpp_source(const char* path);
char* path_join(const char* leading, const char* trailing);
char* path_relative(const char* base, const char* target);
char* path_translate(const char* path, const char* sep);
#endif
/** @} */

229
src/base/path.lua Normal file
View File

@ -0,0 +1,229 @@
--
-- path.lua
-- Path manipulation functions.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project
--
path = { }
--
-- Get the absolute file path from a relative path. The requested
-- file path doesn't actually need to exist.
--
function path.getabsolute(p)
-- normalize the target path
p = path.translate(p, "/")
if (p == "") then p = "." end
-- if the directory is already absolute I don't need to do anything
if (path.isabsolute(p)) then
return p
end
-- split up the supplied relative path and tackle it bit by bit
local result = os.getcwd()
for _,part in ipairs(p:explode("/", true)) do
if (part == "..") then
result = path.getdirectory(result)
elseif (part ~= ".") then
result = result .. "/" .. part
end
end
return result
end
--
-- Retrieve the filename portion of a path, without any extension.
--
function path.getbasename(p)
local name = path.getname(p)
local i = name:findlast(".", true)
if (i) then
return name:sub(1, i - 1)
else
return name
end
end
--
-- Retrieve the directory portion of a path, or an empty string if
-- the path does not include a directory.
--
function path.getdirectory(p)
local i = p:findlast("/", true)
if (i) then
if i > 1 then i = i - 1 end
return p:sub(1, i)
else
return "."
end
end
--
-- Retrieve the file extension.
--
function path.getextension(p)
local i = p:findlast(".", true)
if (i) then
return p:sub(i)
else
return ""
end
end
--
-- Retrieve the filename portion of a path.
--
function path.getname(p)
local i = p:findlast("/", true)
if (i) then
return p:sub(i + 1)
else
return p
end
end
--
-- Returns the relative path from src to dest.
--
function path.getrelative(src, dst)
local result = ""
-- normalize the two paths
src = path.getabsolute(src) .. "/"
dst = path.getabsolute(dst) .. "/"
-- same directory?
if (src == dst) then
return "."
end
-- trim off the common directories from the front
local i = src:find("/")
while (i) do
if (src:sub(1,i) == dst:sub(1,i)) then
src = src:sub(i + 1)
dst = dst:sub(i + 1)
else
break
end
i = src:find("/")
end
-- back up from dst to get to this common parent
i = src:find("/")
while (i) do
result = result .. "../"
i = src:find("/", i + 1)
end
-- tack on the path down to the dst from here
result = result .. dst
-- remove the trailing slash
return result:sub(1, -2)
end
--
-- Returns true if the path is absolute.
--
function path.isabsolute(p)
local ch1 = p:sub(1,1)
local ch2 = p:sub(2,2)
return (ch1 == "/" or ch1 == "\\" or ch2 == ":")
end
--
-- Returns true if the filename represents a C/C++ source code file. This check
-- is used to prevent passing non-code files to the compiler in makefiles. It is
-- not foolproof, but it has held up well. I'm open to better suggestions.
--
function path.iscfile(fname)
local extensions = { ".c", ".s" }
local ext = path.getextension(fname):lower()
return table.contains(extensions, ext)
end
function path.iscppfile(fname)
local extensions = { ".cc", ".cpp", ".cxx", ".c", ".s" }
local ext = path.getextension(fname):lower()
return table.contains(extensions, ext)
end
--
-- Returns true if the filename represents a Windows resource file. This check
-- is used to prevent passing non-resources to the compiler in makefiles.
--
function path.isresourcefile(fname)
local extensions = { ".rc" }
local ext = path.getextension(fname):lower()
return table.contains(extensions, ext)
end
--
-- Join two pieces of a path together into a single path.
--
function path.join(leading, trailing)
if (not leading) then
leading = ""
end
if (not trailing) then
return leading
end
if (path.isabsolute(trailing)) then
return trailing
end
if (leading == ".") then
leading = ""
end
if (leading:len() > 0 and not leading:endswith("/")) then
leading = leading .. "/"
end
return leading .. trailing
end
--
-- Convert the separators in a path from one form to another. If `sep`
-- is nil, then a platform-specific separator is used.
--
function path.translate(p, sep)
if (not sep) then
if (os.windows) then
sep = "\\"
else
sep = "/"
end
end
return p:gsub("[/\\]", sep)
end

121
src/base/premake.lua Normal file
View File

@ -0,0 +1,121 @@
--
-- premake.lua
-- Main (top level) application logic for Premake.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project
--
--
-- Check the specified tools (/cc, /csc, etc.) against the current action
-- to make sure they are compatible and supported.
--
function premake.checktools()
local action = premake.actions[_ACTION]
if (not action.valid_tools) then
return true
end
for tool, values in pairs(action.valid_tools) do
if (_OPTIONS[tool]) then
if (not table.contains(values, _OPTIONS[tool])) then
return nil, "the " .. action.shortname .. " action does not support /" .. tool .. "=" .. _OPTIONS[tool]
end
else
_OPTIONS[tool] = values[1]
end
end
return true
end
--
-- Check to see if the value exists in a list of values, using a
-- case-insensitive match. If the value does exist, the canonical
-- version contained in the list is returned, so future tests can
-- use case-sensitive comparisions.
--
function premake.checkvalue(value, allowed)
if (allowed) then
for _,v in ipairs(allowed) do
if (value:lower() == v:lower()) then
return v
end
end
else
return value
end
end
--
-- Fire a particular action. Generates the output files from the templates
-- listed in the action descriptor, and calls any registered handler functions.
--
function premake.doaction(name)
local action = premake.actions[name]
-- walk the session objects and generate files from the templates
local function generatefiles(this, templates)
if (templates) then
for _,tmpl in ipairs(templates) do
local fname = premake.getoutputname(this, tmpl[1])
premake.template.generate(tmpl[2], fname, this)
end
end
end
for _,sln in ipairs(_SOLUTIONS) do
generatefiles(sln, action.solutiontemplates)
for prj in premake.project.projects(sln) do
generatefiles(prj, action.projecttemplates)
end
end
if (action.execute) then
action.execute()
end
end
--
-- Returns a list of all of the active terms from the current environment.
--
local _terms
function premake.getactiveterms()
if (not _terms) then
_terms = { }
table.insert(_terms, _ACTION)
table.insert(_terms, _OS)
for k,_ in pairs(_OPTIONS) do
table.insert(_terms, k)
end
end
return _terms
end
--
-- Converts a project object and a template filespec (the first value in an
-- action's template reference) into a filename for that template's output.
-- The filespec may be either a file extension, or a function.
--
function premake.getoutputname(this, namespec)
local fname
if (type(namespec) == "function") then
fname = namespec(this)
else
fname = this.name .. namespec
end
return path.join(this.location, fname)
end

540
src/base/project.lua Normal file
View File

@ -0,0 +1,540 @@
--
-- projects.lua
-- Implementations of the solution() and project() functions.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project
--
premake.project = { }
--
-- Performs a sanity check all all of the solutions and projects
-- in the session to be sure they meet some minimum requirements.
--
function premake.project.checkall()
local action = premake.actions[_ACTION]
for _,sln in ipairs(_SOLUTIONS) do
-- every solution must have at least one project
if (#sln.projects == 0) then
return nil, "solution '" .. sln.name .. "' needs at least one project"
end
-- every solution must list configurations
if (not sln.configurations or #sln.configurations == 0) then
return nil, "solution '" .. sln.name .. "' needs configurations"
end
for _,prj in ipairs(sln.projects) do
local cfg = premake.project.getconfig(prj)
-- every project must have a language
if (not cfg.language) then
return nil, "project '" ..prj.name .. "' needs a language"
end
-- and the action must support it
if (action.valid_languages) then
if (not table.contains(action.valid_languages, cfg.language)) then
return nil, "the " .. action.shortname .. " action does not support " .. cfg.language .. " projects"
end
end
for _,cfgname in ipairs(sln.configurations) do
cfg = premake.project.getconfig(prj, cfgname)
-- every config must have a kind
if (not cfg.kind) then
return nil, "project '" ..prj.name .. "' needs a kind in configuration '" .. cfgname .. "'"
end
-- and the action must support it
if (action.valid_kinds) then
if (not table.contains(action.valid_kinds, cfg.kind)) then
return nil, "the " .. action.shortname .. " action does not support " .. cfg.kind .. " projects"
end
end
end
end
end
return true
end
--
-- Checks an active set of "terms" against a keyword set. Keywords may use
-- Lua's pattern matching syntax. Comparisions are case-insensitve. Returns
-- true if every keyword matches at least one term, false otherwise. This
-- feature is used to filter the list of configuration blocks to a
-- particular build or platform.
--
function premake.project.checkterms(terms, keywords)
local function test(kw)
for _,term in pairs(terms) do
if (term:match(kw)) then return true end
end
end
for _,kw in ipairs(keywords) do
-- make keyword pattern case insensitive
kw = kw:gsub("(%%*)(%a)",
function (p,a)
if (p:len() % 2 == 1) then
return p..a
else
return p.."["..a:upper()..a:lower().."]"
end
end)
-- match it to a term
if (not test(kw)) then
return false
end
end
return true
end
--
-- Returns an iterator for a project's configurations.
--
function premake.project.configs(prj)
local i = 0
local t = prj.solution.configurations
return function ()
i = i + 1
if (i <= #t) then
prj.filter.config = t[i]
return premake.project.getconfig(prj, t[i])
else
prj.filter.config = nil
end
end
end
--
-- Locate a project by name; case insensitive.
--
function premake.project.find(name)
name = name:lower()
for _, sln in ipairs(_SOLUTIONS) do
for _, prj in ipairs(sln.projects) do
if (prj.name:lower() == name) then
return prj
end
end
end
end
--
-- Build a configuration object holding all of the settings that
-- match the specified filters.
--
function premake.project.getconfig(prj, cfgname)
-- see if this configuration has already been built and cached
local cachekey = cfgname or ""
local meta = getmetatable(prj)
local cfg = meta.__cfgcache[cachekey]
if (cfg) then
return cfg
end
-- prepare the list of active terms
local terms = premake.getactiveterms()
terms.config = cfgname
local function copyfields(cfg, this)
for field,value in pairs(this) do
if (not table.contains(premake.project.nocopy, field)) then
if (type(value) == "table") then
if (not cfg[field]) then cfg[field] = { } end
table.append(cfg[field], value)
else
cfg[field] = value
end
end
end
end
-- fields are copied first from the solution, then the solution's configs,
-- then from the project, then the project's configs. Each can overwrite
-- or add to the values set previously. The objdir field gets special
-- treatment, in order to provide a project-level default and still enable
-- solution-level overrides
local cfg = { }
copyfields(cfg, prj.solution)
for _,blk in ipairs(prj.solution.blocks) do
if (premake.project.checkterms(terms, blk.keywords)) then
copyfields(cfg, blk)
end
end
copyfields(cfg, prj)
if (not cfg.objdir) then cfg.objdir = path.join(prj.basedir, "obj") end
for _,blk in ipairs(prj.blocks) do
if (premake.project.checkterms(terms, blk.keywords)) then
copyfields(cfg, blk)
end
end
-- remove excluded files
local files = { }
for _, fname in ipairs(cfg.files) do
local excluded = false
for _, exclude in ipairs(cfg.excludes) do
excluded = (fname == exclude)
if (excluded) then break end
end
if (not excluded) then
table.insert(files, fname)
end
end
cfg.files = files
-- fix up paths, making them relative to project location where needed
for _,key in ipairs(premake.project.locationrelative) do
if (type(cfg[key]) == "table") then
for i,p in ipairs(cfg[key]) do
cfg[key][i] = path.getrelative(prj.location, p)
end
else
if (cfg[key]) then
cfg[key] = path.getrelative(prj.location, cfg[key])
end
end
end
cfg.name = cfgname
cfg.project = prj
-- precompute common calculated values
cfg.target = premake.project.gettargetfile(cfg, "target", cfg.kind)
meta.__cfgcache[cachekey] = cfg
return cfg
end
--
-- Returns the list of targets, matching the current configuration,
-- for any dependent sibling projects.
--
function premake.project.getdependencies(cfg)
local siblings = { }
for _, link in ipairs(cfg.links) do
-- is ths a sibling project?
local prj = premake.project.find(link)
if (prj) then
table.insert(siblings, link)
end
end
return siblings
end
--
-- Converts the values in a configuration "links" field into a list
-- library files to be linked. Converts project names to the correct
-- target for the current configuration.
--
function premake.project.getlibraries(cfg, list)
local libs = { }
for _, link in ipairs(list) do
-- is ths a sibling project?
local prj = premake.project.find(link)
if (prj) then
local target
-- figure out the target name
local prjcfg = premake.project.getconfig(prj, cfg.name)
if (prjcfg.kind == "SharedLib" and os.is("windows")) then
target = premake.project.gettargetfile(prjcfg, "implib", prjcfg.kind)
else
target = prjcfg.target
end
-- target is currently relative to its project location, make
-- it relative to my location instead
target = path.getabsolute(path.join(prjcfg.location, target))
target = path.getrelative(cfg.location, target)
table.insert(libs, target)
else
table.insert(libs, link)
end
end
return libs
end
--
-- Return an object directory that is unique across the entire session.
--
function premake.project.getobjdir(cfg)
if (premake.project.isuniquevalue("objdir", cfg.objdir)) then
return cfg.objdir
end
local fn = function (cfg) return path.join(cfg.objdir, cfg.name) end
local objdir = fn(cfg)
if (premake.project.isuniquevalue("objdir", objdir, fn)) then
return objdir
end
return path.join(cfg.objdir, cfg.project.name .. "/" .. cfg.name)
end
--
-- Retrieve the current object of the a particular type from the session.
-- The type may be "solution", "container" (the last activated solution or
-- project), or "config" (the last activated configuration). Returns the
-- requested container, or nil and an error message.
--
function premake.project.getobject(t)
local container
if (t == "container" or t == "solution") then
container = premake.CurrentContainer
else
container = premake.CurrentConfiguration
end
if (t == "solution" and type(container) ~= "solution") then
container = nil
end
local msg
if (not container) then
if (t == "container") then
msg = "no active solution or project"
elseif (t == "solution") then
msg = "no active solution"
else
msg = "no active solution, project, or configuration"
end
end
return container, msg
end
--
-- Builds a platform specific target (executable, library) file name of a
-- specific type, using the information from a project configuration.
--
function premake.project.gettargetfile(cfg, field, kind, os)
if (not os) then os = _OPTIONS.os or _OS end
local name = cfg[field.."name"] or cfg.targetname or cfg.project.name
local dir = cfg[field.."dir"] or cfg.targetdir or cfg.basedir
local prefix = ""
local extension = ""
if (os == "windows") then
if (kind == "ConsoleExe" or kind == "WindowedExe") then
extension = ".exe"
elseif (kind == "SharedLib") then
extension = ".dll"
elseif (kind == "StaticLib") then
extension = ".lib"
end
elseif (os == "macosx" and kind == "WindowedExe") then
name = name .. ".app/Contents/MacOS/" .. name
else
if (kind == "SharedLib") then
prefix = "lib"
extension = ".so"
elseif (kind == "StaticLib") then
prefix = "lib"
extension = ".a"
end
end
prefix = cfg[field.."prefix"] or prefix
extension = cfg[field.."extension"] or extension
return path.join(dir, prefix .. name .. extension)
end
--
-- Determines if a field value is unique across all configurations of
-- all projects in the session. Used to create unique output targets.
--
function premake.project.isuniquevalue(fieldname, value, fn)
local count = 0
for _, sln in ipairs(_SOLUTIONS) do
for _, prj in ipairs(sln.projects) do
for _, cfgname in ipairs(sln.configurations) do
local cfg = premake.project.getconfig(prj, cfgname)
local tst
if (fn) then
tst = fn(cfg)
else
tst = cfg[fieldname]
end
if (tst == value) then
count = count + 1
if (count > 1) then return false end
end
end
end
end
return true
end
--
-- Returns an iterator for a solution's projects.
--
function premake.project.projects(sln)
local i = 0
return function ()
i = i + 1
if (i <= #sln.projects) then
local prj = sln.projects[i]
-- merge solution and project values
local merged = premake.project.getconfig(prj)
setmetatable(merged, getmetatable(prj))
merged.name = prj.name
merged.blocks = prj.blocks
return merged
end
end
end
--
-- Adds values to an array field of a solution/project/configuration. `ctype`
-- specifies the container type (see premake.getobject) for the field.
--
function premake.project.setarray(ctype, fieldname, value, allowed)
local container, err = premake.project.getobject(ctype)
if (not container) then
error(err, 3)
end
if (not container[fieldname]) then
container[fieldname] = { }
end
local function doinsert(value)
if (type(value) == "table") then
for _,v in ipairs(value) do
doinsert(v)
end
else
local v = premake.checkvalue(value, allowed)
if (not v) then error("invalid value '" .. value .. "'", 3) end
table.insert(container[fieldname], v)
end
end
if (value) then
doinsert(value)
end
return container[fieldname]
end
--
-- Adds values to an array-of-directories field of a solution/project/configuration.
-- `ctype` specifies the container type (see premake.getobject) for the field. All
-- values are converted to absolute paths before being stored.
--
local function domatchedarray(ctype, fieldname, value, matchfunc)
local result = { }
function makeabsolute(arr)
for i,value in ipairs(arr) do
if (type(value) == "table") then
makeabsolute(value)
else
if value:find("*") then
makeabsolute(matchfunc(value))
else
table.insert(result, path.getabsolute(value))
end
end
end
end
makeabsolute(value)
return premake.project.setarray(ctype, fieldname, result)
end
function premake.project.setdirarray(ctype, fieldname, value)
return domatchedarray(ctype, fieldname, value, os.matchdirs)
end
function premake.project.setfilearray(ctype, fieldname, value)
return domatchedarray(ctype, fieldname, value, os.matchfiles)
end
--
-- Set a new value for a string field of a solution/project/configuration. `ctype`
-- specifies the container type (see premake.project.getobject) for the field.
--
function premake.project.setstring(ctype, fieldname, value, allowed)
-- find the container for this value
local container, err = premake.project.getobject(ctype)
if (not container) then
error(err, 3)
end
-- if a value was provided, set it
if (value) then
local v = premake.checkvalue(value, allowed)
if (not v) then error("invalid value '" .. value .. "'", 3) end
container[fieldname] = v
end
return container[fieldname]
end

View File

@ -1,330 +0,0 @@
/**
* \file stream.c
* \brief Output stream handling.
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "premake.h"
#include "base/error.h"
#include "base/dir.h"
#include "base/path.h"
#include "base/stream.h"
DEFINE_CLASS(Stream)
{
FILE* file;
const char* newline;
char* buffer;
};
static struct Stream_impl Console_impl = { NULL, "\n", NULL };
/**
* The console output stream.
* Use the stream_write() functions and this stream object instead
* of the usual C functions like printf(). The stream functions have
* more features -- such as setting the line ending sequence -- and
* can be captured for automated testing.
*/
Stream Console = &Console_impl;
/**
* Create a new file output stream, overwriting any existing file.
* \param filename The name of the file to create.
* \returns A new file stream.
*/
Stream stream_create_file(const char* filename)
{
Stream strm;
const char* dirname;
FILE* file;
/* make sure the directory exists before writing to it */
dirname = path_directory(filename);
if (dir_create(dirname) != OKAY)
{
return NULL;
}
/* create the file */
file = fopen(filename, "wb");
if (file == NULL)
{
error_set("Unable to open file %s", filename);
return NULL;
}
/* build the stream object */
strm = stream_create_null();
strm->file = file;
return strm;
}
/**
* Create a "null" stream, which discards any writes; intended for automated testing.
* \returns A new stream object.
*/
Stream stream_create_null()
{
Stream strm = ALLOC_CLASS(Stream);
strm->file = NULL;
strm->newline = "\n";
strm->buffer = NULL;
return strm;
}
/**
* Close a stream and release the associated memory.
* \param strm The stream to close.
*/
void stream_destroy(Stream strm)
{
assert(strm);
if (strm != Console)
{
if (strm->file != NULL)
{
fclose(strm->file);
}
free(strm);
}
}
/**
* Capture the text written to a stream into a buffer.
* When a stream is captured all text is written to the buffer, and
* output to the associated file is blocked.
* \param strm The stream to capture.
* \param buffer The buffer to contain the captured text. No checks are made
* on the size of the buffer while writing, so use carefully.
* May be NULL to disable buffering.
*/
void stream_set_buffer(Stream strm, char* buffer)
{
assert(strm);
strm->buffer = buffer;
strm->buffer[0] = '\0';
}
/**
* Set the newline character sequence.
* \param strm The stream to set.
* \param newline The EOL sequence.
*/
void stream_set_newline(Stream strm, const char* newline)
{
assert(strm);
strm->newline = newline;
}
/**
* Write a formatted list of strings.
* \param strm The stream to which to write.
* \param strs The list of strings to write.
* \param start The start string, always written first, even if there are no items in the list.
* \param prefix A prefix string, to be written before each item.
* \param postfix A postfix string, to be written after each item.
* \param infix An infix strings, to write between items, after the
* previous postfix string and before the next prefix.
* \param end The end string, always written last, even if there are no items in the list.
* \param writer A callback function to handle output of each list item.
* \returns OKAY if successful.
*/
int stream_write_strings(Stream strm, Strings strs, const char* start, const char* prefix, const char* postfix, const char* infix, const char* end, StreamWriterFunc writer)
{
int i, n, z;
z = stream_write(strm, start);
n = strings_size(strs);
for (i = 0; i < n; ++i)
{
const char* value = strings_item(strs, i);
if (i > 0) z |= stream_write(strm, infix);
z |= stream_write(strm, prefix);
if (writer != NULL)
{
z |= writer(strm, value);
}
else
{
z |= stream_write(strm, value);
}
z |= stream_write(strm, postfix);
}
z |= stream_write(strm, end);
return z;
}
/**
* Write a formatted list of strings, followed by a newline.
* \param strm The stream to which to write.
* \param strs The list of strings to write.
* \param start The start string, always written first, even if there are no items in the list.
* \param prefix A prefix string, to be written before each item.
* \param postfix A postfix string, to be written after each item.
* \param infix An infix strings, to write between items, after the
* previous postfix string and before the next prefix.
* \param end The end string, always written last, even if there are no items in the list.
* \param writer A callback function to handle output of each list item.
* \returns OKAY if successful.
*/
int stream_writeline_strings(Stream strm, Strings strs, const char* start, const char* prefix, const char* postfix, const char* infix, const char* end, StreamWriterFunc writer)
{
int z = OKAY;
z |= stream_write_strings(strm, strs, start, prefix, postfix, infix, end, writer);
z |= stream_writeline(strm, "");
return z;
}
/**
* Format and print a string using printf-style codes and a variable argument list.
* \param strm The stream to which to write.
* \param value The value to print; may contain printf-style formatting codes.
* \param args A variable argument list to populate the printf-style codes in `value`.
* \returns OKAY if successful.
*/
int stream_vprintf(Stream strm, const char* value, va_list args)
{
if (strm->buffer)
{
/* write to the end of the current contents of the buffer */
char* start = strm->buffer + strlen(strm->buffer);
vsprintf(start, value, args);
}
else if (strm == Console)
{
vfprintf(stdout, value, args);
}
else if (strm->file)
{
vfprintf(strm->file, value, args);
}
return OKAY;
}
/**
* Write a string value to a stream.
* \param strm The stream.
* \param value The value to append to the stream.
* \returns OKAY is successful.
*/
int stream_write(Stream strm, const char* value, ...)
{
int status;
va_list args;
va_start(args, value);
status = stream_vprintf(strm, value, args);
va_end(args);
return status;
}
/**
* Write a string value to a stream, applying XML escape codes in the process.
* \param strm The stream to which to write.
* \param value The string to write.
* \returns OKAY if successful.
*/
int stream_write_escaped(Stream strm, const char* value)
{
const char* ptr;
char buffer[2];
int z = OKAY;
buffer[1] = '\0';
for (ptr = value; *ptr != '\0'; ++ptr)
{
switch (*ptr)
{
case '\"':
z |= stream_write(strm, "&quot;");
break;
case '&':
z |= stream_write(strm, "&amp;");
break;
case '\'':
z |= stream_write(strm, "&apos;");
break;
case '<':
z |= stream_write(strm, "&lt;");
break;
case '>':
z |= stream_write(strm, "&gt;");
break;
default:
z |= stream_write(strm, "%c", *ptr);
break;
}
}
return z;
}
/**
* Write N copies of a string to a stream.
* \param strm The stream to which to write.
* \param value The string to write.
* \param n The number of copies to write.
* \returns OKAY if successful.
*/
int stream_write_n(Stream strm, const char* value, int n)
{
int i, z = OKAY;
for (i = 0; i < n; ++i)
{
z |= stream_write(strm, value);
}
return z;
}
/**
* Writes the Unicode encoding marker sequence into the stream.
* \param strm The stream to which to write.
*/
int stream_write_unicode_marker(Stream strm)
{
return stream_write(strm, "\357\273\277");
}
/**
* Write a string value, followed by a newline, to a stream.
* \param strm The stream.
* \param value The value to append to the stream.
* \returns OKAY if successful.
*/
int stream_writeline(Stream strm, const char* value, ...)
{
int status;
va_list args;
va_start(args, value);
status = stream_vprintf(strm, value, args);
status |= stream_write(strm, strm->newline);
va_end(args);
return status;
}

View File

@ -1,40 +0,0 @@
/**
* \file stream.h
* \brief Output stream handling.
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
*
* \defgroup stream Streams
* \ingroup base
*
* An output stream class.
*
* @{
*/
#if !defined(PREMAKE_STREAM_H)
#define PREMAKE_STREAM_H
#include <stdarg.h>
#include "strings.h"
DECLARE_CLASS(Stream);
extern Stream Console;
typedef int (*StreamWriterFunc)(Stream strm, const char *value);
Stream stream_create_file(const char* filename);
Stream stream_create_null(void);
void stream_destroy(Stream stream);
void stream_set_buffer(Stream strm, char* buffer);
void stream_set_newline(Stream strm, const char* newline);
int stream_vprintf(Stream strm, const char* value, va_list args);
int stream_write(Stream strm, const char* value, ...);
int stream_write_escaped(Stream strm, const char* value);
int stream_write_n(Stream strm, const char* value, int n);
int stream_write_strings(Stream strm, Strings strs, const char* start, const char* prefix, const char* postfix, const char* infix, const char* end, StreamWriterFunc writer);
int stream_write_unicode_marker(Stream strm);
int stream_writeline(Stream strm, const char* value, ...);
int stream_writeline_strings(Stream strm, Strings strs, const char* start, const char* prefix, const char* postfix, const char* infix, const char* end, StreamWriterFunc writer);
#endif
/** @} */

View File

@ -1,67 +0,0 @@
/**
* \file string.c
* \brief Dynamic string handling.
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
*/
#include <stdlib.h>
#include <string.h>
#include "premake.h"
#include "base/string.h"
DEFINE_CLASS(String)
{
char* contents;
int capacity;
};
/**
* Create a new dynamic string object from an existing C string.
* \param value The C string value.
* \returns A new dynamic string object containing a copy of the string.
*/
String string_create(const char* value)
{
if (value != NULL)
{
String str = ALLOC_CLASS(String);
str->capacity = strlen(value) + 1;
str->contents = (char*)malloc(str->capacity);
strcpy(str->contents, value);
return str;
}
else
{
return NULL;
}
}
/**
* Destroy a dynamic string object and free the associated memory.
* \param str The string to destroy.
*/
void string_destroy(String str)
{
if (str != NULL)
{
free(str->contents);
free(str);
}
}
/**
* Return the contents of a dynamic string as a C string.
* \param str The string to query.
* \returns The C string value.
*/
const char* string_cstr(String str)
{
if (str != NULL)
return str->contents;
else
return NULL;
}

View File

@ -1,23 +0,0 @@
/**
* \file string.h
* \brief Dynamic string handling.
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
*
* \defgroup string Strings
* \ingroup base
*
* A dynamic string class.
*
* @{
*/
#if !defined(PREMAKE_STRING_H)
#define PREMAKE_STRING_H
DECLARE_CLASS(String);
String string_create(const char* value);
void string_destroy(String str);
const char* string_cstr(String str);
#endif
/** @} */

56
src/base/string.lua Normal file
View File

@ -0,0 +1,56 @@
--
-- string.lua
-- Additions to Lua's built-in string functions.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project
--
--
-- Returns true if `haystack` ends with the sequence `needle`.
--
function string.endswith(haystack, needle)
if (haystack and needle) then
local hlen = haystack:len()
local nlen = needle:len()
if (hlen >= nlen) then
return (haystack:sub(-nlen) == needle)
end
end
return false
end
--
-- Returns an array of strings, each of which is a substring of s
-- formed by splitting on boundaries formed by `pattern`.
--
function string.explode(s, pattern, plain)
if (pattern == '') then return false end
local pos = 0
local arr = { }
for st,sp in function() return s:find(pattern, pos, plain) end do
table.insert(arr, s:sub(pos, st-1))
pos = sp + 1
end
table.insert(arr, s:sub(pos))
return arr
end
--
-- Find the last instance of a pattern in a string.
--
function string.findlast(s, pattern, plain)
local curr = 0
repeat
local next = s:find(pattern, curr + 1, plain)
if (next) then curr = next end
until (not next)
if (curr > 0) then
return curr
end
end

View File

@ -1,158 +0,0 @@
/**
* \file strings.c
* \brief A dynamic array of C strings.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*/
#include <stdlib.h>
#include "premake.h"
#include "strings.h"
#include "base/array.h"
#include "base/cstr.h"
#include "base/string.h"
DEFINE_CLASS(Strings)
{
Array contents;
};
/**
* Create a new dynamic array of C strings.
* \returns A new string array.
*/
Strings strings_create()
{
Strings strs = ALLOC_CLASS(Strings);
strs->contents = array_create();
return strs;
}
/**
* Create a dynamic array of C strings, initialized from an existing array.
* \param items The initial list of items for the strings collection.
* \returns A new string array.
*/
Strings strings_create_from_array(const char* items[])
{
Strings strs = strings_create();
for ( ; *items != NULL; ++items)
{
strings_add(strs, *items);
}
return strs;
}
/**
* Destroy a strings array and free the associated memory.
* \param strs The string array to destroy.
*/
void strings_destroy(Strings strs)
{
int i, n;
n = strings_size(strs);
for (i = 0; i < n; ++i)
{
String item = (String)array_item(strs->contents, i);
if (item != NULL)
{
string_destroy(item);
}
}
array_destroy(strs->contents);
free(strs);
}
/**
* Add a new item to the end of an array of strings.
* \param strs The array of strings.
* \param item The C string item to add.
*/
void strings_add(Strings strs, const char* item)
{
String str = (item != NULL) ? string_create(item) : NULL;
array_add(strs->contents, (void*)str);
}
/**
* Append the contents of one string vector to another.
* \param dest The destination vector.
* \param src The source vector.
*/
void strings_append(Strings dest, Strings src)
{
int i, n;
n = strings_size(src);
for (i = 0; i < n; ++i)
{
const char* item = strings_item(src, i);
strings_add(dest, item);
}
}
/**
* Returns true if the collection contains the specified value.
*/
int strings_contains(Strings strs, const char* item)
{
int i, n;
n = strings_size(strs);
for (i = 0; i < n; ++i)
{
const char* str = strings_item(strs, i);
if (cstr_eqi(str, item))
return 1;
}
return 0;
}
/**
* Retrieve an C string item from an array of strings.
* \param strs The string array to query.
* \param index The index of the item to retrieve.
* \returns A pointer to the C string item.
*/
const char* strings_item(Strings strs, int index)
{
String item = (String)array_item(strs->contents, index);
return (item != NULL) ? string_cstr(item) : NULL;
}
/**
* Set the value at a particular index of the array.
* \param strs The string array.
* \param index The index of the item to set.
* \param item The new item.
*/
void strings_set(Strings strs, int index, const char* item)
{
String str = (String)array_item(strs->contents, index);
if (str != NULL)
{
string_destroy(str);
}
str = (item != NULL) ? string_create(item) : NULL;
array_set(strs->contents, index, (void*)str);
}
/**
* Get the number of items in the string array.
* \param strs The string array to query.
* \returns The number elements currently in the array.
*/
int strings_size(Strings strs)
{
return array_size(strs->contents);
}

View File

@ -1,30 +0,0 @@
/**
* \file strings.h
* \brief A dynamic array of C strings.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*
* \defgroup strings String Collection
* \ingroup base
*
* A dynamic array of C strings.
*
* @{
*/
#if !defined(PREMAKE_STRINGS_H)
#define PREMAKE_STRINGS_H
DECLARE_CLASS(Strings);
Strings strings_create(void);
Strings strings_create_from_array(const char** items);
void strings_destroy(Strings strs);
void strings_add(Strings strs, const char* item);
void strings_append(Strings dest, Strings src);
int strings_contains(Strings strs, const char* item);
const char* strings_item(Strings strs, int index);
void strings_set(Strings strs, int index, const char* item);
int strings_size(Strings strs);
#endif
/** @} */

77
src/base/table.lua Normal file
View File

@ -0,0 +1,77 @@
--
-- table.lua
-- Additions to Lua's built-in table functions.
-- Copyright (c) 2002-2008 Jason Perkins and the Premake project
--
--
-- Adds the values from one array to the end of another.
--
function table.append(dst, src)
for _,v in ipairs(src) do
table.insert(dst, v)
end
end
--
-- Returns true if the table contains the specified value.
--
function table.contains(t, value)
for _,v in pairs(t) do
if (v == value) then
return true
end
end
return false
end
--
-- Enumerates an array of objects and returns a new table containing
-- only the value of one particular field.
--
function table.extract(arr, fname)
local result = { }
for _,v in ipairs(arr) do
table.insert(result, v[fname])
end
return result
end
--
-- Merges an array of items into a string.
--
function table.implode(arr, before, after, between)
local result = ""
for _,v in ipairs(arr) do
if (result ~= "" and between) then
result = result .. between
end
result = result .. before .. v .. after
end
return result
end
--
-- Translates the values contained in array, using the specified
-- translation table, and returns the results in a new array.
--
function table.translate(arr, translation)
local result = { }
for _, value in ipairs(arr) do
table.insert(result, translation[value])
end
return result
end

131
src/base/template.lua Normal file
View File

@ -0,0 +1,131 @@
--
-- template.lua
-- The templating system.
-- Copyright (c) 2008 Jason Perkins and the Premake project
--
premake.template = { }
--
-- Process a literal string, splitting up newlines so that the generated
-- code will match the original template line for line, so error messages
-- can refer to the correct line in the template. Lua's [[ ]] string syntax
-- messes with newlines, making this more complicated than it needs to be.
--
local function literal(str)
local code = ""
for line in str:gmatch("[^\n]*") do
if (line:len() > 0) then
code = code .. "io.write[=[" .. line .. "]=]"
else
code = code .. "io.write(eol)\n"
end
end
return code:sub(1, -15)
end
--
-- Convert a template to Lua script code.
--
function premake.template.encode(tmpl)
code = ""
-- normalize line endings
tmpl = tmpl:gsub("\r\n", "\n")
while (true) do
-- find an escaped block
start, finish = tmpl:find("<%%.-%%>")
if (not start) then break end
local before = tmpl:sub(1, start - 1)
local after = tmpl:sub(finish + 1)
-- get the block type and contents
local block
local isexpr = (tmpl:sub(start + 2, start + 2) == "=")
if (isexpr) then
block = tmpl:sub(start + 3, finish - 2)
else
block = tmpl:sub(start + 2, finish - 2)
end
-- if a statement block, strip out everything else on that line
if (not isexpr) then
finish = before:findlast("\n", true)
if (finish) then before = before:sub(1, finish) end
start = after:find("\n", 1, true)
if (start) then after = after:sub(start + 1) end
end
-- output everything before the block
code = code .. literal(before)
-- output the block itself
if (isexpr) then
code = code .. "io.write(" .. block .. ")"
else
code = code .. block .. "\n"
end
-- do it again, with everything after the block
tmpl = after
end
-- tack on everything after the last block
code = code .. literal(tmpl)
return code
end
--
-- Generate output from a template, provided a filename and an object.
--
function premake.template.generate(tmpl, fname, this)
premake.template.newline = "\\n"
local f, err = io.open(fname, "wb")
if (not f) then
error(err, 0)
end
io.output(f)
tmpl(this)
io.output():close()
end
--
-- Load a template from a string and convert to a template function.
--
function premake.template.loadstring(name, str)
local code = premake.template.encode(str)
local fn, msg = loadstring("return function (this) eol='\\n';" .. code .. " end", name)
if (not fn) then
error(msg, 0)
end
return fn()
end
--
-- Load a template from a file and convert it to a template function.
--
function premake.template.loadfile(fname)
local f = io.open(fname, "rb")
local tmpl = f:read("*a")
f:close()
return premake.template.loadstring(path.getname(fname), tmpl)
end

View File

@ -1,23 +0,0 @@
/**
* \file base_tests.cpp
* \brief Automated tests for Premake base library.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*/
#include "premake.h"
#include "testing/testing.h"
extern "C" {
#include "base/base.h"
}
/**
* \brief Run the base library automated tests.
* \returns OKAY if all tests completed successfully.
*/
int base_tests()
{
int status = tests_run_suite("cstr");
if (status == OKAY) status = tests_run_suite("base");
return status;
}

View File

@ -1,190 +0,0 @@
/**
* \file cstr_tests.cpp
* \brief C string automated tests.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*/
#include "premake.h"
#include "testing/testing.h"
extern "C" {
#include "base/cstr.h"
}
SUITE(cstr)
{
/**************************************************************************
* cstr_contains() tests
**************************************************************************/
TEST(CStrContains_ReturnsTrue_OnMatch)
{
CHECK(cstr_contains("Abcdef", "cd"));
}
TEST(CStrContains_ReturnsFalse_OnMismatch)
{
CHECK(!cstr_contains("Abcdef", "xy"));
}
/**************************************************************************
* cstr_ends_with() tests
**************************************************************************/
TEST(CStrEndsWith_ReturnsTrue_OnMatch)
{
CHECK(cstr_ends_with("Abcdef", "def"));
}
TEST(CStrEndsWith_ReturnsFalse_OnMismatch)
{
CHECK(!cstr_ends_with("Abcdef", "ghi"));
}
TEST(CStrEndsWith_ReturnsFalse_OnLongerNeedle)
{
CHECK(!cstr_ends_with("Abc", "Abcdef"));
}
TEST(CStrEndsWith_ReturnsFalse_OnNullHaystack)
{
CHECK(!cstr_ends_with(NULL, "ghi"));
}
TEST(CStrEndsWith_ReturnsFalse_OnNullNeedle)
{
CHECK(!cstr_ends_with("Abc", NULL));
}
/**************************************************************************
* cstr_eq() tests
**************************************************************************/
TEST(CStrEq_ReturnsTrue_OnMatch)
{
CHECK(cstr_eq("A string", "A string"));
}
TEST(CStrEq_ReturnsFalse_OnMismatch)
{
CHECK(!cstr_eq("A string", "A different string"));
}
TEST(CStrEq_ReturnsFalse_OnNullTarget)
{
CHECK(!cstr_eq(NULL, "something"));
}
TEST(CStrEq_ReturnsFalse_OnNullPattern)
{
CHECK(!cstr_eq("something", NULL));
}
/**************************************************************************
* cstr_eqi() tests
**************************************************************************/
TEST(CStrEqi_ReturnsTrue_OnMatch)
{
CHECK(cstr_eqi("A string", "a String"));
}
TEST(CStrEqi_ReturnsFalse_OnMismatch)
{
CHECK(!cstr_eqi("A string", "a different string"));
}
TEST(CStrEqi_ReturnsFalse_OnNullTarget)
{
CHECK(!cstr_eqi(NULL, "something"));
}
TEST(CStrEqi_ReturnsFalse_OnNullPattern)
{
CHECK(!cstr_eqi("something", NULL));
}
/**************************************************************************
* cstr_format() tests
**************************************************************************/
TEST(CstrFormat_ReturnsFormatted)
{
char* result = cstr_format("$(OBJDIR)/%s.o", "hello");
CHECK_EQUAL("$(OBJDIR)/hello.o", result);
}
/**************************************************************************
* cstr_matches_pattern() tests
**************************************************************************/
TEST(CStrMatchesPattern_ReturnsTrue_OnMatch)
{
CHECK(cstr_matches_pattern("01234", "%d*"));
}
TEST(CStrMatchesPattern_ReturnsFalse_OnNonMatch)
{
CHECK(!cstr_matches_pattern("01234", "%a*"));
}
TEST(CStrMatchesPattern_ReturnsTrue_OnCaseMismatch)
{
CHECK(cstr_matches_pattern("Debug", "debug"));
}
/**************************************************************************
* cstr_starts_with() tests
**************************************************************************/
TEST(CStrStartsWith_ReturnsTrue_OnMatch)
{
CHECK(cstr_starts_with("Abcdef", "Abc"));
}
TEST(CStrStartsWith_ReturnsFalse_OnMismatch)
{
CHECK(!cstr_starts_with("Abcdef", "ghi"));
}
TEST(CStrStartsWith_ReturnsFalse_OnLongerNeedle)
{
CHECK(!cstr_starts_with("Abc", "Abcdef"));
}
TEST(CStrStartsWith_ReturnsFalse_OnNullHaystack)
{
CHECK(!cstr_starts_with(NULL, "ghi"));
}
TEST(CStrStartsWith_ReturnsFalse_OnNullNeedle)
{
CHECK(!cstr_starts_with("Abc", NULL));
}
/**********************************************************************
* cstr_trim() tests
**********************************************************************/
TEST(CStrTrim_DoesNothing_OnNoMatch)
{
char buffer[32];
strcpy(buffer, "Msg");
cstr_trim(buffer, '/');
CHECK_EQUAL("Msg", buffer);
}
TEST(CStrTrim_DoesTrim_OnMatch)
{
char buffer[32];
strcpy(buffer, "Msg///");
cstr_trim(buffer, '/');
CHECK_EQUAL("Msg", buffer);
}
}

View File

@ -1,27 +0,0 @@
/**
* \file dir_tests.cpp
* \brief Directory handling automated tests.
* \author Copyright (c) 2002-2008 Jason Perkins and the Premake project
*/
#include "premake.h"
#include "testing/testing.h"
extern "C" {
#include "base/dir.h"
#include "base/cstr.h"
}
SUITE(base)
{
TEST(DirExists_ReturnsOkay_OnEmptyPath)
{
int result = dir_exists("");
CHECK(result);
}
TEST(DirGetCurrent_ReturnsCurrent_WithSlashes)
{
const char* result = dir_get_current();
CHECK(cstr_ends_with(result, "/src"));
}
}

View File

@ -1,28 +0,0 @@
/**
* \file env_tests.cpp
* \brief Automated tests from runtime environment state.
* \author Copyright (c) 2008 Jason Perkins and the Premake project
*/
#include "premake.h"
#include "testing/testing.h"
extern "C" {
#include "base/env.h"
}
SUITE(base)
{
TEST(EnvGetOs_IsNotUnknown)
{
enum OS os = env_get_os();
CHECK(os != UnknownOS);
}
TEST(EnvGetOsName_DoesNotExplode)
{
const char* name = env_get_os_name();
CHECK(name != NULL);
}
}

View File

@ -1,86 +0,0 @@
/**
* \file guid_tests.cpp
* \brief Automated tests for GUID generation and validation.
* \author Copyright (c) 2008 Jason Perkins and the Premake project
*/
#include "premake.h"
#include "testing/testing.h"
extern "C" {
#include "base/guid.h"
}
SUITE(base)
{
TEST(GuidCreate_ReturnsCorrectSize)
{
const char* guid = guid_create();
CHECK(guid != NULL && strlen(guid) == 36);
}
TEST(GuidCreate_CorrectDashes)
{
const char* guid = guid_create();
CHECK(guid[8]=='-' && guid[13]=='-' && guid[18]=='-' && guid[23]=='-');
}
TEST(GuidCreate_CorrectSymbols)
{
for (const char* guid = guid_create(); *guid; ++guid)
{
const char ch = *guid;
CHECK((ch>='0' && ch<='9') || (ch>='A' && ch<='F') || (ch=='-'));
}
}
TEST(GuidCreate_CorrectNumOfDashes)
{
int num = 0;
for (const char* guid = guid_create(); *guid; ++guid)
{
if (*guid=='-') ++num;
}
CHECK(num == 4);
}
TEST(GuidIsValid_ReturnsTrue_OnNoBraces)
{
CHECK(guid_is_valid("4E67EBCE-BC8B-4058-9AA9-48EE5E003683"));
}
TEST(GuidIsValid_ReturnsFalse_OnTooShort)
{
CHECK(!guid_is_valid("4E67EBCE-BC8B-4058-9AA9-48EE"));
}
TEST(GuidIsValid_ReturnsFalse_OnMissingFirstDash)
{
CHECK(!guid_is_valid("4E67EBCE BC8B-4058-9AA9-48EE5E003683"));
}
TEST(GuidIsValid_ReturnsFalse_OnMissingSecondDash)
{
CHECK(!guid_is_valid("4E67EBCE-BC8B 4058-9AA9-48EE5E003683"));
}
TEST(GuidIsValid_ReturnsFalse_OnMissingThirdDash)
{
CHECK(!guid_is_valid("4E67EBCE-BC8B-4058 9AA9-48EE5E003683"));
}
TEST(GuidIsValid_ReturnsFalse_OnMissingLastDash)
{
CHECK(!guid_is_valid("4E67EBCE-BC8B-4058-9AA9 48EE5E003683"));
}
TEST(GuidIsValid_ReturnsFalse_OnTooManyDashes)
{
CHECK(!guid_is_valid("4E67EBCE-BC8B-4058-9AA9-48EE5-003683"));
}
TEST(GuidIsValid_ReturnsFalse_OnInvalidChar)
{
CHECK(!guid_is_valid("XE67EBCE-BC8B-4058-9AA9-48EE5X003683"));
}
}

View File

@ -1,266 +0,0 @@
/**
* \file path_tests.cpp
* \brief Path handling automated tests.
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
*/
#include "premake.h"
#include "testing/testing.h"
extern "C" {
#include "base/path.h"
#include "base/cstr.h"
#include "base/dir.h"
#include "platform/platform.h"
}
SUITE(base)
{
/**************************************************************************
* path_absolute() tests
**************************************************************************/
TEST(PathAbsolute_ReturnsCorrectPath_OnMissingSubdir)
{
char* cwd = dir_get_current();
strcat(cwd, "/a/b/c");
char* result = path_absolute("a/b/c");
CHECK_EQUAL(cwd, result);
}
/**************************************************************************
* path_assemble() tests
**************************************************************************/
TEST(PathAssemble_ReturnsAssembledPath_OnValidParts)
{
char* result = path_assemble("directory", "filename", ".ext");
CHECK_EQUAL("directory/filename.ext", result);
}
TEST(PathAssemble_ReturnsAssembledPath_OnNoDirectory)
{
char* result = path_assemble("", "filename", ".ext");
CHECK_EQUAL("filename.ext", result);
}
/**************************************************************************
* path_basename() tests
**************************************************************************/
TEST(PathBaseName_ReturnsBase_OnDirAndExt)
{
char* result = path_basename("folder/filename.ext");
CHECK_EQUAL("filename", result);
}
/**************************************************************************
* path_directory() tests
**************************************************************************/
TEST(PathDirectory_ReturnsEmptyString_OnNoDirectory)
{
char* result = path_directory("filename.ext");
CHECK_EQUAL("", result);
}
TEST(PathDirectory_ReturnsDirectory_OnSingleLevelPath)
{
char* result = path_directory("dir0/filename.ext");
CHECK_EQUAL("dir0", result);
}
TEST(PathDirectory_ReturnsDirectory_OnMultiLeveLPath)
{
char* result = path_directory("dir0/dir1/dir2/filename.ext");
CHECK_EQUAL("dir0/dir1/dir2", result);
}
/**************************************************************************
* path_extension() tests
**************************************************************************/
TEST(PathExt_ReturnsEmptyString_OnNoExtension)
{
char* result = path_extension("filename");
CHECK_EQUAL("", result);
}
TEST(PathExt_ReturnsExtension)
{
char* result = path_extension("filename.txt");
CHECK_EQUAL(".txt", result);
}
TEST(PathExt_ReturnsLastExtension_OnMultipleDots)
{
char* result = path_extension("filename.mod.txt");
CHECK_EQUAL(".txt", result);
}
/**************************************************************************
* path_filename() tests
**************************************************************************/
TEST(PathFileName_ReturnsAll_OnNoDirectory)
{
char* result = path_filename("filename.ext");
CHECK_EQUAL("filename.ext", result);
}
TEST(PathFileName_ReturnsEmptyString_OnNoName)
{
char* result = path_filename("dir0/dir1/");
CHECK_EQUAL("", result);
}
TEST(PathFileName_ReturnsOnlyName_OnFullPath)
{
char* result = path_filename("dir0/dir1/filename.ext");
CHECK_EQUAL("filename.ext", result);
}
/**************************************************************************
* path_is_absolute() tests
**************************************************************************/
TEST(PathIsAbsolute_ReturnsTrue_OnAbsolutePosixPath)
{
CHECK(path_is_absolute("/a/b/c"));
}
TEST(PathIsAbsolute_ReturnsTrue_OnAbsoluteWindowsPathWithDrive)
{
CHECK(path_is_absolute("c:/a/b/c"));
}
TEST(PathIsAbsolute_ReturnsFalse_OnRelativePath)
{
CHECK(!path_is_absolute("a/b/c"));
}
/**************************************************************************
* path_is_absolute() tests
**************************************************************************/
TEST(PathIsCpp_ReturnsFalse_OnNotCpp)
{
CHECK(!path_is_cpp_source("filename.XXX"));
}
TEST(PathIsCpp_ReturnsTrue_OnC)
{
CHECK(path_is_cpp_source("filename.c"));
}
TEST(PathIsCpp_ReturnsTrue_OnCC)
{
CHECK(path_is_cpp_source("filename.cc"));
}
TEST(PathIsCpp_ReturnsTrue_OnCpp)
{
CHECK(path_is_cpp_source("filename.cpp"));
}
TEST(PathIsCpp_ReturnsTrue_OnCxx)
{
CHECK(path_is_cpp_source("filename.cxx"));
}
TEST(PathIsCpp_ReturnsTrue_OnS)
{
CHECK(path_is_cpp_source("filename.s"));
}
TEST(PathIsCpp_ReturnsTrue_OnUpperCase)
{
CHECK(path_is_cpp_source("filename.C"));
}
/**************************************************************************
* path_join() tests
**************************************************************************/
TEST(PathJoin_ReturnsJoinedPath_OnValidParts)
{
char* result = path_join("leading", "trailing");
CHECK_EQUAL("leading/trailing", result);
}
TEST(PathJoin_ReturnsAbsPath_OnAbsUnixPath)
{
char* result = path_join("leading", "/trailing");
CHECK_EQUAL("/trailing", result);
}
TEST(PathJoin_ReturnsAbsPath_OnAbsWindowsPath)
{
char* result = path_join("leading", "C:/trailing");
CHECK_EQUAL("C:/trailing", result);
}
/**************************************************************************
* path_relative() tests
**************************************************************************/
TEST(PathRelative_ReturnsDot_OnMatchingPaths)
{
char* result = path_relative("/a/b/c", "/a/b/c");
CHECK_EQUAL(".", result);
}
TEST(PathRelative_ReturnsDoubleDot_OnChildToParent)
{
char* result = path_relative("/a/b/c", "/a/b");
CHECK_EQUAL("..", result);
}
TEST(PathRelative_ReturnsDoubleDotPath_OnSiblingToSibling)
{
char* result = path_relative("/a/b/c", "/a/b/d");
CHECK_EQUAL("../d", result);
}
TEST(PathRelative_ReturnsChildPath_OnParentToChild)
{
char* result = path_relative("/a/b/c", "/a/b/c/d");
CHECK_EQUAL("d", result);
}
/**************************************************************************
* path_translate() tests
**************************************************************************/
TEST(PathTranslate_ReturnsTranslatedPath_OnValidPath)
{
char* result = path_translate("dir\\dir\\file", "/");
CHECK_EQUAL("dir/dir/file", result);
}
TEST(PathTranslate_ReturnsCorrectSeparator_OnMixedPath)
{
char* result = path_translate("dir\\dir/file", NULL);
#if defined(PLATFORM_WINDOWS)
CHECK_EQUAL("dir\\dir\\file", result);
#else
CHECK_EQUAL("dir/dir/file", result);
#endif
}
}

View File

@ -1,117 +0,0 @@
/**
* \file stream_tests.cpp
* \brief Output stream automated tests.
* \author Copyright (c) 2007-2008 Jason Perkins and the Premake project
*/
#include "premake.h"
#include "testing/testing.h"
extern "C" {
#include "base/stream.h"
}
struct FxStream
{
Stream strm;
char buffer[1024];
FxStream()
{
strm = stream_create_null();
stream_set_buffer(strm, buffer);
}
~FxStream()
{
stream_destroy(strm);
}
};
struct FxStreamStrings : FxStream
{
Strings strs;
FxStreamStrings()
{
strs = strings_create();
}
~FxStreamStrings()
{
strings_destroy(strs);
}
};
SUITE(base)
{
TEST_FIXTURE(FxStream, Write_WritesValue_OnSimpleValue)
{
stream_write(strm, "Hi there!");
CHECK_EQUAL("Hi there!", buffer);
}
TEST_FIXTURE(FxStream, Write_WritesValue_OnFormattedValue)
{
stream_write(strm, "Hi there, %s!", "Mr. Bill");
CHECK_EQUAL("Hi there, Mr. Bill!", buffer);
}
TEST_FIXTURE(FxStream, WriteLine_AppendsNewLine_OnSimpleValue)
{
stream_writeline(strm, "Hi there!");
CHECK_EQUAL("Hi there!\n", buffer);
}
TEST_FIXTURE(FxStream, WriteLine_AppendsNewLine_OnFormattedValue)
{
stream_writeline(strm, "Hi there, %s!", "Mr. Bill");
CHECK_EQUAL("Hi there, Mr. Bill!\n", buffer);
}
TEST_FIXTURE(FxStream, WriteLine_AppendsNewLine_OnModifiedNewline)
{
stream_set_newline(strm, "\r\n");
stream_writeline(strm, "Hi there!");
CHECK_EQUAL("Hi there!\r\n", buffer);
}
/**********************************************************************
* stream_write_strings() tests
**********************************************************************/
TEST_FIXTURE(FxStreamStrings, WriteStrings_WritesStartEnd_OnEmptyList)
{
stream_write_strings(strm, strs, "^", "<", ">", ",", "$", NULL);
CHECK_EQUAL("^$", buffer);
}
TEST_FIXTURE(FxStreamStrings, WriteStrings_WriteSingleItem_OnSingleItem)
{
strings_add(strs, "AAA");
stream_write_strings(strm, strs, "^", "<", ">", ",", "$", NULL);
CHECK_EQUAL("^<AAA>$", buffer);
}
TEST_FIXTURE(FxStreamStrings, WriteStrings_WriteMultipleItems_OnMultipleItems)
{
strings_add(strs, "AAA");
strings_add(strs, "BBB");
strings_add(strs, "CCC");
stream_write_strings(strm, strs, "^", "<", ">", ",", "$", NULL);
CHECK_EQUAL("^<AAA>,<BBB>,<CCC>$", buffer);
}
/**********************************************************************
* stream_write_escaped() tests
**********************************************************************/
TEST_FIXTURE(FxStream, WriteEscaped_EscapesSpecialCharacters)
{
stream_write_escaped(strm, "Specials: \" & \' < >");
CHECK_EQUAL("Specials: &quot; &amp; &apos; &lt; &gt;", buffer);
}
}

Some files were not shown because too many files have changed in this diff Show More