123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642 |
- --
- -- android/vsandroid_vcxproj.lua
- -- vs-android integration for vstudio.
- -- Copyright (c) 2012-2015 Manu Evans and the Premake project
- --
- local p = premake
- p.modules.vsandroid = { }
- local android = p.modules.android
- local vsandroid = p.modules.vsandroid
- local vc2010 = p.vstudio.vc2010
- local vstudio = p.vstudio
- local project = p.project
- local config = p.config
- --
- -- Utility functions
- --
- local function setBoolOption(optionName, flag, value)
- if flag ~= nil then
- vc2010.element(optionName, nil, value)
- end
- end
- --
- -- Add android tools to vstudio actions.
- --
- if vstudio.vs2010_architectures ~= nil then
- if _ACTION >= "vs2015" then
- vstudio.vs2010_architectures.arm = "ARM"
- else
- vstudio.vs2010_architectures.android = "Android"
- end
- end
- --
- -- Extend global properties
- --
- premake.override(vc2010.elements, "globals", function (oldfn, prj)
- local elements = oldfn(prj)
- if prj.system == premake.ANDROID and prj.kind ~= premake.PACKAGING then
- -- Remove "IgnoreWarnCompileDuplicatedFilename".
- local pos = table.indexof(elements, vc2010.ignoreWarnDuplicateFilename)
- table.remove(elements, pos)
- elements = table.join(elements, {
- android.androidApplicationType
- })
- end
- return elements
- end)
- premake.override(vc2010.elements, "globalsCondition", function (oldfn, prj, cfg)
- local elements = oldfn(prj, cfg)
- if cfg.system == premake.ANDROID and cfg.system ~= prj.system and cfg.kind ~= premake.PACKAGING then
- elements = table.join(elements, {
- android.androidApplicationType
- })
- end
- return elements
- end)
- function android.androidApplicationType(cfg)
- vc2010.element("Keyword", nil, "Android")
- vc2010.element("RootNamespace", nil, "%s", cfg.project.name)
- if _ACTION >= "vs2019" then
- vc2010.element("MinimumVisualStudioVersion", nil, "16.0")
- elseif _ACTION >= "vs2017" then
- vc2010.element("MinimumVisualStudioVersion", nil, "15.0")
- elseif _ACTION >= "vs2015" then
- vc2010.element("MinimumVisualStudioVersion", nil, "14.0")
- end
- vc2010.element("ApplicationType", nil, "Android")
- if _ACTION >= "vs2017" then
- vc2010.element("ApplicationTypeRevision", nil, "3.0")
- elseif _ACTION >= "vs2015" then
- vc2010.element("ApplicationTypeRevision", nil, "2.0")
- else
- vc2010.element("ApplicationTypeRevision", nil, "1.0")
- end
- end
- --
- -- Extend configurationProperties.
- --
- premake.override(vc2010.elements, "configurationProperties", function(oldfn, cfg)
- local elements = oldfn(cfg)
- if cfg.kind ~= p.UTILITY and cfg.kind ~= p.PACKAGING and cfg.system == premake.ANDROID then
- table.remove(elements, table.indexof(elements, vc2010.characterSet))
- table.remove(elements, table.indexof(elements, vc2010.wholeProgramOptimization))
- table.remove(elements, table.indexof(elements, vc2010.windowsSDKDesktopARMSupport))
- elements = table.join(elements, {
- android.androidAPILevel,
- android.androidStlType,
- })
- if _ACTION >= "vs2015" then
- elements = table.join(elements, {
- android.thumbMode,
- })
- end
- end
- return elements
- end)
- function android.androidAPILevel(cfg)
- if cfg.androidapilevel ~= nil then
- vc2010.element("AndroidAPILevel", nil, "android-" .. cfg.androidapilevel)
- end
- end
- function android.androidStlType(cfg)
- if cfg.stl ~= nil then
- local stlType = {
- ["none"] = "system",
- ["gabi++"] = "gabi++",
- ["stlport"] = "stlport",
- ["gnu"] = "gnustl",
- ["libc++"] = "c++",
- }
- local postfix = iif(cfg.staticruntime == "On", "_static", "_shared")
- local runtimeLib = iif(cfg.stl == "none", "system", stlType[cfg.stl] .. postfix)
- if _ACTION >= "vs2015" then
- vc2010.element("UseOfStl", nil, runtimeLib)
- else
- vc2010.element("AndroidStlType", nil, runtimeLib)
- end
- end
- end
- function android.thumbMode(cfg)
- if cfg.thumbmode ~= nil then
- local thumbMode =
- {
- thumb = "Thumb",
- arm = "ARM",
- disabled = "Disabled",
- }
- vc2010.element("ThumbMode", nil, thumbMode[cfg.thumbmode])
- end
- end
- -- Note: this function is already patched in by vs2012...
- premake.override(vc2010, "platformToolset", function(oldfn, cfg)
- if cfg.system ~= premake.ANDROID then
- return oldfn(cfg)
- end
- if _ACTION >= "vs2015" then
- local gcc_map = {
- ["4.6"] = "GCC_4_6",
- ["4.8"] = "GCC_4_8",
- ["4.9"] = "GCC_4_9",
- }
- local clang_map = {
- ["3.4"] = "Clang_3_4",
- ["3.5"] = "Clang_3_5",
- ["3.6"] = "Clang_3_6",
- ["3.8"] = "Clang_3_8",
- ["5.0"] = "Clang_5_0",
- }
- if cfg.toolchainversion ~= nil then
- local map = iif(cfg.toolset == "gcc", gcc_map, clang_map)
- local ts = map[cfg.toolchainversion]
- if ts == nil then
- p.error('Invalid toolchainversion for the selected toolset (%s).', cfg.toolset or "clang")
- end
- vc2010.element("PlatformToolset", nil, ts)
- end
- else
- local archMap = {
- arm = "armv5te", -- should arm5 be default? vs-android thinks so...
- arm5 = "armv5te",
- arm7 = "armv7-a",
- mips = "mips",
- x86 = "x86",
- }
- local arch = cfg.architecture or "arm"
- if (cfg.architecture ~= nil or cfg.toolchainversion ~= nil) and archMap[arch] ~= nil then
- local defaultToolsetMap = {
- arm = "arm-linux-androideabi-",
- armv5 = "arm-linux-androideabi-",
- armv7 = "arm-linux-androideabi-",
- aarch64 = "aarch64-linux-android-",
- mips = "mipsel-linux-android-",
- mips64 = "mips64el-linux-android-",
- x86 = "x86-",
- x86_64 = "x86_64-",
- }
- local toolset = defaultToolsetMap[arch]
- if cfg.toolset == "clang" then
- error("The clang toolset is not yet supported by vs-android", 2)
- toolset = toolset .. "clang"
- elseif cfg.toolset and cfg.toolset ~= "gcc" then
- error("Toolset not supported by the android NDK: " .. cfg.toolset, 2)
- end
- local version = cfg.toolchainversion or iif(cfg.toolset == "clang", "3.5", "4.9")
- vc2010.element("PlatformToolset", nil, toolset .. version)
- vc2010.element("AndroidArch", nil, archMap[arch])
- end
- end
- end)
- --
- -- Extend clCompile.
- --
- premake.override(vc2010.elements, "clCompile", function(oldfn, cfg)
- local elements = oldfn(cfg)
- if cfg.system == premake.ANDROID then
- elements = table.join(elements, {
- android.debugInformation,
- android.strictAliasing,
- android.fpu,
- android.pic,
- android.shortEnums,
- android.cStandard,
- android.cppStandard,
- })
- if _ACTION >= "vs2015" then
- table.remove(elements, table.indexof(elements, vc2010.debugInformationFormat))
- -- Android has C[pp]LanguageStandard instead.
- table.remove(elements, table.indexof(elements, vc2010.languageStandard))
- -- Ignore multiProcessorCompilation for android projects, they use UseMultiToolTask instead.
- table.remove(elements, table.indexof(elements, vc2010.multiProcessorCompilation))
- -- minimalRebuild also ends up in android projects somehow.
- table.remove(elements, table.indexof(elements, vc2010.minimalRebuild))
- -- VS has NEON support through EnableNeonCodegen.
- table.replace(elements, vc2010.enableEnhancedInstructionSet, android.enableEnhancedInstructionSet)
- -- precompiledHeaderFile support.
- table.replace(elements, vc2010.precompiledHeaderFile, android.precompiledHeaderFile)
- end
- end
- return elements
- end)
- function android.precompiledHeaderFile(fileName, cfg)
- -- Doesn't work for project-relative paths.
- vc2010.element("PrecompiledHeaderFile", nil, "%s", path.getabsolute(path.rebase(fileName, cfg.basedir, cfg.location)))
- end
- function android.debugInformation(cfg)
- if cfg.flags.Symbols then
- _p(3,'<GenerateDebugInformation>true</GenerateDebugInformation>')
- end
- end
- function android.strictAliasing(cfg)
- if cfg.strictaliasing ~= nil then
- vc2010.element("StrictAliasing", nil, iif(cfg.strictaliasing == "Off", "false", "true"))
- end
- end
- function android.fpu(cfg)
- if cfg.fpu ~= nil then
- _p(3,'<SoftFloat>true</SoftFloat>', iif(cfg.fpu == "Software", "true", "false"))
- end
- end
- function android.pic(cfg)
- if cfg.pic ~= nil then
- vc2010.element("PositionIndependentCode", nil, iif(cfg.pic == "On", "true", "false"))
- end
- end
- function android.verboseCompiler(cfg)
- setBoolOption("Verbose", cfg.flags.VerboseCompiler, "true")
- end
- function android.undefineAllPreprocessorDefinitions(cfg)
- setBoolOption("UndefineAllPreprocessorDefinitions", cfg.flags.UndefineAllPreprocessorDefinitions, "true")
- end
- function android.showIncludes(cfg)
- setBoolOption("ShowIncludes", cfg.flags.ShowIncludes, "true")
- end
- function android.dataLevelLinking(cfg)
- setBoolOption("DataLevelLinking", cfg.flags.DataLevelLinking, "true")
- end
- function android.shortEnums(cfg)
- setBoolOption("UseShortEnums", cfg.flags.UseShortEnums, "true")
- end
- function android.cStandard(cfg)
- local c_langmap = {
- ["C98"] = "c98",
- ["C99"] = "c99",
- ["C11"] = "c11",
- ["gnu99"] = "gnu99",
- ["gnu11"] = "gnu11",
- }
- if c_langmap[cfg.cdialect] ~= nil then
- vc2010.element("CLanguageStandard", nil, c_langmap[cfg.cdialect])
- end
- end
- function android.cppStandard(cfg)
- local cpp_langmap = {
- ["C++98"] = "c++98",
- ["C++11"] = "c++11",
- ["C++14"] = "c++1y",
- ["C++17"] = "c++1z",
- ["C++latest"] = "c++1z",
- ["gnu++98"] = "gnu++98",
- ["gnu++11"] = "gnu++11",
- ["gnu++14"] = "gnu++1y",
- ["gnu++17"] = "gnu++1z",
- }
- if cpp_langmap[cfg.cppdialect] ~= nil then
- vc2010.element("CppLanguageStandard", nil, cpp_langmap[cfg.cppdialect])
- end
- end
- p.override(vc2010, "additionalCompileOptions", function(oldfn, cfg, condition)
- if cfg.system == p.ANDROID then
- local opts = cfg.buildoptions
- if cfg.disablewarnings and #cfg.disablewarnings > 0 then
- for _, warning in ipairs(cfg.disablewarnings) do
- table.insert(opts, '-Wno-' .. warning)
- end
- end
- -- -fvisibility=<>
- if cfg.visibility ~= nil then
- table.insert(opts, p.tools.gcc.cxxflags.visibility[cfg.visibility])
- end
- if #opts > 0 then
- opts = table.concat(opts, " ")
- vc2010.element("AdditionalOptions", condition, '%s %%(AdditionalOptions)', opts)
- end
- else
- oldfn(cfg, condition)
- end
- end)
- p.override(vc2010, "warningLevel", function(oldfn, cfg)
- if _ACTION >= "vs2015" and cfg.system == p.ANDROID and cfg.warnings and cfg.warnings ~= "Off" then
- vc2010.element("WarningLevel", nil, "EnableAllWarnings")
- elseif (_ACTION >= "vs2015" and cfg.system == p.ANDROID and cfg.warnings) or not (_ACTION >= "vs2015" and cfg.system == p.ANDROID) then
- oldfn(cfg)
- end
- end)
- premake.override(vc2010, "clCompilePreprocessorDefinitions", function(oldfn, cfg, condition)
- if cfg.system == p.ANDROID then
- vc2010.preprocessorDefinitions(cfg, cfg.defines, false, condition)
- else
- oldfn(cfg, condition)
- end
- end)
- premake.override(vc2010, "exceptionHandling", function(oldfn, cfg, condition)
- if cfg.system == p.ANDROID then
- -- Note: Android defaults to 'off'
- local exceptions = {
- On = "Enabled",
- Off = "Disabled",
- UnwindTables = "UnwindTables",
- }
- if _ACTION >= "vs2015" then
- if exceptions[cfg.exceptionhandling] ~= nil then
- vc2010.element("ExceptionHandling", condition, exceptions[cfg.exceptionhandling])
- end
- else
- if cfg.exceptionhandling == premake.ON then
- vc2010.element("GccExceptionHandling", condition, "true")
- end
- end
- else
- oldfn(cfg, condition)
- end
- end)
- function android.enableEnhancedInstructionSet(cfg)
- if cfg.vectorextensions == "NEON" then
- vc2010.element("EnableNeonCodegen", nil, "true")
- end
- end
- premake.override(vc2010, "runtimeTypeInfo", function(oldfn, cfg, condition)
- if cfg.system == premake.ANDROID then
- -- Note: Android defaults to 'off'
- if cfg.rtti == premake.ON then
- vc2010.element("RuntimeTypeInfo", condition, "true")
- end
- else
- oldfn(cfg, condition)
- end
- end)
- --
- -- Extend Link.
- --
- premake.override(vc2010, "generateDebugInformation", function(oldfn, cfg)
- -- Note: Android specifies the debug info in the clCompile section
- if cfg.system ~= premake.ANDROID then
- oldfn(cfg)
- end
- end)
- --
- -- Add android tools to vstudio actions.
- --
- premake.override(vc2010.elements, "itemDefinitionGroup", function(oldfn, cfg)
- local elements = oldfn(cfg)
- if cfg.system == premake.ANDROID and _ACTION < "vs2015" then
- elements = table.join(elements, {
- android.antBuild,
- })
- end
- return elements
- end)
- function android.antPackage(cfg)
- p.push('<AntPackage>')
- if cfg.androidapplibname ~= nil then
- vc2010.element("AndroidAppLibName", nil, cfg.androidapplibname)
- else
- vc2010.element("AndroidAppLibName", nil, "$(RootNamespace)")
- end
- p.pop('</AntPackage>')
- end
- function android.antBuild(cfg)
- if cfg.kind == premake.STATICLIB or cfg.kind == premake.SHAREDLIB then
- return
- end
- _p(2,'<AntBuild>')
- _p(3,'<AntBuildType>%s</AntBuildType>', iif(premake.config.isDebugBuild(cfg), "Debug", "Release"))
- _p(2,'</AntBuild>')
- end
- premake.override(vc2010, "additionalCompileOptions", function(oldfn, cfg, condition)
- if cfg.system == premake.ANDROID then
- vsandroid.additionalOptions(cfg, condition)
- end
- return oldfn(cfg, condition)
- end)
- premake.override(vc2010.elements, "user", function(oldfn, cfg)
- if cfg.system == p.ANDROID then
- return {}
- else
- return oldfn(cfg)
- end
- end)
- --
- -- Add options unsupported by vs-android UI to <AdvancedOptions>.
- --
- function vsandroid.additionalOptions(cfg)
- if _ACTION >= "vs2015" then
- else
- local function alreadyHas(t, key)
- for _, k in ipairs(t) do
- if string.find(k, key) then
- return true
- end
- end
- return false
- end
- if not cfg.architecture or string.startswith(cfg.architecture, "arm") then
- -- we might want to define the arch to generate better code
- -- if not alreadyHas(cfg.buildoptions, "-march=") then
- -- if cfg.architecture == "armv6" then
- -- table.insert(cfg.buildoptions, "-march=armv6")
- -- elseif cfg.architecture == "armv7" then
- -- table.insert(cfg.buildoptions, "-march=armv7")
- -- end
- -- end
- -- ARM has a comprehensive set of floating point options
- if cfg.fpu ~= "Software" and cfg.floatabi ~= "soft" then
- if cfg.architecture == "armv7" then
- -- armv7 always has VFP, may not have NEON
- if not alreadyHas(cfg.buildoptions, "-mfpu=") then
- if cfg.vectorextensions == "NEON" then
- table.insert(cfg.buildoptions, "-mfpu=neon")
- elseif cfg.fpu == "Hardware" or cfg.floatabi == "softfp" or cfg.floatabi == "hard" then
- table.insert(cfg.buildoptions, "-mfpu=vfpv3-d16") -- d16 is the lowest common denominator
- end
- end
- if not alreadyHas(cfg.buildoptions, "-mfloat-abi=") then
- if cfg.floatabi == "hard" then
- table.insert(cfg.buildoptions, "-mfloat-abi=hard")
- else
- -- Android should probably use softfp by default for compatibility
- table.insert(cfg.buildoptions, "-mfloat-abi=softfp")
- end
- end
- else
- -- armv5/6 may not have VFP
- if not alreadyHas(cfg.buildoptions, "-mfpu=") then
- if cfg.fpu == "Hardware" or cfg.floatabi == "softfp" or cfg.floatabi == "hard" then
- table.insert(cfg.buildoptions, "-mfpu=vfp")
- end
- end
- if not alreadyHas(cfg.buildoptions, "-mfloat-abi=") then
- if cfg.floatabi == "softfp" then
- table.insert(cfg.buildoptions, "-mfloat-abi=softfp")
- elseif cfg.floatabi == "hard" then
- table.insert(cfg.buildoptions, "-mfloat-abi=hard")
- end
- end
- end
- elseif cfg.floatabi == "soft" then
- table.insert(cfg.buildoptions, "-mfloat-abi=soft")
- end
- if cfg.endian == "Little" then
- table.insert(cfg.buildoptions, "-mlittle-endian")
- elseif cfg.endian == "Big" then
- table.insert(cfg.buildoptions, "-mbig-endian")
- end
- elseif cfg.architecture == "mips" then
- -- TODO...
- if cfg.vectorextensions == "MXU" then
- table.insert(cfg.buildoptions, "-mmxu")
- end
- elseif cfg.architecture == "x86" then
- -- TODO...
- end
- end
- end
- --
- -- Disable subsystem.
- --
- p.override(vc2010, "subSystem", function(oldfn, cfg)
- if cfg.system ~= p.ANDROID then
- return oldfn(cfg)
- end
- end)
- --
- -- Remove .lib and list in LibraryDependencies instead of AdditionalDependencies.
- --
- p.override(vc2010, "additionalDependencies", function(oldfn, cfg, explicit)
- if cfg.system == p.ANDROID then
- local links = {}
- -- If we need sibling projects to be listed explicitly, grab them first
- if explicit then
- links = config.getlinks(cfg, "siblings", "fullpath")
- end
- -- Then the system libraries, which come undecorated
- local system = config.getlinks(cfg, "system", "name")
- for i = 1, #system do
- local link = system[i]
- table.insert(links, link)
- end
- -- TODO: When to use LibraryDependencies vs AdditionalDependencies
- if #links > 0 then
- links = path.translate(table.concat(links, ";"))
- vc2010.element("LibraryDependencies", nil, "%%(LibraryDependencies);%s", links)
- end
- else
- return oldfn(cfg, explicit)
- end
- end)
- function android.useMultiToolTask(cfg)
- -- Android equivalent of 'MultiProcessorCompilation'
- if cfg.flags.MultiProcessorCompile then
- vc2010.element("UseMultiToolTask", nil, "true")
- end
- end
- premake.override(vc2010.elements, "outputProperties", function(oldfn, cfg)
- if cfg.system == p.ANDROID then
- return table.join(oldfn(cfg), {
- android.useMultiToolTask,
- })
- else
- return oldfn(cfg)
- end
- end)
- --
- -- Disable override of OutDir. This is breaking deployment.
- --
- p.override(vc2010, "outDir", function(oldfn, cfg)
- if cfg.system ~= p.ANDROID then
- return oldfn(cfg)
- end
- end)
|