Skip to content

Commit

Permalink
Add support for idirafter flag in GCC/Clang
Browse files Browse the repository at this point in the history
  • Loading branch information
nickclark2016 committed Jan 30, 2023
1 parent d6caf5f commit 1e65164
Show file tree
Hide file tree
Showing 18 changed files with 219 additions and 18 deletions.
2 changes: 1 addition & 1 deletion modules/codelite/codelite_project.lua
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@
end

local toolset = m.getcompiler(cfg)
local externalincludedirs = toolset.getincludedirs(cfg, {}, cfg.externalincludedirs, cfg.frameworkdirs)
local externalincludedirs = toolset.getincludedirs(cfg, {}, cfg.externalincludedirs, cfg.frameworkdirs, cfg.includedirsafter)
local forceincludes = toolset.getforceincludes(cfg)
local cxxflags = table.concat(table.join(externalincludedirs, toolset.getcxxflags(cfg), forceincludes, cfg.buildoptions), ";")
local cflags = table.concat(table.join(externalincludedirs, toolset.getcflags(cfg), forceincludes, cfg.buildoptions), ";")
Expand Down
10 changes: 10 additions & 0 deletions modules/codelite/tests/test_codelite_config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@
]]
end

function suite.OnProjectCfg_IncludeDirsAfter()
includedirsafter { "sysdir", "sysdir2/"}
prepare()
codelite.project.compiler(cfg)
test.capture [[
<Compiler Options="-idirafter sysdir;-idirafter sysdir2" C_Options="-idirafter sysdir;-idirafter sysdir2" Assembler="" Required="yes" PreCompiledHeader="" PCHInCommandLine="no" PCHFlagsPolicy="1" PCHFlags="">
</Compiler>
]]
end


function suite.OnProjectCfg_Defines()
defines { "TEST", "DEF", "VAL=1", "ESCAPE=\"WITH SPACE\"" }
Expand Down
2 changes: 1 addition & 1 deletion modules/gmake/gmake_cpp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -521,7 +521,7 @@ end


function make.includes(cfg, toolset)
local includes = toolset.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs, cfg.frameworkdirs)
local includes = toolset.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs, cfg.frameworkdirs, cfg.includedirsafter)
_p(' INCLUDES +=%s', make.list(includes))
end

Expand Down
2 changes: 1 addition & 1 deletion modules/gmake2/gmake2_cpp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,7 @@


function cpp.includes(cfg, toolset)
local includes = toolset.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs, cfg.frameworkdirs)
local includes = toolset.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs, cfg.frameworkdirs, cfg.includedirsafter)
p.outln('INCLUDES +=' .. gmake2.list(includes))
end

Expand Down
1 change: 1 addition & 0 deletions modules/gmake2/tests/_tests.lua
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ return {
"test_gmake2_clang.lua",
"test_gmake2_file_rules.lua",
"test_gmake2_flags.lua",
"test_gmake2_includes.lua",
"test_gmake2_ldflags.lua",
"test_gmake2_linking.lua",
"test_gmake2_makefile.lua",
Expand Down
42 changes: 42 additions & 0 deletions modules/gmake2/tests/test_gmake2_includes.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
--
-- test_gmake2_linking.lua
-- Validate the link step generation for makefiles.
-- (c) 2016-2017 Jason Perkins, Blizzard Entertainment and the Premake project
--

local suite = test.declare("gmake2_includes")

local p = premake
local gmake2 = p.modules.gmake2

local project = p.project


--
-- Setup and teardown
--

local wks, prj

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

local function prepare(calls)
local cfg = test.getconfig(prj, "Debug")
local toolset = p.tools.gcc
gmake2.cpp.includes(cfg, toolset)
end


--
-- Check for idirafter flags
--

function suite.includeDirsAfter()
includedirsafter { 'DirAfter' }
prepare()
test.capture [[
INCLUDES += -idirafter DirAfter
]]
end
3 changes: 2 additions & 1 deletion modules/vstudio/vs2010_vcxproj.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2247,7 +2247,8 @@


function m.includePath(cfg)
local dirs = vstudio.path(cfg, cfg.externalincludedirs)
local externaldirs = table.join(cfg.externalincludedirs, cfg.includedirsafter)
local dirs = vstudio.path(cfg, externaldirs)
if #dirs > 0 then
if _ACTION < "vs2019" then
m.element("IncludePath", nil, "%s;$(IncludePath)", table.concat(dirs, ";"))
Expand Down
30 changes: 30 additions & 0 deletions modules/xcode/tests/test_xcode_project.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2428,6 +2428,36 @@
]]
end

function suite.XCBuildConfigurationProject_OnIncludeDirsAfter()
includedirsafter { "../include", "../libs", "../name with spaces" }
prepare()
xcode.XCBuildConfiguration_Project(tr, tr.configs[1])
test.capture [[
A14350AC4595EE5E57CE36EC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ARCHS = "$(NATIVE_ARCH_ACTUAL)";
CONFIGURATION_BUILD_DIR = "$(SYMROOT)";
CONFIGURATION_TEMP_DIR = "$(OBJROOT)";
GCC_OPTIMIZATION_LEVEL = 0;
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
OBJROOT = obj/Debug;
ONLY_ACTIVE_ARCH = NO;
SYMROOT = bin/Debug;
SYSTEM_HEADER_SEARCH_PATHS = (
../include,
../libs,
"\"../name with spaces\"",
"$(inherited)",
);
};
name = Debug;
};
]]
end

function suite.XCBuildConfigurationProject_OnBuildOptions()
buildoptions { "build option 1", "build option 2" }
prepare()
Expand Down
13 changes: 7 additions & 6 deletions modules/xcode/xcode_common.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1521,14 +1521,15 @@
end
settings['USER_HEADER_SEARCH_PATHS'] = cfg.includedirs

local externalincludedirs = project.getrelative(cfg.project, cfg.externalincludedirs)
for i,v in ipairs(externalincludedirs) do
cfg.externalincludedirs[i] = p.quoted(v)
local systemincludedirs = project.getrelative(cfg.project, table.join(cfg.externalincludedirs or {}, cfg.includedirsafter or {}))
for i,v in ipairs(systemincludedirs) do
systemincludedirs[i] = p.quoted(v)
end
if not table.isempty(cfg.externalincludedirs) then
table.insert(cfg.externalincludedirs, "$(inherited)")
if not table.isempty(systemincludedirs) then
table.insert(systemincludedirs, "$(inherited)")
end
settings['SYSTEM_HEADER_SEARCH_PATHS'] = cfg.externalincludedirs

settings['SYSTEM_HEADER_SEARCH_PATHS'] = systemincludedirs

for i,v in ipairs(cfg.libdirs) do
cfg.libdirs[i] = p.project.getrelative(cfg.project, cfg.libdirs[i])
Expand Down
7 changes: 7 additions & 0 deletions src/_premake_init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -1505,6 +1505,13 @@
}
}

api.register {
name = "includedirsafter",
scope = "config",
kind = "list:directory",
tokens = true
}

api.register { -- DEPRECATED 2021-11-16
name = "sysincludedirs",
scope = "config",
Expand Down
13 changes: 11 additions & 2 deletions src/tools/clang.lua
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,23 @@
-- @param dirs
-- An array of include file search directories; as an array of
-- string values.
-- @param extdirs
-- An array of include file search directories for external includes;
-- as an array of string values.
-- @param frameworkdirs
-- An array of file search directories for the framework includes;
-- as an array of string vlaues
-- @param includedirsafter
-- An array of include file search directories for includes after system;
-- as an array of string values.
-- @return
-- An array of symbols with the appropriate flag decorations.
--

function clang.getincludedirs(cfg, dirs, extdirs, frameworkdirs)
function clang.getincludedirs(cfg, dirs, extdirs, frameworkdirs, includedirsafter)

-- Just pass through to GCC for now
local flags = gcc.getincludedirs(cfg, dirs, extdirs, frameworkdirs)
local flags = gcc.getincludedirs(cfg, dirs, extdirs, frameworkdirs, includedirsafter)
return flags

end
Expand Down
27 changes: 25 additions & 2 deletions src/tools/gcc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -296,10 +296,28 @@


--
-- Decorate include file search paths for the GCC command line.
-- Returns a list of include file search directories, decorated for
-- the compiler command line.
--
-- @param cfg
-- The project configuration.
-- @param dirs
-- An array of include file search directories; as an array of
-- string values.
-- @param extdirs
-- An array of include file search directories for external includes;
-- as an array of string values.
-- @param frameworkdirs
-- An array of file search directories for the framework includes;
-- as an array of string vlaues
-- @param includedirsafter
-- An array of include file search directories for includes after system;
-- as an array of string values.
-- @return
-- An array of symbols with the appropriate flag decorations.
--

function gcc.getincludedirs(cfg, dirs, extdirs, frameworkdirs)
function gcc.getincludedirs(cfg, dirs, extdirs, frameworkdirs, includedirsafter)
local result = {}
for _, dir in ipairs(dirs) do
dir = project.getrelative(cfg.project, dir)
Expand All @@ -318,6 +336,11 @@
table.insert(result, '-isystem ' .. p.quoted(dir))
end

for _, dir in ipairs(includedirsafter or {}) do
dir = project.getrelative(cfg.project, dir)
table.insert(result, '-idirafter ' .. p.quoted(dir))
end

return result
end

Expand Down
11 changes: 10 additions & 1 deletion src/tools/msc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@
-- Decorate include file search paths for the MSVC command line.
--

function msc.getincludedirs(cfg, dirs, extdirs, frameworkdirs)
function msc.getincludedirs(cfg, dirs, extdirs, frameworkdirs, includedirsafter)
local result = {}
for _, dir in ipairs(dirs) do
dir = project.getrelative(cfg.project, dir)
Expand All @@ -271,6 +271,15 @@
end
end

for _, dir in ipairs(includedirsafter or {}) do
dir = project.getrelative(cfg.project, dir)
if cfg.toolset and cfg.toolset >= "msc-v142" then
table.insert(result, '/external:I' .. p.quoted(dir))
else
table.insert(result, '-I' .. p.quoted(dir))
end
end

return result
end

Expand Down
15 changes: 12 additions & 3 deletions tests/tools/test_gcc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -644,7 +644,7 @@
includedirs { "../include", "src/include" }
externalincludedirs { "test/include" }
prepare()
test.isequal({ '-I../include', '-Isrc/include', '-isystem test/include' }, gcc.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs))
test.isequal({ '-I../include', '-Isrc/include', '-isystem test/include' }, gcc.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs, cfg.frameworkdirs, cfg.includedirsafter))
end


Expand All @@ -668,16 +668,25 @@
includedirs { "include files" }
externalincludedirs { "test include" }
prepare()
test.isequal({ '-I"include files"', '-isystem "test include"' }, gcc.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs))
test.isequal({ '-I"include files"', '-isystem "test include"' }, gcc.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs, cfg.frameworkdirs, cfg.includedirsafter))
end

function suite.includeDirs_onEnvVars()
includedirs { "$(IntDir)/includes" }
externalincludedirs { "$(BinDir)/include" }
prepare()
test.isequal({ '-I"$(IntDir)/includes"', '-isystem "$(BinDir)/include"' }, gcc.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs))
test.isequal({ '-I"$(IntDir)/includes"', '-isystem "$(BinDir)/include"' }, gcc.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs, cfg.frameworkdirs, cfg.includedirsafter))
end

--
-- Include Directories After correctly take idirafter flag
--

function suite.includeDirs_includeDirAfter()
includedirsafter { "after/path" }
prepare()
test.isequal({ '-idirafter after/path'}, gcc.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs, cfg.frameworkdirs, cfg.includedirsafter))
end


--
Expand Down
17 changes: 17 additions & 0 deletions tests/tools/test_msc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,23 @@
test.contains("/external:I/usr/local/include", msc.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs))
end

--
-- Check handling includedirsafter.
--

function suite.cflags_onIncludeDirsAfter()
includedirsafter { "/usr/local/include" }
prepare()
test.contains("-I/usr/local/include", msc.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs, cfg.frameworkdirs, cfg.includedirsafter))
end

function suite.cflags_onVs2022IncludeDirsAfter()
p.action.set("vs2022")
includedirsafter { "/usr/local/include" }
prepare()
test.contains("/external:I/usr/local/include", msc.getincludedirs(cfg, cfg.includedirs, cfg.externalincludedirs, cfg.frameworkdirs, cfg.includedirsafter))
end


--
-- Check handling of library search paths.
Expand Down
1 change: 1 addition & 0 deletions website/docs/Project-API.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
| [implibsuffix](implibsuffix.md) | |
| [include](include.md) | |
| [includedirs](includedirs.md) | |
| [includedirsafter](includedirsafter.md) | |
| [includeexternal](includeexternal.md) | |
| [inlining](inlining.md) | Tells the compiler when it should inline functions |
| [intrinsics](intrinsics.md) | |
Expand Down
39 changes: 39 additions & 0 deletions website/docs/includedirsafter.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
Specifies the include directories to parse last per the toolset ordering and marks the directory as an external include directory. If the exporter or toolset
does not support include directory ordering, these directories are added to the external include directory path.

```lua
includedirsafter { "paths" }
```

### Parameters ###

`paths` specifies a list of include file search directories. Paths should be specified relative to the currently running script file. Search order is evaluated from
right to left.

### Applies To ###

Project configurations. GCC and Clang are the only toolsets supporting the ordering functionality in the gmake, gmake2 and Codelite exporters. All exporters and toolsets
support appending the directories to the external include directories.

### Availability ###

Premake 5.0 or later.

### Examples ###

Define two include file search paths.

```lua
includedirsafter { "../lua/include", "../zlib" }
```

You can also use wildcards to match multiple directories. The * will match against a single directory, ** will recurse into subdirectories as well.

```lua
includedirsafter { "../includes/**" }
```

### See Also ###

* [includedirs](includedirs.md)
* [externalincludedirs](externalincludedirs.md)
2 changes: 2 additions & 0 deletions website/sidebars.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ module.exports = {
'implibsuffix',
'importdirs',
'includedirs',
'includedirsafter',
'inheritdependencies',
'inlinesvisibility',
'inlining',
Expand Down Expand Up @@ -235,6 +236,7 @@ module.exports = {
'rules',
'runpathdirs',
'runtime',
'sanitize',
'scanformoduledependencies',
'shaderassembler',
'shaderassembleroutput',
Expand Down

0 comments on commit 1e65164

Please sign in to comment.