Merge branch 'master' into fix/xcode-autocompletion

This commit is contained in:
Jordi Vilalta Prat 2018-08-22 11:42:59 +02:00 committed by GitHub
commit 043eaaf290
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 761 additions and 147 deletions

View File

@ -152,14 +152,17 @@
end)
function android.link(cfg, file)
local fname = path.translate(file.relpath)
-- default the seperator to '/' as that is what is searched for
-- below. Otherwise the function will use target seperator which
-- could be '\\' and result in failure to create links.
local fname = path.translate(file.relpath, '/')
-- Files that live outside of the project tree need to be "linked"
-- and provided with a project relative pseudo-path. Check for any
-- leading "../" sequences and, if found, remove them and mark this
-- path as external.
local link, count = fname:gsub("%.%.%/", "")
local external = (count > 0) or fname:find(':', 1, true)
local external = (count > 0) or fname:find(':', 1, true) or (file.vpath and file.vpath ~= file.relpath)
-- Try to provide a little bit of flexibility by allowing virtual
-- paths for external files. Would be great to support them for all

View File

@ -545,7 +545,7 @@
_p('')
end
local function makeVarName(prj, value, saltValue)
function cpp.makeVarName(prj, value, saltValue)
prj._gmake = prj._gmake or {}
prj._gmake.varlist = prj._gmake.varlist or {}
prj._gmake.varlistlength = prj._gmake.varlistlength or 0
@ -569,7 +569,10 @@
function cpp.perFileFlags(cfg, fcfg)
local toolset = gmake2.getToolSet(cfg)
local value = gmake2.list(table.join(toolset.getcflags(fcfg), fcfg.buildoptions))
local isCFile = path.iscfile(fcfg.name)
local getflags = iif(isCFile, toolset.getcflags, toolset.getcxxflags)
local value = gmake2.list(table.join(getflags(fcfg), fcfg.buildoptions))
if fcfg.defines or fcfg.undefines then
local defs = table.join(toolset.getdefines(fcfg.defines, cfg), toolset.getundefines(fcfg.undefines))
@ -587,9 +590,9 @@
if #value > 0 then
local newPerFileFlag = false
fcfg.flagsVariable, newPerFileFlag = makeVarName(cfg.project, value, iif(path.iscfile(fcfg.name), '_C', '_CPP'))
fcfg.flagsVariable, newPerFileFlag = cpp.makeVarName(cfg.project, value, iif(isCFile, '_C', '_CPP'))
if newPerFileFlag then
if path.iscfile(fcfg.name) then
if isCFile then
_p('%s = $(ALL_CFLAGS)%s', fcfg.flagsVariable, value)
else
_p('%s = $(ALL_CXXFLAGS)%s', fcfg.flagsVariable, value)
@ -797,14 +800,12 @@
function cpp.outputFileRules(cfg, file)
local outputs = table.concat(file.buildoutputs, ' ')
local dependencies = p.esc(file.source)
if file.buildinputs and #file.buildinputs > 0 then
dependencies = dependencies .. " " .. table.concat(p.esc(file.buildinputs), " ")
end
_p('%s: %s', outputs, dependencies)
_p('%s: %s', file.buildoutputs[1], dependencies)
if file.buildmessage then
_p('\t@echo %s', file.buildmessage)
@ -820,6 +821,13 @@
end
end
end
-- TODO: this is a hack with some imperfect side-effects.
-- better solution would be to emit a dummy file for the rule, and then outputs depend on it (must clean up dummy in 'clean')
-- better yet, is to use pattern rules, but we need to detect that all outputs have the same stem
if #file.buildoutputs > 1 then
_p('%s: %s', table.concat({ table.unpack(file.buildoutputs, 2) }, ' '), file.buildoutputs[1])
end
end

View File

@ -216,6 +216,40 @@ obj/Release/hello.obj: hello.x hello.x.inc hello.x.inc2
$(SILENT) cxc -c "hello.x" -o "obj/Release/hello.xo"
$(SILENT) c2o -c "obj/Release/hello.xo" -o "obj/Release/hello.obj"
else
$(error "invalid configuration $(config)")
endif
]]
end
function suite.customBuildRuleWithAdditionalOutputs()
files { "hello.x" }
filter "files:**.x"
buildmessage "Compiling %{file.name}"
buildcommands {
'cxc -c "%{file.path}" -o "%{cfg.objdir}/%{file.basename}.xo"',
'c2o -c "%{cfg.objdir}/%{file.basename}.xo" -o "%{cfg.objdir}/%{file.basename}.obj"'
}
buildoutputs { "%{cfg.objdir}/%{file.basename}.obj", "%{cfg.objdir}/%{file.basename}.other", "%{cfg.objdir}/%{file.basename}.another" }
prepare()
test.capture [[
# File Rules
# #############################################
ifeq ($(config),debug)
obj/Debug/hello.obj: hello.x
@echo Compiling hello.x
$(SILENT) cxc -c "hello.x" -o "obj/Debug/hello.xo"
$(SILENT) c2o -c "obj/Debug/hello.xo" -o "obj/Debug/hello.obj"
obj/Debug/hello.other obj/Debug/hello.another: obj/Debug/hello.obj
else ifeq ($(config),release)
obj/Release/hello.obj: hello.x
@echo Compiling hello.x
$(SILENT) cxc -c "hello.x" -o "obj/Release/hello.xo"
$(SILENT) c2o -c "obj/Release/hello.xo" -o "obj/Release/hello.obj"
obj/Release/hello.other obj/Release/hello.another: obj/Release/hello.obj
else
$(error "invalid configuration $(config)")
endif

View File

@ -73,3 +73,20 @@ PERFILE_FLAGS_1 = $(ALL_CXXFLAGS) -msse -msse2 -mfpmath=sse,387
PERFILE_FLAGS_2 = $(ALL_CFLAGS) -msse -msse2 -mfpmath=sse,387 -msse3 -mssse3 -msse4.1 -maes
]]
end
function suite.perfile_cxxApi()
files { 'a.cpp', 'b.cpp', 'c.cpp' }
visibility "Hidden"
filter { 'files:b.cpp' }
visibility "Protected"
prepare()
test.capture [[
# Per File Configurations
# #############################################
PERFILE_FLAGS_0 = $(ALL_CXXFLAGS) -fvisibility=protected
]]
end

View File

@ -198,6 +198,30 @@
end
--
-- Lang version tests
--
function suite.OnCSVersion()
csversion "6"
prepare()
test.capture [[
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.50727</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{AE61726D-187C-E440-BD07-2556188A6565}</ProjectGuid>
<OutputType>Exe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>MyProject</RootNamespace>
<AssemblyName>MyProject</AssemblyName>
<LangVersion>6</LangVersion>
</PropertyGroup>
]]
end
--
-- Make sure the root namespace can be overridden.
--

View File

@ -44,7 +44,8 @@
dotnetbase.targetFrameworkProfile,
dotnetbase.fileAlignment,
dotnetbase.bindingRedirects,
dotnetbase.projectTypeGuids
dotnetbase.projectTypeGuids,
dotnetbase.csversion
}
end

View File

@ -687,7 +687,6 @@
end
end
function dotnetbase.targetFrameworkVersion(cfg)
local action = p.action.current()
local framework = cfg.dotnetframework or action.vstudio.targetFramework
@ -696,6 +695,11 @@
end
end
function dotnetbase.csversion(cfg)
if cfg.csversion then
_p(2,'<LangVersion>%s</LangVersion>', cfg.csversion)
end
end
function dotnetbase.targetFrameworkProfile(cfg)
if _ACTION == "vs2010" then

View File

@ -55,7 +55,7 @@
-- The capabilities of this action
valid_kinds = { "ConsoleApp", "WindowedApp", "SharedLib", "StaticLib", "Makefile", "None" },
valid_kinds = { "ConsoleApp", "WindowedApp", "SharedLib", "StaticLib", "Makefile", "Utility", "None" },
valid_languages = { "C", "C++" },
valid_tools = {
cc = { "gcc", "clang" },

View File

@ -150,6 +150,32 @@
end
function suite.PBXFileReference_ListsOSXBundleTarget()
kind "SharedLib"
sharedlibtype "OSXBundle"
prepare()
xcode.PBXFileReference(tr)
test.capture [[
/* Begin PBXFileReference section */
[MyProject.bundle:product] /* MyProject.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; name = MyProject.bundle; path = MyProject.bundle; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
]]
end
function suite.PBXFileReference_ListsOSXFrameworkTarget()
kind "SharedLib"
sharedlibtype "OSXFramework"
prepare()
xcode.PBXFileReference(tr)
test.capture [[
/* Begin PBXFileReference section */
[MyProject.framework:product] /* MyProject.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; name = MyProject.framework; path = MyProject.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */
]]
end
function suite.PBXFileReference_ListsSourceFiles()
files { "source.c" }
prepare()
@ -660,6 +686,62 @@
end
---------------------------------------------------------------------------
-- PBXAggregateTarget tests
---------------------------------------------------------------------------
function suite.PBXAggregateTarget_OnUtility()
kind "Utility"
prepare()
xcode.PBXAggregateTarget(tr)
test.capture [[
/* Begin PBXAggregateTarget section */
[MyProject:target] /* MyProject */ = {
isa = PBXAggregateTarget;
buildConfigurationList = [MyProject:cfg] /* Build configuration list for PBXAggregateTarget "MyProject" */;
buildPhases = (
);
buildRules = (
);
dependencies = (
);
name = MyProject;
productName = MyProject;
};
/* End PBXAggregateTarget section */
]]
end
function suite.PBXAggregateTarget_OnBuildCommands()
kind "Utility"
prebuildcommands { "prebuildcmd" }
prelinkcommands { "prelinkcmd" }
postbuildcommands { "postbuildcmd" }
prepare()
xcode.PBXAggregateTarget(tr)
test.capture [[
/* Begin PBXAggregateTarget section */
[MyProject:target] /* MyProject */ = {
isa = PBXAggregateTarget;
buildConfigurationList = [MyProject:cfg] /* Build configuration list for PBXAggregateTarget "MyProject" */;
buildPhases = (
9607AE1010C857E500CD1376 /* Prebuild */,
9607AE3510C85E7E00CD1376 /* Prelink */,
9607AE3710C85E8F00CD1376 /* Postbuild */,
);
buildRules = (
);
dependencies = (
);
name = MyProject;
productName = MyProject;
};
/* End PBXAggregateTarget section */
]]
end
---------------------------------------------------------------------------
-- PBXProject tests
---------------------------------------------------------------------------
@ -953,6 +1035,50 @@
end
function suite.XCBuildConfigurationTarget_OnOSXBundle()
kind "SharedLib"
sharedlibtype "OSXBundle"
prepare()
xcode.XCBuildConfiguration_Target(tr, tr.products.children[1], tr.configs[1])
test.capture [[
[MyProject.bundle:Debug] /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = bin/Debug;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
PRODUCT_NAME = MyProject;
};
name = Debug;
};
]]
end
function suite.XCBuildConfigurationTarget_OnOSXFramework()
kind "SharedLib"
sharedlibtype "OSXFramework"
prepare()
xcode.XCBuildConfiguration_Target(tr, tr.products.children[1], tr.configs[1])
test.capture [[
[MyProject.framework:Debug] /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = bin/Debug;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
PRODUCT_NAME = MyProject;
};
name = Debug;
};
]]
end
function suite.XCBuildConfigurationTarget_OnTargetPrefix()
kind "SharedLib"
targetprefix "xyz"
@ -976,7 +1102,51 @@
end
function suite.XCBuildConfigurationTarget_OnTargetExtension()
function suite.XCBuildConfigurationTarget_OnConsoleAppTargetExtension()
kind "ConsoleApp"
targetextension ".xyz"
prepare()
xcode.XCBuildConfiguration_Target(tr, tr.products.children[1], tr.configs[1])
test.capture [[
[MyProject.xyz:Debug] /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = bin/Debug;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = MyProject.xyz;
};
name = Debug;
};
]]
end
function suite.XCBuildConfigurationTarget_OnConsoleAppNoTargetExtension()
kind "ConsoleApp"
targetextension ""
prepare()
xcode.XCBuildConfiguration_Target(tr, tr.products.children[1], tr.configs[1])
test.capture [[
[MyProject:Debug] /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = bin/Debug;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/bin;
PRODUCT_NAME = MyProject;
};
name = Debug;
};
]]
end
function suite.XCBuildConfigurationTarget_OnSharedLibTargetExtension()
kind "SharedLib"
targetextension ".xyz"
prepare()
@ -1000,6 +1170,218 @@
end
function suite.XCBuildConfigurationTarget_OnSharedLibNoTargetExtension()
kind "SharedLib"
targetextension ""
prepare()
xcode.XCBuildConfiguration_Target(tr, tr.products.children[1], tr.configs[1])
test.capture [[
[libMyProject:Debug] /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = bin/Debug;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = "";
EXECUTABLE_PREFIX = lib;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = MyProject;
};
name = Debug;
};
]]
end
function suite.XCBuildConfigurationTarget_OnStaticLibTargetExtension()
kind "StaticLib"
targetextension ".xyz"
prepare()
xcode.XCBuildConfiguration_Target(tr, tr.products.children[1], tr.configs[1])
test.capture [[
[libMyProject.xyz:Debug] /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = bin/Debug;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = xyz;
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = MyProject;
};
name = Debug;
};
]]
end
function suite.XCBuildConfigurationTarget_OnStaticLibNoTargetExtension()
kind "StaticLib"
targetextension ""
prepare()
xcode.XCBuildConfiguration_Target(tr, tr.products.children[1], tr.configs[1])
test.capture [[
[libMyProject:Debug] /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = bin/Debug;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
EXECUTABLE_EXTENSION = "";
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = /usr/local/lib;
PRODUCT_NAME = MyProject;
};
name = Debug;
};
]]
end
function suite.XCBuildConfigurationTarget_OnWindowedAppTargetExtension()
kind "WindowedApp"
targetextension ".xyz"
prepare()
xcode.XCBuildConfiguration_Target(tr, tr.products.children[1], tr.configs[1])
test.capture [[
[MyProject.xyz:Debug] /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = bin/Debug;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = "\"$(HOME)/Applications\"";
PRODUCT_NAME = MyProject;
WRAPPER_EXTENSION = xyz;
};
name = Debug;
};
]]
end
function suite.XCBuildConfigurationTarget_OnWindowedAppNoTargetExtension()
kind "WindowedApp"
targetextension ""
prepare()
xcode.XCBuildConfiguration_Target(tr, tr.products.children[1], tr.configs[1])
test.capture [[
[MyProject:Debug] /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = bin/Debug;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = "\"$(HOME)/Applications\"";
PRODUCT_NAME = MyProject;
WRAPPER_EXTENSION = "";
};
name = Debug;
};
]]
end
function suite.XCBuildConfigurationTarget_OnOSXBundleTargetExtension()
kind "SharedLib"
sharedlibtype "OSXBundle"
targetextension ".xyz"
prepare()
xcode.XCBuildConfiguration_Target(tr, tr.products.children[1], tr.configs[1])
test.capture [[
[MyProject.xyz:Debug] /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = bin/Debug;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
PRODUCT_NAME = MyProject;
WRAPPER_EXTENSION = xyz;
};
name = Debug;
};
]]
end
function suite.XCBuildConfigurationTarget_OnOSXBundleNoTargetExtension()
kind "SharedLib"
sharedlibtype "OSXBundle"
targetextension ""
prepare()
xcode.XCBuildConfiguration_Target(tr, tr.products.children[1], tr.configs[1])
test.capture [[
[MyProject:Debug] /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = bin/Debug;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Bundles";
PRODUCT_NAME = MyProject;
WRAPPER_EXTENSION = "";
};
name = Debug;
};
]]
end
function suite.XCBuildConfigurationTarget_OnOSXFrameworkTargetExtension()
kind "SharedLib"
sharedlibtype "OSXFramework"
targetextension ".xyz"
prepare()
xcode.XCBuildConfiguration_Target(tr, tr.products.children[1], tr.configs[1])
test.capture [[
[MyProject.xyz:Debug] /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = bin/Debug;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
PRODUCT_NAME = MyProject;
WRAPPER_EXTENSION = xyz;
};
name = Debug;
};
]]
end
function suite.XCBuildConfigurationTarget_OnOSXFrameworkNoTargetExtension()
kind "SharedLib"
sharedlibtype "OSXFramework"
targetextension ""
prepare()
xcode.XCBuildConfiguration_Target(tr, tr.products.children[1], tr.configs[1])
test.capture [[
[MyProject:Debug] /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CONFIGURATION_BUILD_DIR = bin/Debug;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
GCC_DYNAMIC_NO_PIC = NO;
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
PRODUCT_NAME = MyProject;
WRAPPER_EXTENSION = "";
};
name = Debug;
};
]]
end
function suite.XCBuildConfigurationTarget_OnInfoPlist()
files { "./a/b/c/MyProject-Info.plist" }
prepare()

View File

@ -262,12 +262,14 @@
function xcode.getproducttype(node)
local types = {
ConsoleApp = "com.apple.product-type.tool",
WindowedApp = "com.apple.product-type.application",
StaticLib = "com.apple.product-type.library.static",
SharedLib = "com.apple.product-type.library.dynamic",
ConsoleApp = "com.apple.product-type.tool",
WindowedApp = "com.apple.product-type.application",
StaticLib = "com.apple.product-type.library.static",
SharedLib = "com.apple.product-type.library.dynamic",
OSXBundle = "com.apple.product-type.bundle",
OSXFramework = "com.apple.product-type.framework",
}
return types[node.cfg.kind]
return types[iif(node.cfg.kind == "SharedLib" and node.cfg.sharedlibtype, node.cfg.sharedlibtype, node.cfg.kind)]
end
@ -282,12 +284,14 @@
function xcode.gettargettype(node)
local types = {
ConsoleApp = "\"compiled.mach-o.executable\"",
WindowedApp = "wrapper.application",
StaticLib = "archive.ar",
SharedLib = "\"compiled.mach-o.dylib\"",
ConsoleApp = "\"compiled.mach-o.executable\"",
WindowedApp = "wrapper.application",
StaticLib = "archive.ar",
SharedLib = "\"compiled.mach-o.dylib\"",
OSXBundle = "wrapper.cfbundle",
OSXFramework = "wrapper.framework",
}
return types[node.cfg.kind]
return types[iif(node.cfg.kind == "SharedLib" and node.cfg.sharedlibtype, node.cfg.sharedlibtype, node.cfg.kind)]
end
@ -449,10 +453,9 @@
-- is this the product node, describing the output target?
if node.kind == "product" then
local name = iif(tr.project.kind ~= "ConsoleApp", node.name, node.cfg.buildtarget.prefix .. node.cfg.buildtarget.basename)
settings[node.id] = function(level)
_p(level,'%s /* %s */ = {isa = PBXFileReference; explicitFileType = %s; includeInIndex = 0; name = %s; path = %s; sourceTree = BUILT_PRODUCTS_DIR; };',
node.id, node.name, xcode.gettargettype(node), stringifySetting(name), stringifySetting(path.getname(node.cfg.buildtarget.bundlename ~= "" and node.cfg.buildtarget.bundlename or node.cfg.buildtarget.relpath)))
node.id, node.name, xcode.gettargettype(node), stringifySetting(node.name), stringifySetting(path.getname(node.cfg.buildtarget.bundlename ~= "" and node.cfg.buildtarget.bundlename or node.cfg.buildtarget.relpath)))
end
-- is this a project dependency?
elseif node.parent.parent == tr.projects then
@ -572,6 +575,14 @@
return
end
local function isAggregateTarget(node)
local productsId = xcode.newid("Products")
return node.id == productsId and node.parent.project and node.parent.project.kind == "Utility"
end
if isAggregateTarget(node) then
return
end
settings[node.productgroupid or node.id] = function()
-- project references get special treatment
if node.parent == tr.projects then
@ -583,7 +594,9 @@
_p(3,'isa = PBXGroup;')
_p(3,'children = (')
for _, childnode in ipairs(node.children) do
_p(4,'%s /* %s */,', childnode.id, childnode.name)
if not isAggregateTarget(childnode) then
_p(4,'%s /* %s */,', childnode.id, childnode.name)
end
end
_p(3,');')
@ -618,8 +631,30 @@
end
function xcode.PBXNativeTarget(tr)
_p('/* Begin PBXNativeTarget section */')
local function xcode_PBXAggregateOrNativeTarget(tr, pbxTargetName)
local kinds = {
Aggregate = {
"Utility",
},
Native = {
"ConsoleApp",
"WindowedApp",
"SharedLib",
"StaticLib",
},
}
local hasTarget = false
for _, node in ipairs(tr.products.children) do
hasTarget = table.contains(kinds[pbxTargetName], node.cfg.kind)
if hasTarget then
break
end
end
if not hasTarget then
return
end
_p('/* Begin PBX%sTarget section */', pbxTargetName)
for _, node in ipairs(tr.products.children) do
local name = tr.project.name
@ -641,18 +676,22 @@
end
_p(2,'%s /* %s */ = {', node.targetid, name)
_p(3,'isa = PBXNativeTarget;')
_p(3,'buildConfigurationList = %s /* Build configuration list for PBXNativeTarget "%s" */;', node.cfgsection, escapeSetting(name))
_p(3,'isa = PBX%sTarget;', pbxTargetName)
_p(3,'buildConfigurationList = %s /* Build configuration list for PBX%sTarget "%s" */;', node.cfgsection, pbxTargetName, escapeSetting(name))
_p(3,'buildPhases = (')
if hasBuildCommands('prebuildcommands') then
_p(4,'9607AE1010C857E500CD1376 /* Prebuild */,')
end
_p(4,'%s /* Resources */,', node.resstageid)
_p(4,'%s /* Sources */,', node.sourcesid)
if pbxTargetName == "Native" then
_p(4,'%s /* Resources */,', node.resstageid)
_p(4,'%s /* Sources */,', node.sourcesid)
end
if hasBuildCommands('prelinkcommands') then
_p(4,'9607AE3510C85E7E00CD1376 /* Prelink */,')
end
_p(4,'%s /* Frameworks */,', node.fxstageid)
if pbxTargetName == "Native" then
_p(4,'%s /* Frameworks */,', node.fxstageid)
end
if hasBuildCommands('postbuildcommands') then
_p(4,'9607AE3710C85E8F00CD1376 /* Postbuild */,')
end
@ -668,26 +707,40 @@
_p(3,'name = %s;', stringifySetting(name))
local p
if node.cfg.kind == "ConsoleApp" then
p = "$(HOME)/bin"
elseif node.cfg.kind == "WindowedApp" then
p = "$(HOME)/Applications"
end
if p then
_p(3,'productInstallPath = %s;', stringifySetting(p))
if pbxTargetName == "Native" then
local p
if node.cfg.kind == "ConsoleApp" then
p = "$(HOME)/bin"
elseif node.cfg.kind == "WindowedApp" then
p = "$(HOME)/Applications"
end
if p then
_p(3,'productInstallPath = %s;', stringifySetting(p))
end
end
_p(3,'productName = %s;', stringifySetting(name))
_p(3,'productReference = %s /* %s */;', node.id, node.name)
_p(3,'productType = %s;', stringifySetting(xcode.getproducttype(node)))
if pbxTargetName == "Native" then
_p(3,'productReference = %s /* %s */;', node.id, node.name)
_p(3,'productType = %s;', stringifySetting(xcode.getproducttype(node)))
end
_p(2,'};')
end
_p('/* End PBXNativeTarget section */')
_p('/* End PBX%sTarget section */', pbxTargetName)
_p('')
end
function xcode.PBXAggregateTarget(tr)
xcode_PBXAggregateOrNativeTarget(tr, "Aggregate")
end
function xcode.PBXNativeTarget(tr)
xcode_PBXAggregateOrNativeTarget(tr, "Native")
end
function xcode.PBXProject(tr)
_p('/* Begin PBXProject section */')
_p(2,'08FB7793FE84155DC02AAC07 /* Project object */ = {')
@ -911,13 +964,21 @@
settings['EXECUTABLE_PREFIX'] = cfg.buildtarget.prefix
end
if cfg.kind ~= "ConsoleApp" and cfg.targetextension then
local ext = cfg.targetextension
ext = iif(ext:startswith('.'), ext:sub(2), ext)
if cfg.kind == "WindowedApp" and ext ~= "app" then
settings['WRAPPER_EXTENSION'] = ext
elseif (cfg.kind == "StaticLib" and ext ~= "a") or (cfg.kind == "SharedLib" and ext ~= "dylib") then
settings['EXECUTABLE_EXTENSION'] = ext
if cfg.buildtarget.extension then
local exts = {
WindowedApp = "app",
SharedLib = "dylib",
StaticLib = "a",
OSXBundle = "bundle",
OSXFramework = "framework",
}
local ext = cfg.buildtarget.extension:sub(2)
if ext ~= exts[iif(cfg.kind == "SharedLib" and cfg.sharedlibtype, cfg.sharedlibtype, cfg.kind)] then
if cfg.kind == "WindowedApp" or (cfg.kind == "SharedLib" and cfg.sharedlibtype) then
settings['WRAPPER_EXTENSION'] = ext
elseif cfg.kind == "SharedLib" or cfg.kind == "StaticLib" then
settings['EXECUTABLE_EXTENSION'] = ext
end
end
end
@ -932,13 +993,15 @@
settings['INFOPLIST_FILE'] = config.findfile(cfg, path.getextension(tr.infoplist.name))
end
installpaths = {
local installpaths = {
ConsoleApp = '/usr/local/bin',
WindowedApp = '"$(HOME)/Applications"',
SharedLib = '/usr/local/lib',
StaticLib = '/usr/local/lib',
OSXBundle = '$(LOCAL_LIBRARY_DIR)/Bundles',
OSXFramework = '$(LOCAL_LIBRARY_DIR)/Frameworks',
}
settings['INSTALL_PATH'] = installpaths[cfg.kind]
settings['INSTALL_PATH'] = installpaths[iif(cfg.kind == "SharedLib" and cfg.sharedlibtype, cfg.sharedlibtype, cfg.kind)]
local fileNameList = {}
local file_tree = project.getsourcetree(tr.project)
@ -965,7 +1028,7 @@
if not table.isempty(fileNameList) then
settings['EXCLUDED_SOURCE_FILE_NAMES'] = fileNameList
end
settings['PRODUCT_NAME'] = cfg.buildtarget.basename
settings['PRODUCT_NAME'] = iif(cfg.kind == "ConsoleApp" and cfg.buildtarget.extension, cfg.buildtarget.basename .. cfg.buildtarget.extension, cfg.buildtarget.basename)
if os.istarget(p.IOS) then
settings['SDKROOT'] = 'iphoneos'

View File

@ -210,6 +210,7 @@
xcode.PBXFrameworksBuildPhase(tr)
xcode.PBXGroup(tr)
xcode.PBXNativeTarget(tr)
xcode.PBXAggregateTarget(tr)
xcode.PBXProject(tr)
xcode.PBXReferenceProxy(tr)
xcode.PBXResourcesBuildPhase(tr)

View File

@ -590,6 +590,12 @@
kind = "string",
}
api.register {
name = "csversion",
scope = "config",
kind = "string",
}
api.register {
name = "gccprefix",
scope = "config",
@ -1761,6 +1767,14 @@
filter { "system:MacOSX", "kind:SharedLib" }
targetextension ".dylib"
filter { "system:MacOSX", "kind:SharedLib", "sharedlibtype:OSXBundle" }
targetprefix ""
targetextension ".bundle"
filter { "system:MacOSX", "kind:SharedLib", "sharedlibtype:OSXFramework" }
targetprefix ""
targetextension ".framework"
-- Windows and friends.
filter { "system:Windows or language:C# or language:F#", "kind:ConsoleApp or WindowedApp" }

View File

@ -48,9 +48,9 @@
local bundlename = ""
local bundlepath = ""
if cfg.system == p.MACOSX and kind == p.WINDOWEDAPP then
if cfg.system == p.MACOSX and (kind == p.WINDOWEDAPP or (kind == p.SHAREDLIB and cfg.sharedlibtype)) then
bundlename = basename .. extension
bundlepath = path.join(bundlename, "Contents/MacOS")
bundlepath = path.join(bundlename, iif(kind == p.SHAREDLIB and cfg.sharedlibtype == "OSXFramework", "Versions/A", "Contents/MacOS"))
end
local info = {}

View File

@ -31,6 +31,7 @@
_options = true,
options = true,
platforms = true,
sharedlibtype = true,
system = true,
toolset = true,
tags = true,

View File

@ -100,8 +100,8 @@
local environ = {}
local fsub = context.new(prj, environ)
context.copyFilters(fsub, cfg)
context.mergeFilters(fsub, fcfg)
context.copyFilters(fsub, fcfg)
context.mergeFilters(fsub, cfg)
fcfg.configs[cfg] = fsub

View File

@ -601,6 +601,9 @@
-- if a kind is set, allow that to influence the configuration
context.addFilter(ctx, "kind", ctx.kind)
-- if a sharedlibtype is set, allow that to influence the configuration
context.addFilter(ctx, "sharedlibtype", ctx.sharedlibtype)
-- if tags are set, allow that to influence the configuration
context.addFilter(ctx, "tags", ctx.tags)

View File

@ -34,6 +34,9 @@ void do_getabsolute(char* result, const char* value, const char* relative_to)
result[0] = '\0';
if (buffer[0] == '/') {
strcat(result, "/");
if (buffer[1] == '/') {
strcat(result, "/");
}
}
prev = NULL;

View File

@ -67,6 +67,14 @@ int path_getrelative(lua_State* L)
return 1;
}
/* Relative paths within a server can't climb outside the server root.
* If the paths don't share server name, return the absolute path. */
if (src[0] == '/' && src[1] == '/' && last == 1) {
dst[strlen(dst) - 1] = '\0';
lua_pushstring(L, dst);
return 1;
}
/* count remaining levels in src */
count = 0;
for (i = last + 1; src[i] != '\0'; ++i) {

View File

@ -8,128 +8,124 @@
#include <ctype.h>
#include <string.h>
// isspace custom version (visual c++'s one doesn't like utf8 characters)
static int is_space(char c)
{
return (c >= 9 && c <= 13) || c == 32;
}
#define IS_SEP(__c) ((__c) == '/' || (__c) == '\\')
static void* normalize_substring(const char* str, const char* endPtr, char* writePtr) {
const char* const source = str;
const char* const writeBegin = writePtr;
const char* ptr;
char last = 0;
char ch;
#define IS_UPPER_ALPHA(__c) ((__c) >= 'A' && (__c) <= 'Z')
#define IS_LOWER_ALPHA(__c) ((__c) >= 'a' && (__c) <= 'z')
#define IS_ALPHA(__c) (IS_UPPER_ALPHA(__c) || IS_LOWER_ALPHA(__c))
while (str != endPtr) {
ch = (*str);
#define IS_SPACE(__c) ((__c >= '\t' && __c <= '\r') || __c == ' ')
/* make sure we're using '/' for all separators */
if (ch == '\\') {
ch = '/';
}
static void* normalize_substring(const char* srcPtr, const char* srcEnd, char* dstPtr) {
/* filter out .. except when it's part of the file or folder name */
if (ch == '.' && last == '.' && *(str - 2) == '/' && (*(str + 1) == '/' || str + 1 == endPtr)) {
last = 0;
#define IS_END(__p) (__p >= srcEnd || *__p == '\0')
#define IS_SEP_OR_END(__p) (IS_END(__p) || IS_SEP(*__p))
ptr = writePtr - 3;
while (ptr >= writeBegin) {
/* break on '/' except when it's '/../' */
if (ptr[0] == '/' && !(ptr[1] == '.' && ptr[2] == '.' && ptr[3] == '/')) {
writePtr -= writePtr - ptr;
// Handle Windows absolute paths
if (IS_ALPHA(srcPtr[0]) && srcPtr[1] == ':')
{
*(dstPtr++) = srcPtr[0];
*(dstPtr++) = ':';
/* special fix for cases, when '..' is the last chars in path i.e. d:\game\.., this should be converted into d:\,
but without this case, it will be converted into d: */
if (writePtr - 1 >= writeBegin && *(writePtr - 1) == ':' && str + 1 == endPtr) {
++writePtr;
}
break;
}
--ptr;
}
if (ptr < writeBegin) {
*(writePtr++) = ch;
}
++str;
continue;
}
/* filter out /./ */
if (ch == '/' && last == '.') {
ptr = str - 2;
if (*ptr == '/') { // there is no need to check whether ptr >= source since all the leading ./ will be skipped in path_normalize
if (ptr - 1 < source || *(ptr - 1) != ':') {
--writePtr;
}
++str;
continue;
}
}
/* add to the result, filtering out duplicate slashes */
if (ch != '/' || last != '/') {
*(writePtr++) = ch;
}
last = ch;
++str;
srcPtr += 2;
}
/* remove any trailing slashes, except those, that follow the ':', to avoid a path corruption i.e. D:\ -> D: */
while (*(--endPtr) == '/' && *(endPtr - 1) != ':') {
--writePtr;
// Handle path starting with a sep (C:/ or /)
if (IS_SEP(*srcPtr))
{
++srcPtr;
*(dstPtr++) = '/';
// Handle path starting with //
if (IS_SEP(*srcPtr))
{
++srcPtr;
*(dstPtr++) = '/';
}
}
*writePtr = *str;
const char * const dstRoot = dstPtr;
unsigned int folderDepth = 0;
return writePtr;
while (!IS_END(srcPtr))
{
// Skip multiple sep and "./" pattern
while (IS_SEP(*srcPtr) || (srcPtr[0] == '.' && IS_SEP_OR_END(&srcPtr[1])))
++srcPtr;
if (IS_END(srcPtr))
break;
// Handle "../ pattern"
if (srcPtr[0] == '.' && srcPtr[1] == '.' && IS_SEP_OR_END(&srcPtr[2]))
{
if (folderDepth > 0)
{
// Here dstPtr[-1] is safe as folderDepth > 0.
while (--dstPtr != dstRoot && !IS_SEP(dstPtr[-1]));
--folderDepth;
}
else
{
*(dstPtr++) = '.';
*(dstPtr++) = '.';
*(dstPtr++) = '/';
}
srcPtr += 3;
}
else
{
while (!IS_SEP_OR_END(srcPtr))
*(dstPtr++) = *(srcPtr++);
if (IS_SEP(*srcPtr))
{
*(dstPtr++) = '/';
++srcPtr;
++folderDepth;
}
}
}
// Remove trailing slash except for C:/ or / (root)
while (dstPtr != dstRoot && IS_SEP(dstPtr[-1]))
--dstPtr;
return dstPtr;
}
int path_normalize(lua_State* L)
{
const char* path = luaL_checkstring(L, 1);
const char* readPtr = path;
const char *path = luaL_checkstring(L, 1);
const char *readPtr = path;
char buffer[0x4000] = { 0 };
char* writePtr = buffer;
const char* endPtr;
char *writePtr = buffer;
const char *endPtr;
// skip leading white spaces
while (*readPtr && is_space(*readPtr)) {
while (IS_SPACE(*readPtr))
++readPtr;
}
endPtr = readPtr;
while (*endPtr) {
/* remove any leading "./" sequences */
while (strncmp(readPtr, "./", 2) == 0) {
readPtr += 2;
}
// find the end of sub path
while (*endPtr && !is_space(*endPtr)) {
while (*endPtr && !IS_SPACE(*endPtr))
++endPtr;
}
writePtr = normalize_substring(readPtr, endPtr, writePtr);
// skip any white spaces between sub paths
while (*endPtr && is_space(*endPtr)) {
while (IS_SPACE(*endPtr))
*(writePtr++) = *(endPtr++);
}
readPtr = endPtr;
}
// skip any trailing white spaces
while (is_space(*(--endPtr))) {
while (writePtr != buffer && IS_SPACE(writePtr[-1]))
--writePtr;
}
*writePtr = 0;

View File

@ -48,6 +48,10 @@
test.isequal("%HOME%/user", path.getabsolute("%HOME%/user"))
end
function suite.getabsolute_onServerPath()
test.isequal("//Server/Volume", path.getabsolute("//Server/Volume"))
end
function suite.getabsolute_onMultipleEnvVar()
test.isequal("$(HOME)/$(USER)", path.getabsolute("$(HOME)/$(USER)"))
end
@ -336,6 +340,10 @@
test.isequal("obj/debug", path.getrelative("C:/Code/Premake4", "C:/Code/Premake4/obj/debug"))
end
function suite.getrelative_ReturnsChildPath_OnServerPath()
test.isequal("../Volume", path.getrelative("//Server/Shared", "//Server/Volume"))
end
function suite.getrelative_ReturnsAbsPath_OnDifferentDriveLetters()
test.isequal("D:/Files", path.getrelative("C:/Code/Premake4", "D:/Files"))
end
@ -348,6 +356,14 @@
test.isequal("/opt/include", path.getrelative("/home/me/src/project", "/opt/include"))
end
function suite.getrelative_ReturnsAbsPath_OnServerPath()
test.isequal("//Server/Volume", path.getrelative("C:/Files", "//Server/Volume"))
end
function suite.getrelative_ReturnsAbsPath_OnDifferentServers()
test.isequal("//Server/Volume", path.getrelative("//Computer/Users", "//Server/Volume"))
end
function suite.getrelative_ignoresExtraSlashes2()
test.isequal("..", path.getrelative("/a//b/c","/a/b"))
end
@ -661,6 +677,11 @@
test.isequal("../../p1/p2/p3/p4/a.pb.cc", p)
end
function suite.normalize_trailingSingleDot()
local p = path.normalize("../../p1/p2/p3/p4/./.")
test.isequal("../../p1/p2/p3/p4", p)
end
function suite.normalize()
test.isequal("d:/ProjectB/bin", path.normalize("d:/ProjectA/../ProjectB/bin"))
test.isequal("/ProjectB/bin", path.normalize("/ProjectA/../ProjectB/bin"))
@ -693,3 +714,8 @@
test.isequal("d:/test/..test/.test", path.normalize("d:/test/..test/test/../.test"))
test.isequal("d:/test", path.normalize("d:/test/..test/../.test/.."))
end
function suite.normalize_serverpath()
test.isequal("//myawesomeserver/test", path.normalize("//myawesomeserver/test/"))
test.isequal("//myawesomeserver/test", path.normalize("///myawesomeserver/test/"))
end

View File

@ -219,6 +219,32 @@
end
--
-- Bundle path should be set for macOS/iOS cocoa bundle.
--
function suite.bundlepathSet_onMacSharedLibOSXBundle()
kind "SharedLib"
sharedlibtype "OSXBundle"
system "macosx"
i = prepare()
test.isequal("bin/Debug/MyProject.bundle/Contents/MacOS", path.getrelative(os.getcwd(), i.bundlepath))
end
--
-- Bundle path should be set for macOS/iOS framework.
--
function suite.bundlepathSet_onMacSharedLibOSXFramework()
kind "SharedLib"
sharedlibtype "OSXFramework"
system "macosx"
i = prepare()
test.isequal("bin/Debug/MyProject.framework/Versions/A", path.getrelative(os.getcwd(), i.bundlepath))
end
--
-- Target extension is used if set.
--