From 64c220b70a64c1ebf698c60930608f0d2ff64bea Mon Sep 17 00:00:00 2001 From: Jason Perkins Date: Mon, 30 Sep 2013 10:16:56 -0400 Subject: [PATCH] Project locations are now inherited from the solution, if set. --- src/actions/make/make_cpp.lua | 2 +- src/actions/make/make_solution.lua | 6 +-- src/actions/vstudio/vs2005_csproj.lua | 3 +- src/actions/vstudio/vs2005_solution.lua | 3 +- src/actions/vstudio/vs200x_vcproj.lua | 4 +- src/actions/vstudio/vs2010_vcxproj.lua | 4 +- src/base/config.lua | 3 +- src/base/fileconfig.lua | 2 +- src/base/project.lua | 46 ++++---------------- src/base/solution.lua | 29 ++++--------- tests/premake5.lua | 2 + tests/project/test_location.lua | 57 +++++++++++++++++++++++++ tests/solution/test_location.lua | 44 +++++++++++++++++++ 13 files changed, 130 insertions(+), 75 deletions(-) create mode 100644 tests/project/test_location.lua create mode 100644 tests/solution/test_location.lua diff --git a/src/actions/make/make_cpp.lua b/src/actions/make/make_cpp.lua index 02e4db71..ac9e4d39 100644 --- a/src/actions/make/make_cpp.lua +++ b/src/actions/make/make_cpp.lua @@ -434,7 +434,7 @@ for _, incdir in ipairs(cfg.includedirs) do local testname = path.join(incdir, pch) if os.isfile(testname) then - pch = path.getrelative(cfg.location, testname) + pch = project.getrelative(cfg.project, testname) break end end diff --git a/src/actions/make/make_solution.lua b/src/actions/make/make_solution.lua index 3beff6f5..54cbfd6d 100644 --- a/src/actions/make/make_solution.lua +++ b/src/actions/make/make_solution.lua @@ -57,9 +57,8 @@ function make.cleanrules(sln) _p('clean:') for prj in solution.eachproject(sln) do - local slnpath = solution.getlocation(sln) local prjpath = project.getfilename(prj, make.getmakefilename(prj, true)) - local prjdir = path.getdirectory(path.getrelative(slnpath, prjpath)) + local prjdir = path.getdirectory(path.getrelative(sln.location, prjpath)) local prjname = path.getname(prjpath) _x(1,'@${MAKE} --no-print-directory -C %s -f %s clean', prjdir, prjname) end @@ -121,9 +120,8 @@ _p(1,'@echo "==== Building %s ($(%s_config)) ===="', prj.name, cfgvar) - local slnpath = solution.getlocation(sln) local prjpath = project.getfilename(prj, make.getmakefilename(prj, true)) - local prjdir = path.getdirectory(path.getrelative(slnpath, prjpath)) + local prjdir = path.getdirectory(path.getrelative(sln.location, prjpath)) local prjname = path.getname(prjpath) _x(1,'@${MAKE} --no-print-directory -C %s -f %s config=$(%s_config)', prjdir, prjname, cfgvar) diff --git a/src/actions/vstudio/vs2005_csproj.lua b/src/actions/vstudio/vs2005_csproj.lua index 07b120bc..c8ae3c0b 100644 --- a/src/actions/vstudio/vs2005_csproj.lua +++ b/src/actions/vstudio/vs2005_csproj.lua @@ -306,9 +306,8 @@ local deps = project.getdependencies(prj) if #deps > 0 then - local prjpath = project.getlocation(prj) for _, dep in ipairs(deps) do - local relpath = path.getrelative(prjpath, vstudio.projectfile(dep)) + local relpath = project.getrelative(prj, vstudio.projectfile(dep)) _x(2,'', path.translate(relpath)) _p(3,'{%s}', dep.uuid) _x(3,'%s', dep.name) diff --git a/src/actions/vstudio/vs2005_solution.lua b/src/actions/vstudio/vs2005_solution.lua index cee67c01..9dbe3f5f 100644 --- a/src/actions/vstudio/vs2005_solution.lua +++ b/src/actions/vstudio/vs2005_solution.lua @@ -90,9 +90,8 @@ local prj = n.project -- Build a relative path from the solution file to the project file - local slnpath = premake.solution.getlocation(prj.solution) local prjpath = vstudio.projectfile(prj) - prjpath = path.translate(path.getrelative(slnpath, prjpath)) + prjpath = path.translate(path.getrelative(prj.solution.location, prjpath)) _x('Project("{%s}") = "%s", "%s", "{%s}"', vstudio.tool(prj), prj.name, prjpath, prj.uuid) if _ACTION < "vs2012" then diff --git a/src/actions/vstudio/vs200x_vcproj.lua b/src/actions/vstudio/vs200x_vcproj.lua index 00cf5508..9942d737 100644 --- a/src/actions/vstudio/vs200x_vcproj.lua +++ b/src/actions/vstudio/vs200x_vcproj.lua @@ -1111,11 +1111,9 @@ -- referencing. Which, in theory, would break if the project is included -- in more than one solution. But that's how they do it. - local prjpath = project.getlocation(prj.solution) - for _, dep in ipairs(deps) do - local relpath = path.getrelative(prjpath, vstudio.projectfile(dep)) + local relpath = path.getrelative(prj.solution.location, vstudio.projectfile(dep)) -- Visual Studio wants the path to start with ./ or ../ if not relpath:startswith(".") then diff --git a/src/actions/vstudio/vs2010_vcxproj.lua b/src/actions/vstudio/vs2010_vcxproj.lua index e26e061a..043e3318 100644 --- a/src/actions/vstudio/vs2010_vcxproj.lua +++ b/src/actions/vstudio/vs2010_vcxproj.lua @@ -591,11 +591,9 @@ function vc2010.projectReferences(prj) local deps = project.getdependencies(prj) if #deps > 0 then - local prjpath = project.getlocation(prj) - _p(1,'') for _, dep in ipairs(deps) do - local relpath = path.getrelative(prjpath, vstudio.projectfile(dep)) + local relpath = project.getrelative(prj, vstudio.projectfile(dep)) _x(2,'', path.translate(relpath)) _p(3,'{%s}', dep.uuid) _p(2,'') diff --git a/src/base/config.lua b/src/base/config.lua index 45cb703e..27a619d2 100755 --- a/src/base/config.lua +++ b/src/base/config.lua @@ -22,6 +22,7 @@ cfg.shortname = cfg.shortname:gsub(" ", "_"):lower() cfg.name = cfg.longname + -- compute build and link targets if cfg.project and cfg.kind then cfg.buildtarget = config.gettargetinfo(cfg) cfg.buildtarget.relpath = project.getrelative(cfg.project, cfg.buildtarget.abspath) @@ -49,7 +50,7 @@ -- local function buildtargetinfo(cfg, kind, field) - local basedir = project.getlocation(cfg.project) + local basedir = cfg.project.location local directory = cfg[field.."dir"] or cfg.targetdir or basedir local basename = cfg[field.."name"] or cfg.targetname or cfg.project.name diff --git a/src/base/fileconfig.lua b/src/base/fileconfig.lua index e16f3dcc..50cfc641 100644 --- a/src/base/fileconfig.lua +++ b/src/base/fileconfig.lua @@ -112,7 +112,7 @@ -- (such as the custom build commands) will be made relative to -- this path, ensuring a portable generated project. - context.basedir(fsub, project.getlocation(cfg.project)) + context.basedir(fsub, cfg.project.location) setmetatable(fsub, fileconfig.fsub_mt) diff --git a/src/base/project.lua b/src/base/project.lua index d3a28031..4be6b126 100755 --- a/src/base/project.lua +++ b/src/base/project.lua @@ -30,11 +30,8 @@ prj.script = _SCRIPT prj.blocks = {} - local cwd = os.getcwd() - local cset = configset.new(sln.configset) - cset.basedir = cwd - cset.location = cwd + cset.basedir = os.getcwd() cset.filename = name cset.uuid = os.uuid(name) prj.configset = cset @@ -122,7 +119,8 @@ -- location. Any path tokens which are expanded in non-path fields -- are made relative to this, ensuring a portable generated project. - context.basedir(ctx, project.getlocation(ctx)) + ctx.location = ctx.location or sln.location or prj.basedir + context.basedir(ctx, ctx.location) -- This bit could use some work: create a canonical set of configurations -- for the project, along with a mapping from the solution's configurations. @@ -391,7 +389,7 @@ ctx.buildcfg = buildcfg ctx.platform = platform ctx.action = _ACTION - ctx.language = prj.language + ctx.language = ctx.language -- Allow the configuration information to accessed by tokens contained -- within the configuration itself @@ -419,14 +417,15 @@ context.addterms(ctx, ctx.kind) context.compile(ctx) - context.basedir(ctx, project.getlocation(prj)) + + ctx.location = ctx.location or prj.location + context.basedir(ctx, ctx.location) -- Fill in a few calculated for the configuration, including the long -- and short names and the build and link target. -- TODO: Merge these two functions premake.config.bake(ctx) - return ctx end @@ -612,7 +611,7 @@ -- function project.getfilename(prj, ext) - local fn = project.getlocation(prj) + local fn = prj.location if ext and not ext:startswith(".") then fn = path.join(fn, ext) else @@ -643,33 +642,6 @@ end --- --- Retrieve the project's file system location. Also works with solutions. --- --- @param prj --- The project object to query. --- @param relativeto --- Optional; if supplied, the project location will be made relative --- to this path. --- @return --- The path to the project's file system location. --- - - function project.getlocation(prj, relativeto) - local location = prj.location - if not location and prj.solution then - location = prj.solution.location - end - if not location then - location = prj.basedir - end - if relativeto then - location = path.getrelative(relativeto, location) - end - return location - end - - -- -- Return the relative path from the project to the specified file. -- @@ -690,7 +662,7 @@ return result else if filename then - return path.getrelative(project.getlocation(prj), filename) + return path.getrelative(prj.location, filename) end end end diff --git a/src/base/solution.lua b/src/base/solution.lua index 7ec2774a..0acf0755 100644 --- a/src/base/solution.lua +++ b/src/base/solution.lua @@ -37,11 +37,8 @@ sln.blocks = {} sln.projects = {} - local cwd = os.getcwd() - local cset = configset.new(configset.root) - cset.basedir = cwd - cset.location = cwd + cset.basedir = os.getcwd() cset.filename = name sln.configset = cset @@ -127,7 +124,8 @@ -- Specify the solution's file system location; when path tokens are -- expanded in solution values, they will be made relative to this. - context.basedir(ctx, project.getlocation(sln)) + ctx.location = ctx.location or sln.basedir + context.basedir(ctx, ctx.location) -- Now bake down all of the projects contained in the solution, and -- store that for future reference @@ -140,6 +138,10 @@ ctx.projects = projects + -- Synthesize a default solution file output location + + ctx.location = ctx.location or sln.basedir + -- I now have enough information to assign unique object directories -- to each project configuration in the solution. @@ -203,7 +205,7 @@ local function getobjdirs(cfg) local dirs = {} - local dir = path.getabsolute(path.join(project.getlocation(cfg.project), cfg.objdir or "obj")) + local dir = path.getabsolute(path.join(cfg.project.location, cfg.objdir or "obj")) table.insert(dirs, dir) if cfg.platform then @@ -402,21 +404,6 @@ end --- --- Retrieve the solution's file system location. --- --- @param sln --- The solution object to query. --- @param relativeto --- Optional; if supplied, the location will be made relative --- to this path. --- @return --- The path to the solution's file system location. --- - - solution.getlocation = project.getlocation - - -- -- Retrieve the project configuration at a particular index. -- diff --git a/tests/premake5.lua b/tests/premake5.lua index ffe9af63..558e6500 100644 --- a/tests/premake5.lua +++ b/tests/premake5.lua @@ -56,6 +56,7 @@ -- Solution object tests dofile("solution/test_eachconfig.lua") + dofile("solution/test_location.lua") dofile("solution/test_objdirs.lua") -- Project object tests @@ -64,6 +65,7 @@ dofile("project/test_filename.lua") dofile("project/test_getconfig.lua") dofile("project/test_hasconfig.lua") + dofile("project/test_location.lua") dofile("project/test_vpaths.lua") -- Configuration object tests diff --git a/tests/project/test_location.lua b/tests/project/test_location.lua new file mode 100644 index 00000000..e9a47038 --- /dev/null +++ b/tests/project/test_location.lua @@ -0,0 +1,57 @@ +-- +-- tests/project/test_location.lua +-- Test handling of the projects's location field. +-- Copyright (c) 2013 Jason Perkins and the Premake project +-- + + local suite = test.declare("project_location") + + +-- +-- Setup and teardown +-- + + local sln, prj + + function suite.setup() + sln = test.createsolution() + end + + local function prepare() + prj = premake.solution.getproject(sln, 1) + end + + +-- +-- If no explicit location is set, the location should be set to the +-- directory containing the script which defined the project. +-- + + function suite.usesScriptLocation_onNoLocation() + prepare() + test.isequal(os.getcwd(), prj.location) + end + + +-- +-- If an explicit location has been set, use it. +-- + + function suite.usesLocation_onLocationSet() + location "build" + prepare() + test.isequal(path.join(os.getcwd(), "build"), prj.location) + end + + +-- +-- If the solution sets a location, and the project does not, it should +-- inherit the value from the solution. +-- + + function suite.inheritsSolutionLocation_onNoProjectLocation() + solution () + location "build" + prepare() + test.isequal(path.join(os.getcwd(), "build"), prj.location) + end diff --git a/tests/solution/test_location.lua b/tests/solution/test_location.lua new file mode 100644 index 00000000..a4ef68ee --- /dev/null +++ b/tests/solution/test_location.lua @@ -0,0 +1,44 @@ +-- +-- tests/solution/test_location.lua +-- Test handling of the solution's location field. +-- Copyright (c) 2013 Jason Perkins and the Premake project +-- + + local suite = test.declare("solution_location") + + +-- +-- Setup and teardown +-- + + local sln + + function suite.setup() + sln = solution("MySolution") + end + + local function prepare() + sln = premake.solution.bake(sln) + end + + +-- +-- If no explicit location is set, the location should be set to the +-- directory containing the script which defined the solution. +-- + + function suite.usesScriptLocation_onNoLocation() + prepare() + test.isequal(os.getcwd(), sln.location) + end + + +-- +-- If an explicit location has been set, use it. +-- + + function suite.usesLocation_onLocationSet() + location "build" + prepare() + test.isequal(path.join(os.getcwd(), "build"), sln.location) + end