From 9fde04053d57ff657b637a68399dc62f6b2dddfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mart=C3=ADn=20Lucas=20Golini?= Date: Sat, 18 May 2019 04:19:41 -0300 Subject: [PATCH] WIP premake5 support. --HG-- branch : dev-premake5 --- premake/modules/androidmk/README.md | 182 ++++ premake/modules/androidmk/_manifest.lua | 7 + premake/modules/androidmk/_preload.lua | 47 + premake/modules/androidmk/androidmk.lua | 56 ++ premake/modules/androidmk/androidmk_api.lua | 140 +++ .../modules/androidmk/androidmk_project.lua | 243 +++++ .../modules/androidmk/androidmk_solution.lua | 175 ++++ premake5.lua | 874 ++++++++++++++++++ 8 files changed, 1724 insertions(+) create mode 100644 premake/modules/androidmk/README.md create mode 100644 premake/modules/androidmk/_manifest.lua create mode 100644 premake/modules/androidmk/_preload.lua create mode 100644 premake/modules/androidmk/androidmk.lua create mode 100644 premake/modules/androidmk/androidmk_api.lua create mode 100644 premake/modules/androidmk/androidmk_project.lua create mode 100644 premake/modules/androidmk/androidmk_solution.lua create mode 100644 premake5.lua diff --git a/premake/modules/androidmk/README.md b/premake/modules/androidmk/README.md new file mode 100644 index 000000000..61f40a1c3 --- /dev/null +++ b/premake/modules/androidmk/README.md @@ -0,0 +1,182 @@ +# premake-androidmk + +Application.mk & Android.mk generator for Premake5. + +This module requires the latest premake version to work (5.0.0 alpha5). + + +## Android.mk API + +Note : All the fields starting with `ndk` are solution-wide, but filters can be applied. + +***** + +`ndkabi` : ABI targets + +Supported values : +Wanted ABIs separated by spaces (e.g. `"armeabi x86 mips"`) +* `armeabi` +* `armeabi-v7a` +* `arm64-v8a` +* `x86` +* `x86_64` +* `mips` +* `mips64` + +Or one of : +* `default` +* `all` + +***** + +`ndkplatform` : Android API version + +Supported values : +* `default` +* `android-3` +* `android-4` +* `android-5` +* `android-8` +* `android-9` +* `android-12` +* `android-13` +* `android-14` +* `android-15` +* `android-16` +* `android-17` +* `android-18` +* `android-19` +* `android-21` + +***** + +`ndkstl` : Standard library + +Supported values : +* `default` +* `libstdc++` +* `gabi++_static` +* `gabi++_shared` +* `stlport_static` +* `stlport_shared` +* `gnustl_static` +* `gnustl_shared` +* `c++_static` +* `c++_shared` + +***** + +`ndktoolchainversion` : Android toolchain version + +Supported values : +* `default` +* `4.8` +* `4.9` +* `clang` +* `clang3.4` +* `clang3.5` + +***** + +`amk_includes` : Include existing Android.mk files + +Supported values : List of files + +***** + +`amk_importmodules` : Import Android.mk modules + +Supported values : List of strings + +***** + +`amk_staticlinks` and `amk_sharedlinks` : Link libs from included Android.mk files and imported modules + +Supported values : List of libraries + +If you want to link to system libraries or other projects in the solution, use `links` instead. + + + +## Premake API support + +Most functions should work as expected. +Some limitations apply, for example you cannot change the output folder. + +`system` and `architecture` are completely ignored. + +You cannot do per ABI filtering yet, but it's technically doable. + +Some useful working commands : + +`rtti "On"` : Enable RTTI + +`exceptionhandling "On"` : Enable C++ exceptions + +`flags { "C++11" }` : Enable C++11 + +`optimize "Off"` or `"Debug"` : Enable debug mode (must be used solution-wide) + +Symbols are always enabled, use ndk-gdb to debug. + + +## Sample code + +```lua +require "androidmk" -- Adjust path if needed + +solution "MySolution" + configurations { "Debug", "Release" } + language "C++" + + location "android/jni" -- Generate files in android project jni folder (recommended) + + ndkabi "all" + ndkplatform "android-12" + + filter "configurations:Release" + optimize "On" + filter "configurations:Debug" + optimize "Debug" + + + project "MyProject" + kind "SharedLib" + includedirs "SDL2/include" + files { + "src/*.cpp", + "SDL2/src/main/android/SDL_android_main.c", + } + + links { + "GLESv1_CM", + "GLESv2", + "log", + } + + amk_includes { + "SDL2/Android.mk", + } + + amk_sharedlinks { + "SDL2", + } +``` + + +It is recommended to create an Application.mk file including your generated one : + +File android/jni/Application.mk : +``` +include $(call my-dir)/MySolution_Application.mk +``` + + +Generate command (in android folder) : +`ndk-build PM5_CONFIG=debug -j` + +Use your own deploy command, mine is : +`ant debug` + +Debug command : +`ndk-gdb-py --gnumake-flag PM5_CONFIG=debug` diff --git a/premake/modules/androidmk/_manifest.lua b/premake/modules/androidmk/_manifest.lua new file mode 100644 index 000000000..e5f61baf0 --- /dev/null +++ b/premake/modules/androidmk/_manifest.lua @@ -0,0 +1,7 @@ +return { + "_preload.lua", + "androidmk.lua", + "androidmk_project.lua", + "androidmk_solution.lua", + "androidmk_api.lua", +} diff --git a/premake/modules/androidmk/_preload.lua b/premake/modules/androidmk/_preload.lua new file mode 100644 index 000000000..f19f35954 --- /dev/null +++ b/premake/modules/androidmk/_preload.lua @@ -0,0 +1,47 @@ +-- +-- _preload.lua +-- Generator for ndk-build makefiles +-- Author : Bastien Brunnenstein +-- + +premake.extensions.androidmk = premake.extensions.androidmk or {} +local androidmk = premake.extensions.androidmk +local make = premake.make + + +androidmk.CONFIG_OPTION = "PM5_CONFIG" + + +newaction { + trigger = "androidmk", + shortname = "Android.mk", + description = "Generate Android.mk files for Android NDK", + + valid_kinds = { + premake.STATICLIB, + premake.SHAREDLIB, + }, + + valid_languages = { "C", "C++" }, + + + onSolution = function(sln) +-- premake.escaper(make.esc) + premake.generate(sln, androidmk.slnApplicationFile(sln), androidmk.generate_applicationmk) + premake.generate(sln, androidmk.slnAndroidFile(sln), androidmk.generate_androidmk) + end, + + onProject = function(prj) +-- premake.escaper(make.esc) + premake.generate(prj, androidmk.prjFile(prj), androidmk.generate_projectmk) + end, + + onCleanSolution = function(sln) + premake.clean.file(sln, androidmk.slnApplicationFile(sln)) + premake.clean.file(sln, androidmk.slnAndroidFile(sln)) + end, + + onCleanProject = function(prj) + premake.clean.file(prj, androidmk.prjFile(prj)) + end +} diff --git a/premake/modules/androidmk/androidmk.lua b/premake/modules/androidmk/androidmk.lua new file mode 100644 index 000000000..513f98d1a --- /dev/null +++ b/premake/modules/androidmk/androidmk.lua @@ -0,0 +1,56 @@ +-- +-- androidmk.lua +-- Generator for ndk-build makefiles +-- Author : Bastien Brunnenstein +-- + +premake.extensions.androidmk = premake.extensions.androidmk or {} +local androidmk = premake.extensions.androidmk + +include "_preload.lua" + + +function androidmk.slnApplicationFile(sln) + return sln.name .."_Application.mk" +end + +function androidmk.slnAndroidFile(sln) + return sln.name .."_Android.mk" +end + + +function androidmk.prjFile(prj) + return prj.name ..".mk" +end + + +androidmk.ldflags = { + flags = { + --LinkTimeOptimization = "-flto", + } +} + +androidmk.cflags = { + flags = { + FatalCompileWarnings = "-Werror", + ShadowedVariables = "-Wshadow", + UndefinedIdentifiers = "-Wundef", + --LinkTimeOptimization = "-flto", + }, + warnings = { + Extra = "-Wall -Wextra", + Off = "-w", + } +} + +androidmk.cppflags = { + flags = { + ["C++11"] = "-std=c++11", + ["C++14"] = "-std=c++14", + } +} + + +include "androidmk_api.lua" +include "androidmk_solution.lua" +include "androidmk_project.lua" diff --git a/premake/modules/androidmk/androidmk_api.lua b/premake/modules/androidmk/androidmk_api.lua new file mode 100644 index 000000000..eb0b3a350 --- /dev/null +++ b/premake/modules/androidmk/androidmk_api.lua @@ -0,0 +1,140 @@ +-- +-- androidmk_api.lua +-- API for Android.mk generator +-- Author : Bastien Brunnenstein +-- + +local api = premake.api + + +-- More info: https://developer.android.com/ndk/guides/abis.html +api.register { + name = "ndkabi", + scope = "config", + kind = "string", + allowed = function(value) + local usedAbis = {} + local validAbis = { + "default", + "armeabi", + "armeabi-v7a", + "arm64-v8a", + "x86", + "x86_64", + "mips", + "mips64", + "all" + } + + for _, v in ipairs(string.explode(value, ' ')) do + if v ~= "" then + if not table.contains(validAbis, v) then + error("ndkabi : "..v.." is not a valid abi") + end + table.insert(usedAbis, v) + end + end + + if #usedAbis == 0 then + error("ndkabi : Invalid parameter") + end + + if table.contains(usedAbis, "all") then + return "all" + else + return table.implode(usedAbis, '', '', ' ') + end + end +} + +-- More info: https://developer.android.com/ndk/guides/stable_apis.html +api.register { + name = "ndkplatform", + scope = "config", + kind = "string", + allowed = { + "default", + "android-3", + "android-4", + "android-5", + "android-8", + "android-9", + "android-12", + "android-13", + "android-14", + "android-15", + "android-16", + "android-17", + "android-18", + "android-19", + "android-21", + "android-22", + "android-23", + "android-24", + "android-25", + "android-26", + "android-27", + "android-28", + }, +} + +-- More info: https://developer.android.com/ndk/guides/cpp-support.html#runtimes +api.register { + name = "ndkstl", + scope = "config", + kind = "string", + allowed = { + "default", + "libstdc++", + "gabi++_static", + "gabi++_shared", + "stlport_static", + "stlport_shared", + "gnustl_static", + "gnustl_shared", + "c++_static", + "c++_shared", + }, +} + +api.register { + name = "ndktoolchainversion", + scope = "config", + kind = "string", + allowed = { + "default", + "4.8", + "4.9", + "clang", + "clang3.4", + "clang3.5", + }, +} + +-- Allows to add existing Android.mk projects +api.register { + name = "amk_includes", + scope = "project", + kind = "list:file", + tokens = true, +} + +api.register { + name = "amk_importmodules", + scope = "project", + kind = "list:string", + tokens = true, +} + +-- Links from includes and imports +api.register { + name = "amk_staticlinks", + scope = "config", + kind = "list:string", +} + +api.register { + name = "amk_sharedlinks", + scope = "config", + kind = "list:string", +} diff --git a/premake/modules/androidmk/androidmk_project.lua b/premake/modules/androidmk/androidmk_project.lua new file mode 100644 index 000000000..2a4a6a225 --- /dev/null +++ b/premake/modules/androidmk/androidmk_project.lua @@ -0,0 +1,243 @@ +-- +-- androidmk_project.lua +-- Generator for Android.mk project files +-- Author : Bastien Brunnenstein +-- + +local androidmk = premake.extensions.androidmk +local make = premake.make +local project = premake.project + +local p = premake + + +function androidmk.generate_projectmk(prj) + premake.eol("\n") + + androidmk.prjHeader(prj) + + -- Prepare the list of files + local rootFiles, cfgFiles = androidmk.prepareSrcFiles(prj) + androidmk.prjSrcFiles(rootFiles) + + for cfg in project.eachconfig(prj) do + p.w('') + p.x('ifeq ($(%s),%s)', androidmk.CONFIG_OPTION, cfg.shortname) + + androidmk.prjIncludes(prj, cfg) + androidmk.prjCppFeatures(prj, cfg) + androidmk.prjCfgSrcFiles(cfgFiles[cfg]) + androidmk.prjDependencies(prj, cfg) + androidmk.prjLdFlags(prj, cfg) + androidmk.prjCFlags(prj, cfg) + + -- Always last + androidmk.prjKind(prj, cfg) + + p.w('endif') + end +end + + +function androidmk.prjHeader(prj) + p.w('LOCAL_PATH := $(call my-dir)') + p.w('include $(CLEAR_VARS)') + p.w('LOCAL_MODULE := %s', prj.name) + if prj.targetname then + p.w('LOCAL_MODULE_FILENAME := %s', prj.targetname) + end + p.w('') +end + +function androidmk.prjKind(prj, cfg) + if cfg.kind == premake.STATICLIB then + p.w(' include $(BUILD_STATIC_LIBRARY)') + + else -- cfg.kind == premake.SHAREDLIB + p.w(' include $(BUILD_SHARED_LIBRARY)') + + end +end + + +function androidmk.prjIncludes(prj, cfg) + if cfg.includedirs then + p.w(' LOCAL_C_INCLUDES := %s', + table.implode( + table.translate( + table.translate(cfg.includedirs, + function(d) + return "$(LOCAL_PATH)/"..project.getrelative(prj, d) + end) + , p.esc) + , '', '', ' ')) + end +end + +function androidmk.prjCppFeatures(prj, cfg) + local features = {} + + if cfg.rtti == p.ON then + table.insert(features, "rtti") + end + + if cfg.exceptionhandling == p.ON then + table.insert(features, "exceptions") + end + + if #features > 0 then + p.w(' LOCAL_CPP_FEATURES := %s', table.implode(features, '', '', ' ')) + end +end + +function androidmk.prepareSrcFiles(prj) + local root = {} + local configs = {} + for cfg in project.eachconfig(prj) do + configs[cfg] = {} + end + + local tr = project.getsourcetree(prj) + premake.tree.traverse(tr, { + onleaf = function(node, depth) + -- Figure out what configurations contain this file + local incfg = {} + local inall = true + for cfg in project.eachconfig(prj) do + local filecfg = premake.fileconfig.getconfig(node, cfg) + if filecfg and not filecfg.flags.ExcludeFromBuild then + incfg[cfg] = filecfg + else + inall = false + end + end + + -- Allow .arm, .neon and .arm.neon files + if not path.iscppfile(node.abspath) and + path.getextension(node.abspath) ~= "arm" and + path.getextension(node.abspath) ~= "neon" then + return + end + + local filename = project.getrelative(prj, node.abspath) + + -- If this file exists in all configurations, write it to + -- the project's list of files, else add to specific cfgs + if inall then + table.insert(root, filename) + else + for cfg in project.eachconfig(prj) do + if incfg[cfg] then + table.insert(configs[cfg], filename) + end + end + end + + end + }) + + return root, configs +end + +function androidmk.prjSrcFiles(files) + p.w('LOCAL_SRC_FILES := %s', table.implode(table.translate(files, p.esc), '', '', ' ')) +end + +function androidmk.prjCfgSrcFiles(files) + if #files > 0 then + p.w(' LOCAL_SRC_FILES += %s', table.implode(table.translate(files, p.esc), '', '', ' ')) + end +end + +function androidmk.prjDependencies(prj, cfg) + local staticdeps = {} + local shareddeps = {} + + local dependencies = premake.config.getlinks(cfg, "dependencies", "object") + for _, dep in ipairs(dependencies) do + if dep.kind == premake.STATICLIB then + table.insert(staticdeps, dep.filename) + else + table.insert(shareddeps, dep.filename) + end + end + + for _, v in ipairs(cfg.amk_staticlinks) do + table.insert(staticdeps, v) + end + for _, v in ipairs(cfg.amk_sharedlinks) do + table.insert(shareddeps, v) + end + + if #staticdeps > 0 then + p.w(' LOCAL_STATIC_LIBRARIES := %s', table.implode(staticdeps, '', '', ' ')) + end + + if #shareddeps > 0 then + p.w(' LOCAL_SHARED_LIBRARIES := %s', table.implode(shareddeps, '', '', ' ')) + end +end + +function androidmk.prjLdFlags(prj, cfg) + -- LDLIBS + local flags = {} + + for _, dir in ipairs(premake.config.getlinks(cfg, "system", "directory")) do + table.insert(flags, '-L' .. premake.quoted(dir)) + end + + for _, name in ipairs(premake.config.getlinks(cfg, "system", "basename")) do + table.insert(flags, "-l" .. name) + end + + if #flags > 0 then + p.w(' LOCAL_LDLIBS := %s', table.implode(table.translate(flags, p.esc), '', '', ' ')) + end + + --LDFLAGS + flags = premake.config.mapFlags(cfg, androidmk.ldflags) + + for _, opt in ipairs(cfg.linkoptions) do + table.insert(flags, opt) + end + + if #flags > 0 then + p.w(' LOCAL_LDFLAGS := %s', table.implode(table.translate(flags, p.esc), '', '', ' ')) + end +end + +function androidmk.prjCFlags(prj, cfg) + local flags = premake.config.mapFlags(cfg, androidmk.cflags) + + -- Defines + for _, def in ipairs(cfg.defines) do + table.insert(flags, '-D' .. def) + end + + -- Warnings + for _, enable in ipairs(cfg.enablewarnings) do + table.insert(flags, '-W' .. enable) + end + for _, disable in ipairs(cfg.disablewarnings) do + table.insert(flags, '-Wno-' .. disable) + end + for _, fatal in ipairs(cfg.fatalwarnings) do + table.insert(flags, '-Werror=' .. fatal) + end + + -- Build options + for _, opt in ipairs(cfg.buildoptions) do + table.insert(flags, opt) + end + + if #flags > 0 then + p.w(' LOCAL_CFLAGS := %s', table.implode(table.translate(flags, p.esc), '', '', ' ')) + end + + + local cppflags = premake.config.mapFlags(cfg, androidmk.cppflags) + + if #cppflags > 0 then + p.w(' LOCAL_CPPFLAGS := %s', table.implode(table.translate(cppflags, p.esc), '', '', ' ')) + end +end diff --git a/premake/modules/androidmk/androidmk_solution.lua b/premake/modules/androidmk/androidmk_solution.lua new file mode 100644 index 000000000..1c1a299d7 --- /dev/null +++ b/premake/modules/androidmk/androidmk_solution.lua @@ -0,0 +1,175 @@ +-- +-- androidmk_solution.lua +-- Generator for Application.mk and Android.mk solution files +-- Author : Bastien Brunnenstein +-- + +local androidmk = premake.extensions.androidmk +local solution = premake.solution +local project = premake.project +local make = premake.make + +local p = premake + + +function androidmk.generate_applicationmk(sln) + premake.eol("\n") + + androidmk.slnBuildScript(sln) + + p.w('PM5_HELP := true') + + for cfg in solution.eachconfig(sln) do + p.w('') + p.x('ifeq ($(%s),%s)', androidmk.CONFIG_OPTION, cfg.shortname) + + androidmk.slnOptim(sln, cfg) + androidmk.slnAbi(sln, cfg) + androidmk.slnPlatform(sln, cfg) + androidmk.slnStl(sln, cfg) + androidmk.slnToolchainVersion(sln, cfg) + + p.w(' PM5_HELP := false') + p.w('endif') + end + + androidmk.slnPremakeHelp(sln) +end + +function androidmk.generate_androidmk(sln) + premake.eol("\n") + local curpath = 'SOLUTION_'..sln.name:upper()..'_PATH' + p.w('%s := $(call my-dir)', curpath) + p.w('') + + for prj in solution.eachproject(sln) do + local prjpath = premake.filename(prj, androidmk.prjFile(prj)) + local prjrelpath = path.getrelative(sln.location, prjpath) + p.x('include $(%s)/%s', curpath, prjrelpath) + end + + for cfg in solution.eachconfig(sln) do + local existingmklist = {} + local moduleslist = {} + + -- Agregate existing Android.mk files for each project per configuration + for prj in solution.eachproject(sln) do + for prjcfg in project.eachconfig(prj) do + if prjcfg.shortname == cfg.shortname then + for _, mkpath in ipairs(prj.amk_includes) do + local mkrelpath = path.getrelative(sln.location, mkpath) + if not table.contains(existingmklist, mkrelpath) then + table.insert(existingmklist, mkrelpath) + end + end + for _, mod in ipairs(prj.amk_importmodules) do + if not table.contains(moduleslist, mod) then + table.insert(moduleslist, mod) + end + end + end + end + end + + if #existingmklist > 0 or #moduleslist > 0 then + p.w('') + p.x('ifeq ($(%s),%s)', androidmk.CONFIG_OPTION, cfg.shortname) + for _, mkpath in ipairs(existingmklist) do + p.x(' include $(%s)/%s', curpath, mkpath) + end + for _, mod in ipairs(moduleslist) do + p.x(' $(call import-module,%s)', mod) + end + p.w('endif') + end + end +end + + +function androidmk.slnBuildScript(sln) + p.x('APP_BUILD_SCRIPT := $(call my-dir)/%s', androidmk.slnAndroidFile(sln)) +end + +function androidmk.slnPremakeHelp(sln) + p.w('') + p.w('ifeq ($(PM5_HELP),true)') + + p.w(' $(info )') + p.w(' $(info Usage:)') + p.w(' $(info $() ndk-build %s=)', androidmk.CONFIG_OPTION) + p.w(' $(info )') + p.w(' $(info CONFIGURATIONS:)') + for cfg in solution.eachconfig(sln) do + p.w(' $(info $() %s)', cfg.shortname) + end + + p.w(' $(info )') + p.w(' $(info For more ndk-build options, see https://developer.android.com/ndk/guides/ndk-build.html)') + p.w(' $(info )') + + p.w(' $(error Set %s and try again)', androidmk.CONFIG_OPTION) + p.w('endif') +end + + +-- Function to make sure that an option in a given config is the same for every project +-- Additionnaly, replace "default" with "nil" +local function agregateOption(sln, cfg, option) + local first = true + local val + for prj in solution.eachproject(sln) do + for prjcfg in project.eachconfig(prj) do + if prjcfg.shortname == cfg.shortname then + if first then + first = false + val = prjcfg[option] + else + if prjcfg[option] ~= val then + error("Value for "..option.." must be the same on every project for configuration "..cfg.longname.." in solution "..sln.name) + end + end + end + end + end + if val == "default" then + return nil + end + return val +end + +function androidmk.slnOptim(sln, cfg) + local optim = agregateOption(sln, cfg, "optimize") + if optim == p.OFF or optim == "Debug" then + p.w(' APP_OPTIM := debug') + elseif optim ~= nil then + p.w(' APP_OPTIM := release') + end +end + +function androidmk.slnAbi(sln, cfg) + local abi = agregateOption(sln, cfg, "ndkabi") + if abi then + p.w(' APP_ABI := %s', abi) + end +end + +function androidmk.slnPlatform(sln, cfg) + local plat = agregateOption(sln, cfg, "ndkplatform") + if plat then + p.w(' APP_PLATFORM := %s', plat) + end +end + +function androidmk.slnStl(sln, cfg) + local stl = agregateOption(sln, cfg, "ndkstl") + if stl then + p.w(' APP_STL := %s', stl) + end +end + +function androidmk.slnToolchainVersion(sln, cfg) + local toolchain = agregateOption(sln, cfg, "ndktoolchainversion") + if toolchain then + p.w(' NDK_TOOLCHAIN_VERSION := %s', toolchain) + end +end diff --git a/premake5.lua b/premake5.lua new file mode 100644 index 000000000..f62d677c2 --- /dev/null +++ b/premake5.lua @@ -0,0 +1,874 @@ +require "premake/modules/androidmk" + +newoption { trigger = "with-ssl", description = "Enables SSL support for the Network module ( by default uses mbedtls. )" } +newoption { trigger = "with-openssl", description = "Enables OpenSSL support ( and disables mbedtls backend )." } +newoption { trigger = "with-static-freetype", description = "Build freetype as a static library." } +newoption { trigger = "with-static-eepp", description = "Force to build the demos and tests with eepp compiled statically" } +newoption { trigger = "with-static-backend", description = "It will try to compile the library with a static backend (only for gcc and mingw).\n\t\t\t\tThe backend should be placed in libs/your_platform/libYourBackend.a" } +newoption { trigger = "with-gles2", description = "Compile with GLES2 support" } +newoption { trigger = "with-gles1", description = "Compile with GLES1 support" } +newoption { trigger = "use-frameworks", description = "In Mac OS X it will try to link the external libraries from its frameworks. For example, instead of linking against SDL2 it will link agains SDL2.framework." } +newoption { + trigger = "with-backend", + description = "Select the backend to use for window and input handling.\n\t\t\tIf no backend is selected or if the selected is not installed the script will search for a backend present in the system, and will use it.", + allowed = { + { "SDL2", "SDL2 (default and recommended)" }, + { "SFML", "SFML2" }, + { "SDL2,SFML", "SDL2+SFML" } + } +} + +function explode(div,str) + if (div=='') then return false end + local pos,arr = 0,{} + for st,sp in function() return string.find(str,div,pos,true) end do + table.insert(arr,string.sub(str,pos,st-1)) + pos = sp + 1 + end + table.insert(arr,string.sub(str,pos)) + return arr +end + +if os.istarget("haiku") and not os.is64bit() then + premake.gcc.cc = "gcc-x86" + premake.gcc.cxx = "g++-x86" + premake.gcc.ar = "ar-x86" +end + +function print_table( table_ref ) + for _, value in pairs( table_ref ) do + print(value) + end +end + +function table_length(T) + local count = 0 + for _ in pairs(T) do count = count + 1 end + return count +end + +function args_contains( element ) + return table.contains( _ARGS, element ) +end + +function multiple_insert( parent_table, insert_table ) + for _, value in pairs( insert_table ) do + table.insert( parent_table, value ) + end +end + +function get_ios_arch() + local archs = explode( "-", _OPTIONS.platform ) + return archs[ table_length( archs ) ] +end + +function os_findlib( name ) + if os.istarget("macosx") and ( is_xcode() or _OPTIONS["use-frameworks"] ) then + local path = "/Library/Frameworks/" .. name .. ".framework" + + if os.isdir( path ) then + return path + end + end + + return os.findlib( name ) +end + +function get_backend_link_name( name ) + if os.istarget("macosx") and ( is_xcode() or _OPTIONS["use-frameworks"] ) then + local fname = name .. ".framework" + + if os_findlib( name ) then -- Search for the framework + return fname + end + end + + return name +end + +function string.starts(String,Start) + if ( _ACTION ) then + return string.sub(String,1,string.len(Start))==Start + end + + return false +end + +function is_vs() + return ( string.starts(_ACTION,"vs") ) +end + +function is_xcode() + return ( string.starts(_ACTION,"xcode") ) +end + +function set_kind() + if os.istarget("macosx") then + kind("ConsoleApp") + else + kind("WindowedApp") + end +end + +link_list = { } +os_links = { } +backends = { } +static_backends = { } +backend_selected = false + +function build_base_configuration( package_name ) + includedirs { "src/thirdparty/zlib" } + + if not os.istarget("windows") then + buildoptions{ "-fPIC" } + end + + if is_vs() then + includedirs { "src/thirdparty/libzip/vs" } + end + + configuration "debug" + defines { "DEBUG" } + symbols "On" + if not is_vs() then + buildoptions{ "-Wall", "-std=gnu99" } + end + targetname ( package_name .. "-debug" ) + + configuration "release" + optimize "Speed" + if not is_vs() then + buildoptions{ "-Wall", "-std=gnu99" } + end + targetname ( package_name ) + + set_ios_config() + set_xcode_config() +end + +function build_base_cpp_configuration( package_name ) + if not os.istarget("windows") then + buildoptions{ "-fPIC" } + end + + set_ios_config() + set_xcode_config() + + configuration "debug" + defines { "DEBUG" } + symbols "On" + if not is_vs() then + buildoptions{ "-Wall" } + end + targetname ( package_name .. "-debug" ) + + configuration "release" + optimize "Speed" + if not is_vs() then + buildoptions{ "-Wall" } + end + targetname ( package_name ) +end + +function add_cross_config_links() + if not is_vs() then + if os.istarget("mingw32") or os.istarget("windows") or os.istarget("ios") then -- if is crosscompiling from *nix + linkoptions { "-static-libgcc", "-static-libstdc++" } + end + + if os.istarget("mingw32") then + linkoptions { "-Wl,-Bstatic -lstdc++ -lpthread -Wl,-Bdynamic" } + end + end +end + +function fix_shared_lib_linking_path( package_name, libname ) + if ( "4.4-beta5" == _PREMAKE_VERSION or "HEAD" == _PREMAKE_VERSION ) and not _OPTIONS["with-static-eepp"] and package_name == "eepp" then + if os.istarget("macosx") then + linkoptions { "-install_name " .. libname .. ".dylib" } + elseif os.istarget("linux") or os.istarget("freebsd") then + linkoptions { "-Wl,-soname=\"" .. libname .. "\"" } + elseif os.istarget("haiku") then + linkoptions { "-Wl,-soname=\"" .. libname .. ".so" .. "\"" } + end + end +end + +function build_link_configuration( package_name, use_ee_icon ) + includedirs { "include" } + + local extension = ""; + + if package_name == "eepp" then + defines { "EE_EXPORTS" } + elseif package_name == "eepp-static" then + defines { "EE_STATIC" } + end + + if not is_vs() then + buildoptions{ "-std=c++14" } + end + + if package_name ~= "eepp" and package_name ~= "eepp-static" then + if not _OPTIONS["with-static-eepp"] then + links { "eepp-shared" } + else + links { "eepp-static" } + defines { "EE_STATIC" } + add_static_links() + links { link_list } + end + + if os.istarget("windows") and not is_vs() then + if ( true == use_ee_icon ) then + linkoptions { "../../bin/assets/icon/ee.res" } + end + end + + if os.istarget("emscripten") then + extension = ".html" + + if ( package_name ~= "eeew" and + package_name ~= "eees" and + package_name ~= "eehttp-request" and + package_name ~= "eephysics" and + package_name ~= "eevbo-fbo-batch" + ) then + linkoptions { "--preload-file assets/" } + end + end + + if _OPTIONS.platform == "ios-cross-arm7" then + extension = ".ios" + end + + if _OPTIONS.platform == "ios-cross-x86" then + extension = ".x86.ios" + end + end + + configuration "debug" + defines { "DEBUG", "EE_DEBUG", "EE_MEMORY_MANAGER" } + symbols "On" + + if not is_vs() and not os.istarget("emscripten") then + buildoptions{ "-Wall -Wno-long-long" } + end + + fix_shared_lib_linking_path( package_name, "libeepp-debug" ) + + targetname ( package_name .. "-debug" .. extension ) + + configuration "release" + optimize "Speed" + + if not is_vs() and not os.istarget("emscripten") then + buildoptions { "-fno-strict-aliasing -ffast-math" } + end + + if not is_vs() and not os.istarget("emscripten") and not os.istarget("macosx") then + buildoptions { "-s" } + end + + fix_shared_lib_linking_path( package_name, "libeepp" ) + + targetname ( package_name .. extension ) + + configuration "windows" + add_cross_config_links() + + configuration "emscripten" + linkoptions{ "-O2 -s TOTAL_MEMORY=67108864 -s ASM_JS=1 -s VERBOSE=1 -s DISABLE_EXCEPTION_CATCHING=0 -s USE_SDL=2 -s ERROR_ON_UNDEFINED_SYMBOLS=0 -s FULL_ES3=1 -s \"BINARYEN_TRAP_MODE='clamp'\"" } + buildoptions { "-fno-strict-aliasing -O2 -s USE_SDL=2 -s PRECISE_F32=1" } + + if _OPTIONS["with-gles1"] and ( not _OPTIONS["with-gles2"] or _OPTIONS["force-gles1"] ) then + linkoptions{ "-s LEGACY_GL_EMULATION=1" } + end + + if _OPTIONS["with-gles2"] and not _OPTIONS["force-gles1"] then + linkoptions{ "-s FULL_ES2=1" } + end + + set_ios_config() + set_xcode_config() +end + +function generate_os_links() + if os.istarget("linux") then + multiple_insert( os_links, { "rt", "pthread", "X11", "openal", "GL", "Xcursor" } ) + + if _OPTIONS["with-static-eepp"] then + table.insert( os_links, "dl" ) + end + elseif os.istarget("windows") then + multiple_insert( os_links, { "OpenAL32", "opengl32", "glu32", "gdi32", "ws2_32", "winmm" } ) + elseif os.istarget("mingw32") then + multiple_insert( os_links, { "OpenAL32", "opengl32", "glu32", "gdi32", "ws2_32", "winmm" } ) + elseif os.istarget("macosx") then + multiple_insert( os_links, { "OpenGL.framework", "OpenAL.framework", "CoreFoundation.framework" } ) + elseif os.istarget("freebsd") then + multiple_insert( os_links, { "rt", "pthread", "X11", "openal", "GL", "Xcursor" } ) + elseif os.istarget("haiku") then + multiple_insert( os_links, { "openal", "GL", "network" } ) + elseif os.istarget("ios") then + multiple_insert( os_links, { "OpenGLES.framework", "OpenAL.framework", "AudioToolbox.framework", "CoreAudio.framework", "Foundation.framework", "CoreFoundation.framework", "UIKit.framework", "QuartzCore.framework", "CoreGraphics.framework" } ) + elseif os.istarget("emscripten") then + multiple_insert( os_links, { "openal" } ) + elseif os.istarget("android") then + multiple_insert( os_links, { "GLESv1_CM", "GLESv2", "log" } ) + end +end + +function parse_args() + if _OPTIONS["with-gles2"] then + defines { "EE_GLES2", "SOIL_GLES2" } + end + + if _OPTIONS["with-gles1"] then + defines { "EE_GLES1", "SOIL_GLES1" } + end +end + +function add_static_links() + -- The linking order DOES matter + -- Expose the symbols that need one static library AFTER adding that static lib + + -- Add static backends + if next(static_backends) ~= nil then + for _, value in pairs( static_backends ) do + linkoptions { value } + end + end + + if _OPTIONS["with-static-freetype"] or not os_findlib("freetype") then + print("Enabled static freetype") + links { "freetype-static" } + end + + links { "SOIL2-static", + "chipmunk-static", + "libzip-static", + "jpeg-compressor-static", + "zlib-static", + "imageresampler-static", + "pugixml-static", + "vorbis-static" + } + + if _OPTIONS["with-ssl"] and not _OPTIONS["with-openssl"] then + links { "mbedtls-static" } + end + + if not os.istarget("haiku") and not os.istarget("ios") and not os.istarget("android") and not os.istarget("emscripten") then + links{ "glew-static" } + end +end + +function can_add_static_backend( name ) + if _OPTIONS["with-static-backend"] then + local path = "libs/" .. os.target() .. "/lib" .. name .. ".a" + return os.isfile(path) + end +end + +function insert_static_backend( name ) + table.insert( static_backends, path.getrelative( "libs/" .. os.target(), "./" ) .. "/libs/" .. os.target() .. "/lib" .. name .. ".a" ) +end + +function add_sdl2() + print("Using SDL2 backend"); + files { "src/eepp/window/backend/SDL2/*.cpp" } + defines { "EE_BACKEND_SDL_ACTIVE", "EE_SDL_VERSION_2" } + + if not can_add_static_backend("SDL2") then + table.insert( link_list, get_backend_link_name( "SDL2" ) ) + else + insert_static_backend( "SDL2" ) + end +end + +function add_sfml() + print("Using SFML backend"); + files { "src/eepp/window/backend/SFML/*.cpp" } + defines { "EE_BACKEND_SFML_ACTIVE" } + + if not can_add_static_backend("SFML") then + table.insert( link_list, get_backend_link_name( "sfml-system" ) ) + table.insert( link_list, get_backend_link_name( "sfml-window" ) ) + else + insert_static_backend( "libsfml-system" ) + insert_static_backend( "libsfml-window" ) + end +end + +function set_xcode_config() + if is_xcode() or _OPTIONS["use-frameworks"] then + linkoptions { "-F/Library/Frameworks" } + includedirs { "/Library/Frameworks/SDL2.framework/Headers" } + defines { "EE_SDL2_FROM_ROOTPATH" } + end +end + +function set_ios_config() + if _OPTIONS.platform == "ios-arm7" or _OPTIONS.platform == "ios-x86" then + local err = false + + if nil == os.getenv("TOOLCHAINPATH") then + print("You must set TOOLCHAINPATH enviroment variable.") + print("\tExample: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/") + err = true + end + + if nil == os.getenv("SYSROOTPATH") then + print("You must set SYSROOTPATH enviroment variable.") + print("\tExample: /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.0.sdk") + err = true + end + + if nil == os.getenv("IOSVERSION") then + print("You must set IOSVERSION enviroment variable.") + print("\tExample: 5.0") + err = true + end + + if err then + os.exit(1) + end + + local sysroot_path = os.getenv("SYSROOTPATH") + local framework_path = sysroot_path .. "/System/Library/Frameworks" + local framework_libs_path = framework_path .. "/usr/lib" + local sysroot_ver = " -miphoneos-version-min=" .. os.getenv("IOSVERSION") .. " -isysroot " .. sysroot_path + + buildoptions { sysroot_ver .. " -I" .. sysroot_path .. "/usr/include" } + linkoptions { sysroot_ver } + libdirs { framework_libs_path } + linkoptions { " -F" .. framework_path .. " -L" .. framework_libs_path .. " -isysroot " .. sysroot_path } + includedirs { "src/thirdparty/SDL2/include" } + end + + if _OPTIONS.platform == "ios-cross-arm7" or _OPTIONS.platform == "ios-cross-x86" then + includedirs { "src/thirdparty/SDL2/include" } + end +end + +function backend_is( name, libname ) + if not _OPTIONS["with-backend"] then + _OPTIONS["with-backend"] = "SDL2" + end + + if next(backends) == nil then + backends = string.explode(_OPTIONS["with-backend"],",") + end + + local backend_sel = table.contains( backends, name ) + + local ret_val = os_findlib( libname ) and backend_sel + + if os.istarget("mingw32") or os.istarget("emscripten") then + ret_val = backend_sel + end + + if ret_val then + backend_selected = true + end + + return ret_val +end + +function select_backend() + if backend_is("SDL2", "SDL2") then + print("Selected SDL2") + add_sdl2() + end + + if backend_is("SFML", "sfml-window") then + print("Selected SFML") + add_sfml() + end + + -- If the selected backend is not present, try to find one present + if not backend_selected then + if os_findlib("SDL2", "SDL2") then + add_sdl2() + elseif os_findlib("SFML", "sfml-window") then + add_sfml() + else + print("ERROR: Couldnt find any backend. Forced SDL2.") + add_sdl2( true ) + end + end +end + +function check_ssl_support() + if _OPTIONS["with-ssl"] then + print("Enabled SSL support") + + if _OPTIONS["with-openssl"] then + if os.istarget("windows") then + table.insert( link_list, get_backend_link_name( "libssl" ) ) + table.insert( link_list, get_backend_link_name( "libcrypto" ) ) + else + table.insert( link_list, get_backend_link_name( "ssl" ) ) + table.insert( link_list, get_backend_link_name( "crypto" ) ) + end + + files { "src/eepp/network/ssl/backend/openssl/*.cpp" } + + defines { "EE_OPENSSL" } + else + files { "src/eepp/network/ssl/backend/mbedtls/*.cpp" } + + defines { "EE_MBEDTLS" } + end + + defines { "EE_SSL_SUPPORT" } + end +end + +function build_eepp( build_name ) + includedirs { "include", "src", "src/thirdparty", "include/eepp/thirdparty", "src/thirdparty/freetype2/include", "src/thirdparty/zlib", "src/thirdparty/libogg/include", "src/thirdparty/libvorbis/include", "src/thirdparty/mbedtls/include" } + + set_ios_config() + set_xcode_config() + + add_static_links() + + if is_vs() then + includedirs { "src/thirdparty/libzip/vs" } + end + + if not is_vs() then + buildoptions{ "-std=c++14" } + end + + if os.istarget("windows") then + files { "src/eepp/system/platform/win/*.cpp" } + files { "src/eepp/network/platform/win/*.cpp" } + else + files { "src/eepp/system/platform/posix/*.cpp" } + files { "src/eepp/network/platform/unix/*.cpp" } + end + + files { "src/eepp/core/*.cpp", + "src/eepp/math/*.cpp", + "src/eepp/system/*.cpp", + "src/eepp/audio/*.cpp", + "src/eepp/graphics/*.cpp", + "src/eepp/graphics/renderer/*.cpp", + "src/eepp/window/*.cpp", + "src/eepp/window/platform/null/*.cpp", + "src/eepp/network/*.cpp", + "src/eepp/network/ssl/*.cpp", + "src/eepp/network/http/*.cpp", + "src/eepp/scene/*.cpp", + "src/eepp/scene/actions/*.cpp", + "src/eepp/ui/*.cpp", + "src/eepp/ui/actions/*.cpp", + "src/eepp/ui/css/*.cpp", + "src/eepp/ui/tools/*.cpp", + "src/eepp/physics/*.cpp", + "src/eepp/physics/constraints/*.cpp", + "src/eepp/maps/*.cpp", + "src/eepp/maps/mapeditor/*.cpp" + } + + check_ssl_support() + + select_backend() + + if not _OPTIONS["with-static-freetype"] and os_findlib("freetype") then + table.insert( link_list, get_backend_link_name( "freetype" ) ) + end + + multiple_insert( link_list, os_links ) + + links { link_list } + + build_link_configuration( build_name ) + + configuration "windows" + files { "src/eepp/window/platform/win/*.cpp" } + add_cross_config_links() + + configuration "linux" + files { "src/eepp/window/platform/x11/*.cpp" } + + configuration "macosx" + files { "src/eepp/window/platform/osx/*.cpp" } + + configuration "emscripten" + if _OPTIONS["force-gles1"] then + defines{ "EE_GLES1_DEFAULT" } + end +end + +function set_targetdir( dir ) + if os.istarget("ios") then + targetdir(dir .. get_ios_arch() .. "/" ) + else + targetdir(dir) + end +end + +workspace "eepp" + + targetdir("./bin/") + configurations { "debug", "release" } + rtti "On" + + if os.istarget("android") then + ndkabi "arm64-v8a" + ndkplatform "android-28" + ndkstl "c++_static" + end + + if os.istarget("ios") then + location("./make/" .. _OPTIONS.platform .. "/" ) + objdir("obj/" .. os.target() .. "/" .. get_ios_arch() .. "/" ) + else + location("./make/" .. os.target() .. "/") + objdir("obj/" .. os.target() .. "/") + end + + generate_os_links() + parse_args() + + project "SOIL2-static" + kind "StaticLib" + + if is_vs() then + language "C++" + buildoptions { "/TP" } + else + language "C" + end + + set_targetdir("libs/" .. os.target() .. "/thirdparty/") + files { "src/thirdparty/SOIL2/src/SOIL2/*.c" } + includedirs { "src/thirdparty/SOIL2" } + build_base_configuration( "SOIL2" ) + + if not os.istarget("haiku") and not os.istarget("ios") and not os.istarget("android") and not os.istarget("emscripten") then + project "glew-static" + kind "StaticLib" + language "C" + defines { "GLEW_NO_GLU", "GLEW_STATIC" } + set_targetdir("libs/" .. os.target() .. "/thirdparty/") + files { "src/thirdparty/glew/*.c" } + includedirs { "include/thirdparty/glew" } + build_base_configuration( "glew" ) + end + + if _OPTIONS["with-ssl"] and not _OPTIONS["with-openssl"] then + project "mbedtls-static" + kind "StaticLib" + language "C" + set_targetdir("libs/" .. os.target() .. "/thirdparty/") + includedirs { "src/thirdparty/mbedtls/include/" } + files { "src/thirdparty/mbedtls/library/*.c" } + build_base_cpp_configuration( "mbedtls" ) + end + + project "vorbis-static" + kind "StaticLib" + language "C" + set_targetdir("libs/" .. os.target() .. "/thirdparty/") + includedirs { "src/thirdparty/libvorbis/lib/", "src/thirdparty/libogg/include", "src/thirdparty/libvorbis/include" } + files { "src/thirdparty/libogg/**.c", "src/thirdparty/libvorbis/**.c" } + build_base_cpp_configuration( "vorbis" ) + + project "pugixml-static" + kind "StaticLib" + language "C++" + set_targetdir("libs/" .. os.target() .. "/thirdparty/") + files { "src/thirdparty/pugixml/*.cpp" } + build_base_cpp_configuration( "pugixml" ) + + project "zlib-static" + kind "StaticLib" + language "C" + set_targetdir("libs/" .. os.target() .. "/thirdparty/") + files { "src/thirdparty/zlib/*.c" } + build_base_configuration( "zlib" ) + + project "libzip-static" + kind "StaticLib" + language "C" + set_targetdir("libs/" .. os.target() .. "/thirdparty/") + files { "src/thirdparty/libzip/*.c" } + includedirs { "src/thirdparty/zlib" } + build_base_configuration( "libzip" ) + + project "freetype-static" + kind "StaticLib" + language "C" + set_targetdir("libs/" .. os.target() .. "/thirdparty/") + defines { "FT2_BUILD_LIBRARY" } + files { "src/thirdparty/freetype2/src/**.c" } + includedirs { "src/thirdparty/freetype2/include" } + build_base_configuration( "freetype" ) + + project "chipmunk-static" + kind "StaticLib" + + if is_vs() then + language "C++" + buildoptions { "/TP" } + else + language "C" + end + + set_targetdir("libs/" .. os.target() .. "/thirdparty/") + files { "src/thirdparty/chipmunk/*.c", "src/thirdparty/chipmunk/constraints/*.c" } + includedirs { "include/eepp/thirdparty/chipmunk" } + build_base_configuration( "chipmunk" ) + + project "jpeg-compressor-static" + kind "StaticLib" + language "C++" + set_targetdir("libs/" .. os.target() .. "/thirdparty/") + files { "src/thirdparty/jpeg-compressor/*.cpp" } + build_base_cpp_configuration( "jpeg-compressor" ) + + project "imageresampler-static" + kind "StaticLib" + language "C++" + set_targetdir("libs/" .. os.target() .. "/thirdparty/") + files { "src/thirdparty/imageresampler/*.cpp" } + build_base_cpp_configuration( "imageresampler" ) + + project "efsw-static" + kind "StaticLib" + language "C++" + set_targetdir("libs/" .. os.target() .. "/thirdparty/") + includedirs { "src/thirdparty/efsw/include", "src/thirdparty/efsw/src" } + + if os.istarget("windows") then + osfiles = "src/thirdparty/efsw/src/efsw/platform/win/*.cpp" + else + osfiles = "src/thirdparty/efsw/src/efsw/platform/posix/*.cpp" + end + + files { "src/thirdparty/efsw/src/efsw/*.cpp", osfiles } + + if os.istarget("windows") then + excludes { "src/thirdparty/efsw/src/efsw/WatcherKqueue.cpp", "src/thirdparty/efsw/src/efsw/WatcherFSEvents.cpp", "src/thirdparty/efsw/src/efsw/WatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherKqueue.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherFSEvents.cpp" } + elseif os.istarget("linux") then + excludes { "src/thirdparty/efsw/src/efsw/WatcherKqueue.cpp", "src/thirdparty/efsw/src/efsw/WatcherFSEvents.cpp", "src/thirdparty/efsw/src/efsw/WatcherWin32.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherKqueue.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherWin32.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherFSEvents.cpp" } + elseif os.istarget("macosx") then + excludes { "src/thirdparty/efsw/src/efsw/WatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/WatcherWin32.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherWin32.cpp" } + elseif os.istarget("freebsd") then + excludes { "src/thirdparty/efsw/src/efsw/WatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/WatcherWin32.cpp", "src/thirdparty/efsw/src/efsw/WatcherFSEvents.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherInotify.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherWin32.cpp", "src/thirdparty/efsw/src/efsw/FileWatcherFSEvents.cpp" } + end + + build_base_cpp_configuration( "efsw" ) + + project "eepp-main" + kind "StaticLib" + language "C++" + set_targetdir("libs/" .. os.target() .. "/") + files { "src/eepp/main/eepp_main.cpp" } + configuration "debug" + defines { "DEBUG" } + symbols "On" + configuration "release" + optimize "Speed" + + project "eepp-static" + kind "StaticLib" + language "C++" + set_targetdir("libs/" .. os.target() .. "/") + build_eepp( "eepp-static" ) + + project "eepp-shared" + kind "SharedLib" + language "C++" + set_targetdir("libs/" .. os.target() .. "/") + build_eepp( "eepp" ) + + -- Examples + project "eepp-test" + set_kind() + language "C++" + files { "src/test/*.cpp" } + build_link_configuration( "eetest", true ) + + project "eepp-es" + set_kind() + language "C++" + files { "src/examples/external_shader/*.cpp" } + build_link_configuration( "eees", true ) + + project "eepp-ew" + set_kind() + language "C++" + files { "src/examples/empty_window/*.cpp" } + build_link_configuration( "eeew", true ) + + project "eepp-sound" + kind "ConsoleApp" + language "C++" + files { "src/examples/sound/*.cpp" } + build_link_configuration( "eesound", true ) + + project "eepp-sprites" + set_kind() + language "C++" + files { "src/examples/sprites/*.cpp" } + build_link_configuration( "eesprites", true ) + + project "eepp-fonts" + set_kind() + language "C++" + files { "src/examples/fonts/*.cpp" } + build_link_configuration( "eefonts", true ) + + project "eepp-vbo-fbo-batch" + set_kind() + language "C++" + files { "src/examples/vbo_fbo_batch/*.cpp" } + build_link_configuration( "eevbo-fbo-batch", true ) + + project "eepp-physics" + set_kind() + language "C++" + files { "src/examples/physics/*.cpp" } + build_link_configuration( "eephysics", true ) + + project "eepp-http-request" + kind "ConsoleApp" + language "C++" + files { "src/examples/http_request/*.cpp" } + includedirs { "src/thirdparty" } + build_link_configuration( "eehttp-request", true ) + + -- Tools + project "eepp-textureatlaseditor" + set_kind() + language "C++" + files { "src/tools/textureatlaseditor/*.cpp" } + build_link_configuration( "eepp-TextureAtlasEditor", true ) + + project "eepp-mapeditor" + set_kind() + language "C++" + files { "src/tools/mapeditor/*.cpp" } + build_link_configuration( "eepp-MapEditor", true ) + + project "eepp-uieditor" + set_kind() + language "C++" + includedirs { "src/thirdparty/efsw/include", "src/thirdparty" } + + if not os.istarget("windows") and not os.istarget("haiku") then + links { "pthread" } + end + + links { "efsw-static", "pugixml-static" } + files { "src/tools/uieditor/*.cpp" } + build_link_configuration( "eepp-UIEditor", true ) + +if os.isfile("external_projects.lua") then + dofile("external_projects.lua") +end