Skip to content

Commit

Permalink
Allow using basedir as a root base directory for files and paths.
Browse files Browse the repository at this point in the history
  • Loading branch information
tritao committed Oct 16, 2024
1 parent f785f20 commit a053949
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 17 deletions.
3 changes: 2 additions & 1 deletion src/_premake_init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,8 @@
api.register {
name = "basedir",
scope = "project",
kind = "path"
kind = "path",
cwdAsBase = true
}

api.register {
Expand Down
31 changes: 22 additions & 9 deletions src/base/api.lua
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,8 @@
-- if I have an existing instance, create a new configuration
-- block for it so I don't pick up an old filter
if instance then
configset.addFilter(instance, {}, os.getcwd())
local basedir = p.api.scope.current.basedir or os.getcwd()
configset.addFilter(instance, {}, basedir)
end

-- otherwise, a new instance
Expand All @@ -163,7 +164,7 @@
-- (recursive call, so needs to be its own function)
api._clearContainerChildren(class)

-- active this container, as well as it ancestors
-- active this container, as well as its ancestors
if not class.placeholder then
api.scope.current = instance
end
Expand Down Expand Up @@ -716,7 +717,8 @@
table.remove(api.scope.global.blocks, i)
end

configset.addFilter(api.scope.current, {}, os.getcwd())
local basedir = p.api.scope.current.basedir or os.getcwd()
configset.addFilter(api.scope.current, {}, basedir)
end


Expand Down Expand Up @@ -802,10 +804,12 @@
premake.field.kind("directory", {
paths = true,
store = function(field, current, value, processor)
return path.getabsolute(value)
local basedir = p.api.scope.current.basedir or os.getcwd()
return path.getabsolute(value, basedir)
end,
remove = function(field, current, value, processor)
return path.getabsolute(value)
local basedir = p.api.scope.current.basedir or os.getcwd()
return path.getabsolute(value, basedir)
end,
compare = function(field, a, b, processor)
return (a == b)
Expand All @@ -829,10 +833,12 @@
premake.field.kind("file", {
paths = true,
store = function(field, current, value, processor)
return path.getabsolute(value)
local basedir = p.api.scope.current.basedir or os.getcwd()
return path.getabsolute(value, basedir)
end,
remove = function(field, current, value, processor)
return path.getabsolute(value)
local basedir = p.api.scope.current.basedir or os.getcwd()
return path.getabsolute(value, basedir)
end,
compare = function(field, a, b, processor)
return (a == b)
Expand Down Expand Up @@ -1087,7 +1093,13 @@
premake.field.kind("path", {
paths = true,
store = function(field, current, value, processor)
return path.deferredjoin(os.getcwd(), value)
local basedir
if field.cwdAsBase then
basedir = os.getcwd()
else
basedir = p.api.scope.current.basedir or os.getcwd()
end
return path.deferredjoin(basedir, value)
end,
compare = function(field, a, b, processor)
return (a == b)
Expand Down Expand Up @@ -1152,7 +1164,8 @@
if (type(terms) == "table" and #terms == 1 and terms[1] == "*") or (terms == "*") then
terms = nil
end
local ok, err = configset.addFilter(api.scope.current, {terms}, os.getcwd())
local basedir = p.api.scope.current.basedir or os.getcwd()
local ok, err = configset.addFilter(api.scope.current, {terms}, basedir)
if not ok then
error(err, 2)
end
Expand Down
6 changes: 3 additions & 3 deletions src/base/context.lua
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,12 @@
ctx.terms = {}

-- This base directory is used when expanding path tokens encountered
-- in non-path value; such values will be made relative to this value
-- in non-path values; such values will be made relative to this value
-- so the resulting projects will only contain relative paths. It is
-- expected that the creator of the context will set this value using
-- the setbasedir() function.
-- the basedir() function.

ctx._basedir = os.getcwd()
ctx._basedir = cfgset.basedir or os.getcwd()

-- when a missing field is requested, fetch it from my config
-- set, and then cache the value for future lookups
Expand Down
1 change: 1 addition & 0 deletions tests/_tests.lua
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ return {
"workspace/test_objdirs.lua",

-- Project object tests
"project/test_basedir.lua",
"project/test_config_maps.lua",
"project/test_eachconfig.lua",
"project/test_getconfig.lua",
Expand Down
116 changes: 116 additions & 0 deletions tests/project/test_basedir.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
--
-- tests/project/test_basedir.lua
-- Test handling of the projects's basedir field.
-- Copyright (c) 2024 Jason Perkins and the Premake project
--

local suite = test.declare("project_basedir")


--
-- Setup and teardown
--

local wks, prj

function suite.setup()
wks = test.createWorkspace()
end

local function prepare()
prj = test.getproject(wks, 1)
end

local function get_files()
local cfg = test.getconfig(prj, "Debug")

local files = {}
for _, file in ipairs(cfg.files) do
table.insert(files, file)
end

return files
end

local function get_includedirs()
local cfg = test.getconfig(prj, "Debug")

local dirs = {}
for _, dir in ipairs(cfg.includedirs) do
table.insert(dirs, dir)
end

return dirs
end

--
-- If no explicit basedir is set, the location should be set to the
-- directory containing the script which defined the project.
--

function suite.onNoBaseDir()
prepare()
test.isequal(os.getcwd(), prj.basedir)
end


--
-- If an explicit basedir has been set, use it.
--

function suite.onBaseDir()
basedir "base"
prepare()
test.isequal(path.join(os.getcwd(), "base"), prj.basedir)
end


--
-- If multiple basedir are set, make sure the value is overriden correctly.
--

function suite.onMultipleBaseDir()
basedir "base0"
basedir "base"
prepare()
test.isequal(path.join(os.getcwd(), "base"), prj.basedir)
end

--
-- Files should be set relative to basedir.
-- Tests "file" data kind.
--

function suite.onFilesBaseDir()
basedir "base"
files { "test.cpp" }
prepare()
test.isequal({path.join(prj.basedir, "test.cpp")}, get_files())
end


--
-- Include directories should be set relative to basedir.
-- Tests "directory" data kind.
--

function suite.onIncludeDirsBaseDir()
basedir "base"
includedirs { "dir" }
prepare()
test.isequal({path.join(prj.basedir, "dir")}, get_includedirs())
end


--
-- If the workspace sets a basedir, and the project does not, it should
-- inherit the value from the workspace.
--

function suite.projectInheritsWorkspaceBaseDir()
workspace ()
basedir "base"
prepare()
-- dbg()
test.isequal(path.join(os.getcwd(), "base"), prj.basedir)
end
4 changes: 2 additions & 2 deletions tests/project/test_sources.lua
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
local oldcwd

function suite.setup()
wks, prj = test.createWorkspace()

-- We change the directory to get nice relative paths
oldcwd = os.getcwd()
os.chdir(cwd)

wks, prj = test.createWorkspace()

-- Create a token to be used in search paths
p.api.register { name = "mytoken", kind = "string", scope = "config" }
mytoken "test"
Expand Down
38 changes: 36 additions & 2 deletions website/docs/basedir.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
Sets the base directory for a configuration, from with other paths contained by the configuration will be made relative at export time.
Sets the base directory for a workspace or project, from which other paths contained by the configuration will be made relative to.

This base directory is also used when expanding path tokens encountered in non-path values.
Such values will be made relative to this value so the resulting projects will only contain relative paths.

```lua
basedir ("value")
Expand All @@ -8,7 +11,7 @@ You do not normally need to set this value, as it is filled in automatically wit

### Parameters ###

`value` is an absolute path, from which other paths contained by the configuration should be made relative.
`value` is an absolute or relative path, from which other paths contained by the configuration should be made relative to.

### Applies To ###

Expand All @@ -17,3 +20,34 @@ Any configuration.
### Availability ###

Premake 4.4 or later.

### Examples ###

```lua
workspace "workspace"
basedir "base"
project "project"
files { "file.cpp" }
includedirs { "dir" }
```

In this case, files will be generated as `base/file.cpp`, and the include directory as `base/dir`.


```lua
basedir "root"
workspace "workspace"
project "project"
basedir "base"
files { "file.cpp" }
includedirs { "dir" }
```

This results in the same output, as the project-level `basedir` overrides the workspace-level value.

```lua
filter { "configurations:Debug" }
includedirs { "%{prj.basedir}" }
```

`basedir` can also be used as a token, via for example `%{prj.basedir}` syntax. See the [Tokens](Tokens.md) reference for more details.

0 comments on commit a053949

Please sign in to comment.