From ebbbb72ab7107133c68ea71edbde325d1a59b3ba Mon Sep 17 00:00:00 2001 From: Joris Dauphin Date: Sat, 29 May 2021 20:19:18 +0200 Subject: [PATCH 01/19] Enable pchheader for Codelite. (#1627) * Enable pchheader for Codelite. * Factorize code. --- modules/codelite/codelite_project.lua | 10 +++-- .../codelite/tests/test_codelite_config.lua | 10 +++++ modules/gmake/gmake_cpp.lua | 39 +--------------- modules/gmake2/gmake2_cpp.lua | 38 +--------------- src/tools/gcc.lua | 44 +++++++++++++++++-- 5 files changed, 62 insertions(+), 79 deletions(-) diff --git a/modules/codelite/codelite_project.lua b/modules/codelite/codelite_project.lua index 7c5a2283..d427fe41 100755 --- a/modules/codelite/codelite_project.lua +++ b/modules/codelite/codelite_project.lua @@ -188,7 +188,6 @@ } end - function m.compiler(cfg) if configuration_iscustombuild(cfg) or configuration_isfilelist(cfg) then _p(3, '') @@ -201,9 +200,14 @@ local cxxflags = table.concat(table.join(sysincludedirs, toolset.getcxxflags(cfg), forceincludes, cfg.buildoptions), ";") local cflags = table.concat(table.join(sysincludedirs, toolset.getcflags(cfg), forceincludes, cfg.buildoptions), ";") local asmflags = "" - local pch = "" + local pch = p.tools.gcc.getpch(cfg) + local usepch = "yes" + if pch == nil then + pch = ""; + usepch = "no" + end - _x(3, '', cxxflags, cflags, asmflags, pch) + _x(3, '', cxxflags, cflags, asmflags, pch, usepch) for _, includedir in ipairs(cfg.includedirs) do _x(4, '', project.getrelative(cfg.project, includedir)) diff --git a/modules/codelite/tests/test_codelite_config.lua b/modules/codelite/tests/test_codelite_config.lua index fc839da0..e98c8b88 100644 --- a/modules/codelite/tests/test_codelite_config.lua +++ b/modules/codelite/tests/test_codelite_config.lua @@ -93,6 +93,16 @@ ]] end + function suite.OnProjectCfg_Pch() + pchheader "pch.h" + prepare() + codelite.project.compiler(cfg) + test.capture [[ + + + ]] + end + function suite.OnProjectCfg_Linker() prepare() codelite.project.linker(cfg) diff --git a/modules/gmake/gmake_cpp.lua b/modules/gmake/gmake_cpp.lua index 3814b695..e1e561ef 100644 --- a/modules/gmake/gmake_cpp.lua +++ b/modules/gmake/gmake_cpp.lua @@ -567,51 +567,16 @@ end function make.pch(cfg, toolset) + local pch = p.tools.gcc.getpch(cfg) -- If there is no header, or if PCH has been disabled, I can early out - if not cfg.pchheader or cfg.flags.NoPCH then + if pch == nil then return end - -- Visual Studio requires the PCH header to be specified in the same way - -- it appears in the #include statements used in the source code; the PCH - -- source actual handles the compilation of the header. GCC compiles the - -- header file directly, and needs the file's actual file system path in - -- order to locate it. - - -- To maximize the compatibility between the two approaches, see if I can - -- locate the specified PCH header on one of the include file search paths - -- and, if so, adjust the path automatically so the user doesn't have - -- add a conditional configuration to the project script. - - local pch = cfg.pchheader - local found = false - - -- test locally in the project folder first (this is the most likely location) - local testname = path.join(cfg.project.basedir, pch) - if os.isfile(testname) then - pch = project.getrelative(cfg.project, testname) - found = true - else - -- else scan in all include dirs. - for _, incdir in ipairs(cfg.includedirs) do - testname = path.join(incdir, pch) - if os.isfile(testname) then - pch = project.getrelative(cfg.project, testname) - found = true - break - end - end - end - - if not found then - pch = project.getrelative(cfg.project, path.getabsolute(pch)) - end - _x(' PCH = %s', pch) _p(' GCH = $(OBJDIR)/$(notdir $(PCH)).gch') end - function make.pchRules(prj) _p('ifneq (,$(PCH))') _p('$(OBJECTS): $(GCH) $(PCH) | $(OBJDIR)') diff --git a/modules/gmake2/gmake2_cpp.lua b/modules/gmake2/gmake2_cpp.lua index 11c202dd..bc45cbd2 100644 --- a/modules/gmake2/gmake2_cpp.lua +++ b/modules/gmake2/gmake2_cpp.lua @@ -368,46 +368,12 @@ function cpp.pch(cfg, toolset) + local pch = p.tools.gcc.getpch(cfg) -- If there is no header, or if PCH has been disabled, I can early out - if not cfg.pchheader or cfg.flags.NoPCH then + if pch == nil then return end - -- Visual Studio requires the PCH header to be specified in the same way - -- it appears in the #include statements used in the source code; the PCH - -- source actual handles the compilation of the header. GCC compiles the - -- header file directly, and needs the file's actual file system path in - -- order to locate it. - - -- To maximize the compatibility between the two approaches, see if I can - -- locate the specified PCH header on one of the include file search paths - -- and, if so, adjust the path automatically so the user doesn't have - -- add a conditional configuration to the project script. - - local pch = cfg.pchheader - local found = false - - -- test locally in the project folder first (this is the most likely location) - local testname = path.join(cfg.project.basedir, pch) - if os.isfile(testname) then - pch = project.getrelative(cfg.project, testname) - found = true - else - -- else scan in all include dirs. - for _, incdir in ipairs(cfg.includedirs) do - testname = path.join(incdir, pch) - if os.isfile(testname) then - pch = project.getrelative(cfg.project, testname) - found = true - break - end - end - end - - if not found then - pch = project.getrelative(cfg.project, path.getabsolute(pch)) - end - p.outln('PCH = ' .. pch) p.outln('PCH_PLACEHOLDER = $(OBJDIR)/$(notdir $(PCH))') p.outln('GCH = $(PCH_PLACEHOLDER).gch') diff --git a/src/tools/gcc.lua b/src/tools/gcc.lua index c30233a1..d7942747 100644 --- a/src/tools/gcc.lua +++ b/src/tools/gcc.lua @@ -297,9 +297,47 @@ return result end + -- relative pch file path if any + function gcc.getpch(cfg) + -- If there is no header, or if PCH has been disabled, I can early out + if not cfg.pchheader or cfg.flags.NoPCH then + return nil + end + + -- Visual Studio requires the PCH header to be specified in the same way + -- it appears in the #include statements used in the source code; the PCH + -- source actual handles the compilation of the header. GCC compiles the + -- header file directly, and needs the file's actual file system path in + -- order to locate it. + + -- To maximize the compatibility between the two approaches, see if I can + -- locate the specified PCH header on one of the include file search paths + -- and, if so, adjust the path automatically so the user doesn't have + -- add a conditional configuration to the project script. + + local pch = cfg.pchheader + local found = false + + -- test locally in the project folder first (this is the most likely location) + local testname = path.join(cfg.project.basedir, pch) + if os.isfile(testname) then + return project.getrelative(cfg.project, testname) + else + -- else scan in all include dirs. + for _, incdir in ipairs(cfg.includedirs) do + testname = path.join(incdir, pch) + if os.isfile(testname) then + return project.getrelative(cfg.project, testname) + end + end + end + + return project.getrelative(cfg.project, path.getabsolute(pch)) + end + -- -- Return a list of decorated rpaths --- +-- -- @param cfg -- The configuration to query. -- @param dirs @@ -328,10 +366,10 @@ rpath = "$$ORIGIN" .. rpath end - if mode == "linker" then + if mode == "linker" then rpath = "-Wl,-rpath,'" .. rpath .. "'" end - + table.insert(result, rpath) end From ed25044cd29f18af7e121e06855f569c4bacc092 Mon Sep 17 00:00:00 2001 From: abhiss <36640936+abhiss@users.noreply.github.com> Date: Tue, 1 Jun 2021 00:44:48 -0700 Subject: [PATCH 02/19] fix typo --- website/docs/Using-Premake.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/Using-Premake.md b/website/docs/Using-Premake.md index 82ac459a..39a19ede 100644 --- a/website/docs/Using-Premake.md +++ b/website/docs/Using-Premake.md @@ -47,7 +47,7 @@ premake5 --help ## Using the Generated Projects -For toolsets like Visual Studio and Xcode, you can simply load the generated workspace or workspace into your IDE and build as you normally would. +For toolsets like Visual Studio and Xcode, you can simply load the generated workspace or workspaces into your IDE and build as you normally would. If you have generated makefiles, running `make` with no options will build all targets using the default configuration, as set by the project author. To see the list of available configurations, type: From 504c7640164cae351522234049228446d3d6c4e4 Mon Sep 17 00:00:00 2001 From: KyrietS Date: Tue, 1 Jun 2021 23:24:42 +0200 Subject: [PATCH 03/19] Fix broken links in docs --- website/README.md | 16 +- website/docs/Adding-New-Action.md | 4 +- website/docs/Adding-Source-Files.md | 4 +- website/docs/Adding-Unit-Tests.md | 4 +- website/docs/Build-Settings.md | 20 +- website/docs/Building-Premake.md | 4 +- website/docs/Code-Overview.md | 12 +- website/docs/Coding-Conventions.md | 2 +- website/docs/Command-Line-Arguments.md | 8 +- website/docs/Configurations-and-Platforms.md | 10 +- website/docs/Custom-Build-Commands.md | 8 +- website/docs/Custom-Rules.md | 8 +- website/docs/Debugging-Scripts.md | 2 +- website/docs/Developing-Modules.md | 8 +- website/docs/Extending-Premake.md | 8 +- website/docs/Filters.md | 4 +- website/docs/How-to-Help.md | 2 +- website/docs/Introducing-Modules.md | 8 +- website/docs/Linking.md | 6 +- website/docs/Locating-Scripts.md | 2 +- website/docs/Lua-Library-Additions.md | 205 ++++++----- website/docs/Makefile-Projects.md | 12 +- website/docs/Migrating-From-4.x.md | 22 +- website/docs/Overrides-and-Call-Arrays.md | 12 +- website/docs/Project-API.md | 344 +++++++++---------- website/docs/Removing-Values.md | 2 +- website/docs/Scopes-and-Inheritance.md | 2 +- website/docs/Starting-Your-New-Action.md | 10 +- website/docs/System-Scripts.md | 4 +- website/docs/Tokens.md | 16 +- website/docs/Topics.md | 18 +- website/docs/Using-Modules.md | 12 +- website/docs/Using-Premake.md | 8 +- website/docs/Whats-New-in-5.0.md | 238 ++++++------- website/docs/Workspaces-and-Projects.md | 18 +- website/docs/Your-First-Script.md | 2 +- website/docs/os.translateCommands.md | 2 +- 37 files changed, 540 insertions(+), 527 deletions(-) diff --git a/website/README.md b/website/README.md index 37330d86..5ddfc2b3 100644 --- a/website/README.md +++ b/website/README.md @@ -10,7 +10,21 @@ Editing our documentation website is very simple. You don't have to build a whol 1. Add a new Markdown file into the `docs/` folder. Follow naming conventions there. 2. Add your Markdown file's name into the `sidebars.js`. Make sure you've kept alphabetical order among category items. -*Use other files as references.* +### Adding a reference to another documentation page + +Always reference another documentation page like this: +```markdown +[some text](Case-Sensitive-Filename.md) +``` + +and **never** like this: +```markdown +[some text](some-markdown-file) +[some text](/docs/some-markdown-file) +[some text](https://premake.github.io/docs/some-markdown-file) +``` + +*Use existing files in documentation as examples.* ## Installation diff --git a/website/docs/Adding-New-Action.md b/website/docs/Adding-New-Action.md index 20d82d3d..156f1800 100644 --- a/website/docs/Adding-New-Action.md +++ b/website/docs/Adding-New-Action.md @@ -8,7 +8,7 @@ Premake provides the ability to create your own actions. These can be simple one This tutorial walks through the process of creating a new action that outputs solution and project information as Lua tables, which you can then use Premake to read and manipulate if you wish. -* [Starting Your New Action](starting-your-new-action) -* [Generating Project Files](generating-project-files) +* [Starting Your New Action](Starting-Your-New-Action.md) +* [Generating Project Files](Generating-Project-Files.md) * Working with Configurations * (More to come!) diff --git a/website/docs/Adding-Source-Files.md b/website/docs/Adding-Source-Files.md index 1aba0545..20a857ae 100644 --- a/website/docs/Adding-Source-Files.md +++ b/website/docs/Adding-Source-Files.md @@ -2,7 +2,7 @@ title: Adding Source Files --- -You add files—source code, resources, and so on—to your project using the [files](files) function. +You add files—source code, resources, and so on—to your project using the [files](files.md) function. ```lua files { @@ -24,7 +24,7 @@ Paths should always use the forward slash `/` as a separator; Premake will trans ## Excluding Files -Sometimes you want most, but not all, of the files in a directory. In that case, use the [removefiles()](removing-values) function to mask out those few exceptions. +Sometimes you want most, but not all, of the files in a directory. In that case, use the [removefiles()](Removing-Values.md) function to mask out those few exceptions. ```lua files { "*.c" } diff --git a/website/docs/Adding-Unit-Tests.md b/website/docs/Adding-Unit-Tests.md index 011b8af8..a8c32a66 100644 --- a/website/docs/Adding-Unit-Tests.md +++ b/website/docs/Adding-Unit-Tests.md @@ -7,7 +7,7 @@ Premake includes an automated testing system that you can use the verify the beh ## Add your first test -Within our [Lucky module](introducing-modules) folder, create a new folder named `tests`. +Within our [Lucky module](Introducing-Modules.md) folder, create a new folder named `tests`. Within that folder, create a new file named `tests/test_lucky_numbers.lua` with a simple failing test: @@ -43,7 +43,7 @@ lucky/ Premake's automated testing module is considered an advanced, developer-only feature which is not enabled by default. To enable it, you simply need to add the line `test = require("self-test")` somewhere it will be executed before your tests run. -The best place to put it is in your [system script](system-scripts), which will make the testing action available to all of your projects. But if that isn't feasible for you or your users, you can also place it in your project or testing script. +The best place to put it is in your [system script](System-Scripts.md), which will make the testing action available to all of your projects. But if that isn't feasible for you or your users, you can also place it in your project or testing script. Premake's own code makes use of the latter approach: its `premake5.lua` script defines a custom action named "test", which in turn enables the built-in testing module: diff --git a/website/docs/Build-Settings.md b/website/docs/Build-Settings.md index 1fede43b..8a5e0a96 100644 --- a/website/docs/Build-Settings.md +++ b/website/docs/Build-Settings.md @@ -2,19 +2,19 @@ title: Build Settings --- -Premake provides an ever-growing list of build settings that you can tweak; the following table lists some of the most common configuration tasks with a link to the corresponding functions. For a comprehensive list of available settings and functions, see the [Project API](project-api) and [Lua Library Additions](lua-library-additions). +Premake provides an ever-growing list of build settings that you can tweak; the following table lists some of the most common configuration tasks with a link to the corresponding functions. For a comprehensive list of available settings and functions, see the [Project API](Project-API.md) and [Lua Library Additions](Lua-Library-Additions.md). If you think something should be possible and you can't figure out how to do it, see [Support](/community/support). | | | |-----------------------------------------------|----------------------| -| Specify the binary type (executable, library) | [kind](kind) | -| Specify source code files | [files](files), [removefiles](files) | -| Define compiler or preprocessor symbols | [defines](defines) | -| Locate include files | [includedirs](includedirs) | -| Set up precompiled headers | [pchheader](pchheader), [pchsource](pchsource) | -| Link libraries, frameworks, or other projects | [links](links), [libdirs](libdirs) | +| Specify the binary type (executable, library) | [kind](kind.md) | +| Specify source code files | [files](files.md), [removefiles](files.md) | +| Define compiler or preprocessor symbols | [defines](defines.md) | +| Locate include files | [includedirs](includedirs.md) | +| Set up precompiled headers | [pchheader](pchheader.md), [pchsource](pchsource.md) | +| Link libraries, frameworks, or other projects | [links](links.md), [libdirs](libdirs.md) | | Enable debugging information | symbols(symbols) | -| Optimize for size or speed | [optimize](optimize) | -| Add arbitrary build flags | [buildoptions](buildoptions), [linkoptions](linkoptions) | -| Set the name or location of compiled targets | [targetname](targetname), [targetdir](targetdir) | +| Optimize for size or speed | [optimize](optimize.md) | +| Add arbitrary build flags | [buildoptions](buildoptions.md), [linkoptions](linkoptions.md) | +| Set the name or location of compiled targets | [targetname](targetname.md), [targetdir](targetdir.md) | diff --git a/website/docs/Building-Premake.md b/website/docs/Building-Premake.md index 90e8f4f1..ea0155d3 100644 --- a/website/docs/Building-Premake.md +++ b/website/docs/Building-Premake.md @@ -7,7 +7,7 @@ If you downloaded a prebuilt binary package you can skip this page, which discus ## Using a Source Code Package ## -If you have one of the [official source code packages](http://premake.github.io/download.html), you'll find that project files for a variety of toolsets have already been generated for you in the `build/` folder. Find the right set for your platform and toolset and build as you normally would (i.e. run `make`). The resulting binaries will be placed in the top-level `bin/` folder. +If you have one of the [official source code packages](/download), you'll find that project files for a variety of toolsets have already been generated for you in the `build/` folder. Find the right set for your platform and toolset and build as you normally would (i.e. run `make`). The resulting binaries will be placed in the top-level `bin/` folder. Skip ahead to the next section to learn more about using the source version of Premake. @@ -31,7 +31,7 @@ call "%VS140COMNTOOLS%\..\..\VC\vcvarsall.bat" # Sets up the necessary environme nmake -f Bootstrap.mak MSDEV=vs2015 windows # For Windows with Visual Studio 2015. ``` -On other platforms, if the bootstrap fails to build, you will need to have a working Premake executable on your system. The easiest way to get one is by [downloading prebuilt binary package](http://premake.github.io/download.html). If a binary is not available for your system, or if you would prefer to build one yourself, grab the latest source code package from that same site and follow the steps in **Using a Source Code Package**, above. +On other platforms, if the bootstrap fails to build, you will need to have a working Premake executable on your system. The easiest way to get one is by [downloading prebuilt binary package](/download). If a binary is not available for your system, or if you would prefer to build one yourself, grab the latest source code package from that same site and follow the steps in **Using a Source Code Package**, above. Once you have a working Premake available, you can generate the project files for your toolset by running a command like the following in the top-level Premake directory: diff --git a/website/docs/Code-Overview.md b/website/docs/Code-Overview.md index ae38ad56..9e1d7077 100644 --- a/website/docs/Code-Overview.md +++ b/website/docs/Code-Overview.md @@ -10,7 +10,7 @@ The Premake source code is organized into a few different folders: * `src/base` contains the core Lua scripts, the code that is used to read and process your project scripts, and supporting logic for the actions and exporters. -* `src/host` contains all of the C language code, logic that either can't easily be written in Lua because of the way it needs to interact with the underlying operating system, or because a Lua implementation would be too slow. We try to keep C code to a minimum and use Lua whenever we can, to enable [overrides and call arrays](overrides-and-call-arrays). +* `src/host` contains all of the C language code, logic that either can't easily be written in Lua because of the way it needs to interact with the underlying operating system, or because a Lua implementation would be too slow. We try to keep C code to a minimum and use Lua whenever we can, to enable [overrides and call arrays](Overrides-and-Call-Arrays.md). * `src/tools` contains the adapters for command line toolsets like GCC and Clang. We will probably be migrating these toward modules in the near-ish future as well. @@ -22,7 +22,7 @@ In addition to those general categories, there are a few special files of note: * `src/_premake_init.lua` sets up much of the initial configuration, including all of the project scripting functions, the default set of command line arguments, and the default project configurations. -* `src/_modules.lua` contains the list of built-in modules which are automatically loaded in startup. See [Embedding Modules](embedding-modules) for more information. +* `src/_modules.lua` contains the list of built-in modules which are automatically loaded in startup. See [Embedding Modules](Embedding-Modules.md) for more information. * `src/_manifest.lua` lists the Lua scripts that should be embedded into the Premake executable when making the release builds. There are separate manifests for Premake's core scripts and each embedded module. @@ -39,9 +39,9 @@ Execution starts at `main()` in `src/host/premake_main.c`, which calls into to ` * Once `src/premake_main.lua` has finished, `premake_execute()` calls `_premake_main()`, which located at the end of `src/_premake_main.lua`, and waits for it to return. -At this point, execution has moved into and remains in Lua; [extending Premake by overriding functions and call arrays](overrides-and-call-arrays) now becomes possible. +At this point, execution has moved into and remains in Lua; [extending Premake by overriding functions and call arrays](Overrides-and-Call-Arrays.md) now becomes possible. -`_premake_main()` uses a [call array](overrides-and-call-arrays) to control the high-level process of evaluating the user scripts and acting on the results. Notable functions in this list include: +`_premake_main()` uses a [call array](Overrides-and-Call-Arrays.md) to control the high-level process of evaluating the user scripts and acting on the results. Notable functions in this list include: * `prepareEnvironment()` sets more global variables and otherwise gets the script environment ready to use. @@ -49,7 +49,7 @@ At this point, execution has moved into and remains in Lua; [extending Premake b * `checkInteractive()` is responsible for launching the REPL prompt, if requested. -* `runSystemScript()` runs [the user's system script](system-scripts), and `runUserScript()` runs the project script found by `locateUserScript()`. +* `runSystemScript()` runs [the user's system script](System-Scripts.md), and `runUserScript()` runs the project script found by `locateUserScript()`. * `processCommandLine()` handles any command line options and sets the target action and arguments. This needs to happen after the project script has run, in case it defines new options or modifies the behavior of existing options—a common point of confusion. @@ -59,5 +59,5 @@ At this point, execution has moved into and remains in Lua; [extending Premake b * `callAction()` passes each workspace, project, rule, and other container to the target action, causing the appropriate result--like generating a Visual Studio project or GNU makefile--to occur. This container iteration is done in `action.call()` in `src/base/action.lua`. -Calling the action, via `callAction()`, is where the interesting part for most people begins. Control now transfers to one of exporters, causing the project files to be written. For more information on how *that* happens, see [Creating a New Action](adding-new-action). +Calling the action, via `callAction()`, is where the interesting part for most people begins. Control now transfers to one of exporters, causing the project files to be written. For more information on how *that* happens, see [Creating a New Action](Adding-New-Action.md). diff --git a/website/docs/Coding-Conventions.md b/website/docs/Coding-Conventions.md index b4d4dc98..f303803f 100644 --- a/website/docs/Coding-Conventions.md +++ b/website/docs/Coding-Conventions.md @@ -111,4 +111,4 @@ Similarly, instead of implementing the output of a particular section of the pro end ``` -For an example of how to implement a new feature using these conventions, see [Overrides and Call Arrays](Overrides-and-Call-Arrays). +For an example of how to implement a new feature using these conventions, see [Overrides and Call Arrays](Overrides-and-Call-Arrays.md). diff --git a/website/docs/Command-Line-Arguments.md b/website/docs/Command-Line-Arguments.md index 22759d7a..8048af49 100644 --- a/website/docs/Command-Line-Arguments.md +++ b/website/docs/Command-Line-Arguments.md @@ -2,7 +2,7 @@ title: Command Line Arguments --- -Premake provides the ability to define and handle new command-line arguments from within your project script using the [newaction](newaction) and [newoption](newoption) functions. +Premake provides the ability to define and handle new command-line arguments from within your project script using the [newaction](newaction.md) and [newoption](newoption.md) functions. ## Actions and Options @@ -12,7 +12,7 @@ An _action_ indicates what Premake should do on any given run. For instance, the An _option_ modifies the behavior of the action. For instance, the `dotnet` option is used to change which .NET compiler set is used in the generated files. Options can accept a value, such as `--dotnet=mono` or act as a flag, like `--with-opengl`. -From within your script, you can identify the current action with the [`_ACTION`](_ACTION) global variable, a string value. You can check for an option using the [`_OPTIONS`](_OPTIONS) table, which contains a list of key-value pairs. The key is the option identifier ("dotnet"), which references the command line value ("mono") or an empty string for valueless options. +From within your script, you can identify the current action with the [`_ACTION`](_ACTION.md) global variable, a string value. You can check for an option using the [`_OPTIONS`](_OPTIONS.md) table, which contains a list of key-value pairs. The key is the option identifier ("dotnet"), which references the command line value ("mono") or an empty string for valueless options. ```lua -- delete a file if the clean action is running @@ -26,7 +26,7 @@ targetdir ( _OPTIONS["outdir"] or "out" ) ## Creating New Options -New command-line options are created using the [`newoption`](newoption) function, passing a table which fully describes the option. This is best illustrated with some examples. +New command-line options are created using the [`newoption`](newoption.md) function, passing a table which fully describes the option. This is best illustrated with some examples. Here is an option intended to force the use of OpenGL in a 3D application. It serves as a simple flag, and does not take any value. @@ -125,4 +125,4 @@ newaction { The actual code to be executed when the action is fired should be placed in the `execute()` function. -That's the simple version, which is great for one-off operations that don't need to access to the specific project information. For a tutorial for writing a more complete action, see [Adding a New Action](adding-new-Action). +That's the simple version, which is great for one-off operations that don't need to access to the specific project information. For a tutorial for writing a more complete action, see [Adding a New Action](Adding-New-Action.md). diff --git a/website/docs/Configurations-and-Platforms.md b/website/docs/Configurations-and-Platforms.md index 584b3b67..d02fb40f 100644 --- a/website/docs/Configurations-and-Platforms.md +++ b/website/docs/Configurations-and-Platforms.md @@ -6,7 +6,7 @@ A *configuration* is a collection of settings to apply to a build, including fla ## Build Configurations -The [previous examples](your-first-script) showed how to specify build configurations. +The [previous examples](Your-First-Script.md) showed how to specify build configurations. ```lua workspace "MyWorkspace" @@ -27,7 +27,7 @@ workspace "MyWorkspace" configurations { "Froobniz", "Fozbat", "Cthulhu" } ``` -The meaning of the build configuration depends on the settings you apply to it, as shown in [the earlier examples](your-first-script). +The meaning of the build configuration depends on the settings you apply to it, as shown in [the earlier examples](Your-First-Script.md). ```lua workspace "HelloWorld" @@ -42,7 +42,7 @@ workspace "HelloWorld" optimize "On" ``` -The [Filters](filters) section will cover this in more detail. +The [Filters](Filters.md) section will cover this in more detail. ## Platforms @@ -56,7 +56,7 @@ platforms { "Win32", "Win64", "Xbox360" } Once set, your listed platforms will appear in the Platforms list of your IDE. So you can choose a "Debug Win32" build, or a "Release Xbox360" build, or any combination of the two lists. -Just like the build configurations, the platform names have no meaning on their own. You provide meaning by applying settings using the [`filter`](filter) function. +Just like the build configurations, the platform names have no meaning on their own. You provide meaning by applying settings using the [`filter`](filter.md) function. ```lua configurations { "Debug", "Release" } @@ -76,7 +76,7 @@ filter { "platforms:Xbox360" } Unlike build configurations, platforms are completely optional. If you don't need them, just don't call the platforms function at all and the toolset's default behavior will be used. -Platforms are just another form of build configuration. You can use all of the same settings, and the same scoping rules apply. You can use the [`system`](system) and [`architecture`()`](architecture) settings without platforms, and you can use otherwise non-platform settings in a platform configuration. If you've ever done build configurations like "Debug Static", "Debug DLL", "Release Static", and "Release DLL", platforms can really simplify things. +Platforms are just another form of build configuration. You can use all of the same settings, and the same scoping rules apply. You can use the [`system`](system.md) and [`architecture`()`](architecture.md) settings without platforms, and you can use otherwise non-platform settings in a platform configuration. If you've ever done build configurations like "Debug Static", "Debug DLL", "Release Static", and "Release DLL", platforms can really simplify things. ```lua configurations { "Debug", "Release" } diff --git a/website/docs/Custom-Build-Commands.md b/website/docs/Custom-Build-Commands.md index 504e3316..979d6d54 100644 --- a/website/docs/Custom-Build-Commands.md +++ b/website/docs/Custom-Build-Commands.md @@ -4,11 +4,11 @@ title: Custom Build Commads There are a few different ways that you can add custom commands to your Premake-generated builds: *pre- and post-build stages*, *custom build commands*, and *custom rules*. -You can also use [Makefile projects](makefile-projects) to execute external shell scripts or makefiles, rather than use the normal build system. +You can also use [Makefile projects](Makefile-Projects.md) to execute external shell scripts or makefiles, rather than use the normal build system. ## Pre- and Post-Build Stages -These are the simplest to setup and use: pass one or more command lines to the [`prebuildcommands`](prebuildcommands), [`prelinkcommands`](prelinkcommands), or [`postbuildcommands`](postbuildcommands) functions. You can use [Tokens](tokens) to create generic commands that will work across platforms and configurations. +These are the simplest to setup and use: pass one or more command lines to the [`prebuildcommands`](prebuildcommands.md), [`prelinkcommands`](prelinkcommands.md), or [`postbuildcommands`](postbuildcommands.md) functions. You can use [Tokens](Tokens.md) to create generic commands that will work across platforms and configurations. ```lua @@ -46,7 +46,7 @@ filter 'files:**.lua' The basic syntax follows Visual Studio's model, but it should be easy to see how it would translate to makefiles. -Build rules follow the same configuration scoping as the rest of the Premake API. You can apply rules to a specific platform or build configuration, to specific files or all files, or to any combination. And you can use [Tokens](tokens) to create generic commands that will work across platforms and configurations. +Build rules follow the same configuration scoping as the rest of the Premake API. You can apply rules to a specific platform or build configuration, to specific files or all files, or to any combination. And you can use [Tokens](Tokens.md) to create generic commands that will work across platforms and configurations. If the outputs include any object files, they will be automatically added to the link step. Ideally, any source code files included in the outputs would be fed back into the build, but that is not the case currently. @@ -68,4 +68,4 @@ Custom build commands currently have a few shortcomings. Help fixing these issue ## Custom Rules ## -The [custom rules feature](custom-rules) is similar to custom build commands. It allows you describe how to build a particular kind of file, but in a more generic way, and with variables that can be set in your project script. [Learn more about custom rules here](custom-rules). +The [custom rules feature](Custom-Rules.md) is similar to custom build commands. It allows you describe how to build a particular kind of file, but in a more generic way, and with variables that can be set in your project script. [Learn more about custom rules here](Custom-Rules.md). diff --git a/website/docs/Custom-Rules.md b/website/docs/Custom-Rules.md index b34c4a9c..871ef43b 100644 --- a/website/docs/Custom-Rules.md +++ b/website/docs/Custom-Rules.md @@ -2,7 +2,7 @@ title: Custom Rules --- -Rule file generation is a new and experimental feature of Premake 5.0, which currently only supports Visual Studio and the gmake2 action. It allows you describe how to build a particular kind of file, similar to [custom build commands](custom-build-commands), but in a more generic way, and with variables that can be set in your project script. +Rule file generation is a new and experimental feature of Premake 5.0, which currently only supports Visual Studio and the gmake2 action. It allows you describe how to build a particular kind of file, similar to [custom build commands](Custom-Build-Commands.md), but in a more generic way, and with variables that can be set in your project script. At generation time, Premake will output the appropriate rule files for the target action, just as it does for workspaces and projects. For Visual Studio 2010+, Premake will generate `RuleName.props`, `RuleName.targets`, and `RuleName.xml`. Currently, no other actions are supported. @@ -23,11 +23,11 @@ rule "MyCustomRule" buildoutputs '%(IntDir)/%(Filename).obj"' ``` -This rule will pass all files in project with the ".xyz" file extension through the specified build command. At export time, the files `MyCustomRule.props`, `MyCustomRule.targets`, and `MyCustomRule.xml` will be generated in the sample directory. Like workspaces and projects, this can be changed with [`location`](location) and [`filename`](filename). +This rule will pass all files in project with the ".xyz" file extension through the specified build command. At export time, the files `MyCustomRule.props`, `MyCustomRule.targets`, and `MyCustomRule.xml` will be generated in the sample directory. Like workspaces and projects, this can be changed with [`location`](location.md) and [`filename`](filename.md). There are still some shortcomings with the current implementation, notably that we don't have a generic set of variables to use in the commands. The example above uses Visual Studio's own variables such as `%(FullPath)` and `%(IntDir)`; obviously these won't work if rules are implemented for a different toolset. -To use the sample rule from above in a project, list the rule name in a [`rules`](rules) statement: +To use the sample rule from above in a project, list the rule name in a [`rules`](rules.md) statement: ```lua project "MyProject" @@ -37,7 +37,7 @@ project "MyProject" ## Rule Properties -The benefit of custom rules over [custom build commands](custom-build-commands) is the ability to specify *properties*, which can then be set like any other project or configuration value. Properties are defined with [`propertydefinition`](propertydefinition) functions, including default values which can be overridden by specific project configurations. +The benefit of custom rules over [custom build commands](Custom-Build-Commands.md) is the ability to specify *properties*, which can then be set like any other project or configuration value. Properties are defined with [`propertydefinition`](propertydefinition.md) functions, including default values which can be overridden by specific project configurations. ```lua rule "MyCustomRule" diff --git a/website/docs/Debugging-Scripts.md b/website/docs/Debugging-Scripts.md index 1b35de5e..61baf16d 100644 --- a/website/docs/Debugging-Scripts.md +++ b/website/docs/Debugging-Scripts.md @@ -7,7 +7,7 @@ title: Debugging Scripts Since Premake's update to 5.3, the only debugger that seems to be able to debug Premake is the free ZeroBrane Studio IDE. * [Download ZeroBrane Studio](https://studio.zerobrane.com/) and install it -* Compile a [debug build of Premake](building-premake). Your premake build should have built luasocket.dll, and there is a mobdebug.lua file in the root. Copy both alongside your premake executable to the location where you intend to run premake. +* Compile a [debug build of Premake](Building-Premake.md). Your premake build should have built luasocket.dll, and there is a mobdebug.lua file in the root. Copy both alongside your premake executable to the location where you intend to run premake. * Run ZeroBrane Studio and in the Project dropdown, select **Start Debugger Server**. * There's also a Project tab. Right-click the root folder and select **Project Directory > Choose...** to select the root of the premake repository. Open the lua file you want to debug (you can start with _premake_init.lua) and set a breakpoint. * Run premake with your desired command line and append `--scripts=path_to_premake --debugger` path_to_premake is the root of the repository where src lives. This isn't necessary if you run premake in the same directory as the src folder. If all goes well premake should think for a moment and the debugger should flash indicating that it has broken execution. diff --git a/website/docs/Developing-Modules.md b/website/docs/Developing-Modules.md index 3198c1b3..4baf7a71 100644 --- a/website/docs/Developing-Modules.md +++ b/website/docs/Developing-Modules.md @@ -4,7 +4,7 @@ title: Developing Modules Modules are the preferred way to package your customizations to reuse and share with others. -* [Introduction](introducing-modules) -* [Adding Unit Tests](adding-unit-tests) -* [Sharing Your Module](sharing-your-module) -* [Embedding Modules](embedding-modules) +* [Introduction](Introducing-Modules.md) +* [Adding Unit Tests](Adding-Unit-Tests.md) +* [Sharing Your Module](Sharing-Your-Module.md) +* [Embedding Modules](Embedding-Modules.md) diff --git a/website/docs/Extending-Premake.md b/website/docs/Extending-Premake.md index cfecd8c5..33c8d3e9 100644 --- a/website/docs/Extending-Premake.md +++ b/website/docs/Extending-Premake.md @@ -2,7 +2,7 @@ title: Extending Premake --- -Premake is written almost entirely in [Lua](http://www.lua.org/), the same dynamic language that you use while [writing your project scripts](your-first-script). Because Lua is dynamic, you can easily replace functions, add new values, and generally run amok in the code to make things work the way you like. +Premake is written almost entirely in [Lua](http://www.lua.org/), the same dynamic language that you use while [writing your project scripts](Your-First-Script.md). Because Lua is dynamic, you can easily replace functions, add new values, and generally run amok in the code to make things work the way you like. We've structured (or are in the process of structuring, with the intention of being done before the 5.0 release) the code with this feature in mind, adopting coding conventions that make it easy to hook and override or extend Premake's functionality. @@ -12,8 +12,8 @@ Before you start hacking away, you should be comfortable browsing through the [s If you haven't already, you should [grab a source code package, or clone the code repository on GitHub](/download) to use as a reference. -Then check out the [Code Overview](code-overview) to get a general sense of where things live, and [Coding Conventions](coding-conventions) for an overview on how the code is structured and why we did it that way. +Then check out the [Code Overview](Code-Overview.md) to get a general sense of where things live, and [Coding Conventions](Coding-Conventions.md) for an overview on how the code is structured and why we did it that way. -Have a look at [Overrides and Call Arrays](overrides-and-call-arrays) to learn more about Premake's extensible coding conventions, and how you can leverage them to easily change its current behavior. +Have a look at [Overrides and Call Arrays](Overrides-and-Call-Arrays.md) to learn more about Premake's extensible coding conventions, and how you can leverage them to easily change its current behavior. -When you're ready, check out the [documentation index](/docs) for more customization topics like adding support for new actions and toolsets, and [how to use modules](introducing-modules) to package your code up to share with others. +When you're ready, check out the [documentation index](/docs) for more customization topics like adding support for new actions and toolsets, and [how to use modules](Introducing-Modules.md) to package your code up to share with others. diff --git a/website/docs/Filters.md b/website/docs/Filters.md index cba77b5c..62c5722f 100644 --- a/website/docs/Filters.md +++ b/website/docs/Filters.md @@ -2,7 +2,7 @@ title: Filters --- -Premake's filter system allows you target build settings to the exact configurations in which you want them to appear. You can filter by specific build configurations or platforms, operating system, target actions, [and more](filter). +Premake's filter system allows you target build settings to the exact configurations in which you want them to appear. You can filter by specific build configurations or platforms, operating system, target actions, [and more](filter.md). Here is an example which sets a preprocessor symbol named "DEBUG" in a workspace's "Debug" build configuration, and "NDEBUG" in the Release configuration. @@ -51,4 +51,4 @@ The filter "configurations:Release" would be skipped, because the pattern "Relea The last filter "{}" does not define any filtering criteria, and so does not exclude anything. Any settings applied after this filter will appear in _all_ configurations within the workspace or project. -Filters may also be combined, modified with "or" or "not", and use pattern matches. For a more complete description and lots of examples, see [`filter`](filter). +Filters may also be combined, modified with "or" or "not", and use pattern matches. For a more complete description and lots of examples, see [`filter`](filter.md). diff --git a/website/docs/How-to-Help.md b/website/docs/How-to-Help.md index 4b2fea68..faa9fdda 100644 --- a/website/docs/How-to-Help.md +++ b/website/docs/How-to-Help.md @@ -2,7 +2,7 @@ title: How to Help --- -I've posted a [Development Roadmap](Development-Roadmap) to get us to the Premake 5.0 release. That is where help is most needed right now and there is plenty to do, from moving documentation (easy) to developing new modules (harder). +I've posted a [Development Roadmap](Development-Roadmap.md) to get us to the Premake 5.0 release. That is where help is most needed right now and there is plenty to do, from moving documentation (easy) to developing new modules (harder). Here are some other ways you can help: diff --git a/website/docs/Introducing-Modules.md b/website/docs/Introducing-Modules.md index 96fa69fa..f2c6b08b 100644 --- a/website/docs/Introducing-Modules.md +++ b/website/docs/Introducing-Modules.md @@ -6,9 +6,9 @@ A Premake module is simply a Lua script that follows a few extra conventions: * the name of the script file is the name of the module * the script should be placed in a folder of the same name -* the folder should be placed [somewhere Premake can find it](locating-scripts) +* the folder should be placed [somewhere Premake can find it](Locating-Scripts.md) -Let's start with a simple example. Create a new module by creating a folder named `lucky` and placing it [somewhere where Premake can find it](locating-scripts). Create a new file inside this folder named `lucky.lua`, with this simple starter module: +Let's start with a simple example. Create a new module by creating a folder named `lucky` and placing it [somewhere where Premake can find it](Locating-Scripts.md). Create a new file inside this folder named `lucky.lua`, with this simple starter module: ```lua -- lucky.lua @@ -52,7 +52,7 @@ Generating MyProject.vcxproj... Done. ``` -`require()` is [Lua's standard module loading function](http://www.lua.org/pil/8.1.html) (though the version in Premake has been extended to support [more search locations](locating-scripts)). The first time a module is required, Lua will load it and return the module's interface (the table we assigned to `m` in the example). If the module is later required again, the same table instance will be returned, without reloading the scripts. +`require()` is [Lua's standard module loading function](http://www.lua.org/pil/8.1.html) (though the version in Premake has been extended to support [more search locations](Locating-Scripts.md)). The first time a module is required, Lua will load it and return the module's interface (the table we assigned to `m` in the example). If the module is later required again, the same table instance will be returned, without reloading the scripts. Any local variables or functions you define in your module will be private, and only accessible from your module script. Variables or functions you assign to the module table will public, and accessible through the module interface returned from `require()`. @@ -87,5 +87,5 @@ local luckyEight = lucky.makeNumberLucky(8) That's all there to it! -Note that if you decide you want to [share your module](/community/modules) with other people, there are a [few other considerations to make](sharing-your-module). +Note that if you decide you want to [share your module](/community/modules) with other people, there are a [few other considerations to make](Sharing-Your-Module.md). diff --git a/website/docs/Linking.md b/website/docs/Linking.md index 22cc97d1..36b017ef 100644 --- a/website/docs/Linking.md +++ b/website/docs/Linking.md @@ -2,7 +2,7 @@ title: Linking --- -Linking to external libraries is done with the [`links`](links) function. +Linking to external libraries is done with the [`links`](links.md) function. ```lua links { "png", "zlib" } @@ -29,13 +29,13 @@ workspace "MyWorkspace" ### Finding Libraries ### -You can tell Premake where to search for libraries with the [`libdirs`](libdirs) function. +You can tell Premake where to search for libraries with the [`libdirs`](libdirs.md) function. ```lua libdirs { "libs", "../mylibs" } ``` -If you need to discover the location of a library, use the [`os.findlib`](os.findlib) function. +If you need to discover the location of a library, use the [`os.findlib`](os.findlib.md) function. ```lua libdirs { os.findlib("X11") } diff --git a/website/docs/Locating-Scripts.md b/website/docs/Locating-Scripts.md index 2a4f00c6..fb16cc8f 100644 --- a/website/docs/Locating-Scripts.md +++ b/website/docs/Locating-Scripts.md @@ -20,6 +20,6 @@ When Premake needs to load a script file, via a call to `dofile()` or `include() * In the directory containing the currently running Premake executable. -Note that these search paths also work for modules (e.g. `~/.premake/monodevelop`) and [system scripts](system-scripts). +Note that these search paths also work for modules (e.g. `~/.premake/monodevelop`) and [system scripts](System-Scripts.md). You are free to add or remove paths from `premake.path`, in either your project or system scripts. Any requests to load scripts after the change will use your modified path. diff --git a/website/docs/Lua-Library-Additions.md b/website/docs/Lua-Library-Additions.md index 851424f7..c2c981d8 100644 --- a/website/docs/Lua-Library-Additions.md +++ b/website/docs/Lua-Library-Additions.md @@ -1,136 +1,135 @@ ### Globals -* [dofileopt](dofileopt) -* [include](include) -* [includeexternal](includeexternal) -* [require](require) +* [dofileopt](dofileopt.md) +* [include](include.md) +* [includeexternal](includeexternal.md) +* [require](require.md) ### Debugging -* [debug.prompt](debug.prompt) +* [debug.prompt](debug.prompt.md) ### HTTP/S -* [http.download](http.download) -* [http.get](http.get) -* [http.post](http.post) +* [http.download](http.download.md) +* [http.get](http.get.md) +* [http.post](http.post.md) ### I/O -* [io.readfile](io.readfile) -* [io.writefile](io.writefile) +* [io.readfile](io.readfile.md) +* [io.writefile](io.writefile.md) ### JSON -* [json.decode](json.decode) -* [json.encode](json.encode) +* [json.decode](json.decode.md) +* [json.encode](json.encode.md) ### OS -* [os.chdir](os.chdir) -* [os.chmod](os.chmod) -* [os.comparefiles](os.comparefiles) -* [os.copyfile](os.copyfile) -* [os.executef](os.executef) -* [os.findheader](os.findheader) -* [os.findlib](os.findlib) -* [os.get](os.get) -* [os.getcwd](os.getcwd) -* [os.getpass](os.getpass) -* [os.getversion](os.getversion) -* [os.host](os.host) -* [os.is](os.is) -* [os.is64bit](os.is64bit) -* [os.isdir](os.isdir) -* [os.isfile](os.isfile) -* [os.islink](os.islink) -* [os.locate](os.locate) -* [os.matchdirs](os.matchdirs) -* [os.matchfiles](os.matchfiles) -* [os.mkdir](os.mkdir) -* [os.outputof](os.outputof) -* [os.pathsearch](os.pathsearch) -* [os.realpath](os.realpath) -* [os.remove](os.remove) -* [os.rmdir](os.rmdir) -* [os.stat](os.stat) -* [os.target](os.target) -* [os.touchfile](os.touchfile) -* [os.translateCommands](os.translateCommands) -* [os.uuid](os.uuid) -* [os.writefile_ifnotequal](os.writefile_ifnotequal) +* [os.chdir](os.chdir.md) +* [os.chmod](os.chmod.md) +* [os.comparefiles](os.comparefiles.md) +* [os.copyfile](os.copyfile.md) +* [os.executef](os.executef.md) +* [os.findheader](os.findheader.md) +* [os.findlib](os.findlib.md) +* [os.get](os.get.md) +* [os.getcwd](os.getcwd.md) +* [os.getpass](os.getpass.md) +* [os.getversion](os.getversion.md) +* [os.host](os.host.md) +* [os.is](os.is.md) +* [os.is64bit](os.is64bit.md) +* [os.isdir](os.isdir.md) +* [os.isfile](os.isfile.md) +* [os.islink](os.islink.md) +* [os.locate](os.locate.md) +* [os.matchdirs](os.matchdirs.md) +* [os.matchfiles](os.matchfiles.md) +* [os.mkdir](os.mkdir.md) +* [os.outputof](os.outputof.md) +* [os.pathsearch](os.pathsearch.md) +* [os.realpath](os.realpath.md) +* [os.remove](os.remove.md) +* [os.rmdir](os.rmdir.md) +* [os.stat](os.stat.md) +* [os.target](os.target.md) +* [os.touchfile](os.touchfile.md) +* [os.translateCommands](os.translateCommands.md) +* [os.uuid](os.uuid.md) +* [os.writefile_ifnotequal](os.writefile_ifnotequal.md) ### Path -* [path.appendextension](path.appendextension) -* [path.appendExtension](path.appendExtension) -* [path.getabsolute](path.getabsolute) -* [path.getbasename](path.getbasename) -* [path.getdirectory](path.getdirectory) -* [path.getdrive](path.getdrive) -* [path.getextension](path.getextension) -* [path.getname](path.getname) -* [path.getrelative](path.getrelative) -* [path.hasextension](path.hasextension) -* [path.isabsolute](path.isabsolute) -* [path.iscfile](path.iscfile) -* [path.iscppfile](path.iscppfile) -* [path.iscppheader](path.iscppheader) -* [path.isframework](path.isframework) -* [path.islinkable](path.islinkable) -* [path.isobjectfile](path.isobjectfile) -* [path.isresourcefile](path.isresourcefile) -* [path.join](path.join) -* [path.normalize](path.normalize) -* [path.rebase](path.rebase) -* [path.replaceextension](path.replaceextension) -* [path.translate](path.translate) -* [path.wildcards](path.wildcards) +* [path.appendExtension](path.appendExtension.md) +* [path.getabsolute](path.getabsolute.md) +* [path.getbasename](path.getbasename.md) +* [path.getdirectory](path.getdirectory.md) +* [path.getdrive](path.getdrive.md) +* [path.getextension](path.getextension.md) +* [path.getname](path.getname.md) +* [path.getrelative](path.getrelative.md) +* [path.hasextension](path.hasextension.md) +* [path.isabsolute](path.isabsolute.md) +* [path.iscfile](path.iscfile.md) +* [path.iscppfile](path.iscppfile.md) +* [path.iscppheader](path.iscppheader.md) +* [path.isframework](path.isframework.md) +* [path.islinkable](path.islinkable.md) +* [path.isobjectfile](path.isobjectfile.md) +* [path.isresourcefile](path.isresourcefile.md) +* [path.join](path.join.md) +* [path.normalize](path.normalize.md) +* [path.rebase](path.rebase.md) +* [path.replaceextension](path.replaceextension.md) +* [path.translate](path.translate.md) +* [path.wildcards](path.wildcards.md) ### String -* [string.capitalized](string.capitalized) -* [string.contains](string.contains) -* [string.endswith](string.endswith) -* [string.escapepattern](string.escapepattern) -* [string.explode](string.explode) -* [string.findlast](string.findlast) -* [string.hash](string.hash) -* [string.lines](string.lines) -* [string.plural](string.plural) -* [string.sha1](string.sha1) -* [string.startswith](string.startswith) +* [string.capitalized](string.capitalized.md) +* [string.contains](string.contains.md) +* [string.endswith](string.endswith.md) +* [string.escapepattern](string.escapepattern.md) +* [string.explode](string.explode.md) +* [string.findlast](string.findlast.md) +* [string.hash](string.hash.md) +* [string.lines](string.lines.md) +* [string.plural](string.plural.md) +* [string.sha1](string.sha1.md) +* [string.startswith](string.startswith.md) ### Table -* [table.arraycopy](table.arraycopy) -* [table.contains](table.contains) -* [table.deepcopy](table.deepcopy) -* [table.extract](table.extract) -* [table.filterempty](table.filterempty) -* [table.flatten](table.flatten) -* [table.fold](table.fold) -* [table.foreachi](table.foreachi) -* [table.implode](table.implode) -* [table.indexof](table.indexof) -* [table.insertafter](table.insertafter) -* [table.insertflat](table.insertflat) -* [table.isempty](table.isempty) -* [table.join](table.join) -* [table.keys](table.keys) -* [table.merge](table.merge) -* [table.replace](table.replace) -* [table.tostring](table.tostring) -* [table.translate](table.translate) +* [table.arraycopy](table.arraycopy.md) +* [table.contains](table.contains.md) +* [table.deepcopy](table.deepcopy.md) +* [table.extract](table.extract.md) +* [table.filterempty](table.filterempty.md) +* [table.flatten](table.flatten.md) +* [table.fold](table.fold.md) +* [table.foreachi](table.foreachi.md) +* [table.implode](table.implode.md) +* [table.indexof](table.indexof.md) +* [table.insertafter](table.insertafter.md) +* [table.insertflat](table.insertflat.md) +* [table.isempty](table.isempty.md) +* [table.join](table.join.md) +* [table.keys](table.keys.md) +* [table.merge](table.merge.md) +* [table.replace](table.replace.md) +* [table.tostring](table.tostring.md) +* [table.translate](table.translate.md) ### Term -* [term.getTextColor](term.getTextColor) -* [term.setTextColor](term.setTextColor) -* [term.pushColor](term.pushColor) -* [term.popColor](term.popColor) +* [term.getTextColor](term.getTextColor.md) +* [term.setTextColor](term.setTextColor.md) +* [term.pushColor](term.pushColor.md) +* [term.popColor](term.popColor.md) ### Zip -* [zip.extract](zip.extract) +* [zip.extract](zip.extract.md) diff --git a/website/docs/Makefile-Projects.md b/website/docs/Makefile-Projects.md index 15f04ad0..812252e6 100644 --- a/website/docs/Makefile-Projects.md +++ b/website/docs/Makefile-Projects.md @@ -50,9 +50,9 @@ Makefile projects currently have a few shortcomings. Help fixing these issues, o ## See Also ## -* [Custom Build Commands](custom-build-commands) -* [Custom Rules](custom-rules) -* [buildcommands](buildcommands) -* [buildoutputs](buildoutputs) -* [cleancommands](cleancommands) -* [rebuildcommands](rebuildcommands) +* [Custom Build Commands](Custom-Build-Commands.md) +* [Custom Rules](Custom-Rules.md) +* [buildcommands](buildcommands.md) +* [buildoutputs](buildoutputs.md) +* [cleancommands](cleancommands.md) +* [rebuildcommands](rebuildcommands.md) diff --git a/website/docs/Migrating-From-4.x.md b/website/docs/Migrating-From-4.x.md index aa8bb7fb..d65fe52b 100644 --- a/website/docs/Migrating-From-4.x.md +++ b/website/docs/Migrating-From-4.x.md @@ -4,21 +4,21 @@ title: Migrating from Premake 4.x # Function name changes -The function [`workspace`](workspace) replaces `solution`. The latter still works, but the former is preferred. +The function [`workspace`](workspace.md) replaces `solution`. The latter still works, but the former is preferred. -The function [`filter`](filter) replaces the `configuration` function for specifying the current configuration. It provides a more powerful interface for selecting which configuration is current, making it easy to specify flags for different actions, files, etc. The `configurations` setting at the workspace level still sets the available configurations. +The function [`filter`](filter.md) replaces the `configuration` function for specifying the current configuration. It provides a more powerful interface for selecting which configuration is current, making it easy to specify flags for different actions, files, etc. The `configurations` setting at the workspace level still sets the available configurations. # Flag changes -Many of the old [`flags`](flags) have become full-fledged functions. This should be a comprehensive list of such changes. +Many of the old [`flags`](flags.md) have become full-fledged functions. This should be a comprehensive list of such changes. | Old flags | New Function | | --------- | ------------ | -| `EnableSSE`, `EnableSSE2` | [`vectorextensions`](vectorextensions) | -| `ExtraWarnings`, `NoWarnings` | [`warnings`](warnings) | -| `FloatFast`, `FloatStrict` | [`floatingpoint`](floatingpoint) | -| `Managed`, `Unsafe` | [`clr`](clr) | -| `NativeWChar` | [`nativewchar`](nativewchar) | -| `NoEditAndContinue` | [`editandcontinue`](editandcontinue) | -| `NoRTTI` | [`rtti`](rtti) | -| `OptimizeSize`, `OptimizeSpeed` | [`optimize`](optimize) | +| `EnableSSE`, `EnableSSE2` | [`vectorextensions`](vectorextensions.md) | +| `ExtraWarnings`, `NoWarnings` | [`warnings`](warnings.md) | +| `FloatFast`, `FloatStrict` | [`floatingpoint`](floatingpoint.md) | +| `Managed`, `Unsafe` | [`clr`](clr.md) | +| `NativeWChar` | [`nativewchar`](nativewchar.md) | +| `NoEditAndContinue` | [`editandcontinue`](editAndContinue.md) | +| `NoRTTI` | [`rtti`](rtti.md) | +| `OptimizeSize`, `OptimizeSpeed` | [`optimize`](optimize.md) | diff --git a/website/docs/Overrides-and-Call-Arrays.md b/website/docs/Overrides-and-Call-Arrays.md index f2784e27..0a2b107e 100644 --- a/website/docs/Overrides-and-Call-Arrays.md +++ b/website/docs/Overrides-and-Call-Arrays.md @@ -23,7 +23,7 @@ Instead, we'd really like to implement this customization right in our project s ## Use the Source! -Before we can make this change, we first need to know what function in the Premake source code is emitting this particular markup. As described in the [Code Overview](code-overview), the Visual Studio exporter is currently located in the `src/actions/vstudio` folder in the Premake source tree (go ahead and find it, we'll wait!). +Before we can make this change, we first need to know what function in the Premake source code is emitting this particular markup. As described in the [Code Overview](Code-Overview.md), the Visual Studio exporter is currently located in the `src/actions/vstudio` folder in the Premake source tree (go ahead and find it, we'll wait!). We're looking for the code which generates the `.vcxproj` files, and browsing the file names brings us to `vs2010_vcxproj.lua`. Opening this file, we can then search for the `"=1.1") ``` -See [the `require()` documentation](require) for more information and examples. +See [the `require()` documentation](require.md) for more information and examples. diff --git a/website/docs/Using-Premake.md b/website/docs/Using-Premake.md index 82ac459a..fd61cd43 100644 --- a/website/docs/Using-Premake.md +++ b/website/docs/Using-Premake.md @@ -2,9 +2,9 @@ title: Using Premake --- -*New to Premake? You might want to start with [What is Premake?](what-is-premake)* +*New to Premake? You might want to start with [What is Premake?](What-Is-Premake.md)* -If you haven't already, you can [download Premake here](/download), or [build it from source](building-premake). Premake is a small command line executable, delivered as a single file. Just unpack the download and place the executable on your system search path, or anywhere else convenient. +If you haven't already, you can [download Premake here](/download), or [build it from source](Building-Premake.md). Premake is a small command line executable, delivered as a single file. Just unpack the download and place the executable on your system search path, or anywhere else convenient. ## Using Premake to Generate Project Files @@ -31,7 +31,7 @@ Premake defines the following list of actions out of the box; projects may also | xcode4 | XCode projects | | codelite | CodeLite projects | -(Premake4 supported some additional actions that haven't yet been ported to this new version; see the [Available Feature Matrix](feature-matrix) for the whole list.) +(Premake4 supported some additional actions that haven't yet been ported to this new version; see the [Available Feature Matrix](Feature-Matrix.md) for the whole list.) To generate Visual Studio 2013 project files, use the command: @@ -68,7 +68,7 @@ make clean # to clean the default target make config=release clean # to clean a different target ``` -Premake generated makefiles do not (currently) support a `make install` step. Instead, project owners are encouraged to [add an install action](command-line-arguments) to their Premake scripts, which has the advantage of working with any toolset on any platform. You can check for the existence of an install action by viewing the help (run `premake5 --help` in the project directory). +Premake generated makefiles do not (currently) support a `make install` step. Instead, project owners are encouraged to [add an install action](Command-Line-Arguments.md) to their Premake scripts, which has the advantage of working with any toolset on any platform. You can check for the existence of an install action by viewing the help (run `premake5 --help` in the project directory). [1]: http://www.cygwin.com/ [2]: http://www.mingw.org/ diff --git a/website/docs/Whats-New-in-5.0.md b/website/docs/Whats-New-in-5.0.md index c43cb7cb..4c812ab7 100644 --- a/website/docs/Whats-New-in-5.0.md +++ b/website/docs/Whats-New-in-5.0.md @@ -16,140 +16,140 @@ title: What's New in 5.0 ## Major Features ## -* [Custom Rules](custom-rules) (still experimental) -* [Makefile Projects](makefile-projects) -* [Modules](developing-modules) -* [Per-Configuration File Lists](files) -* [Per-File Configurations](configuration) -* [Per-Project Configurations](configurations-and-platforms) -* [Platforms](configurations-and-platforms) -* [Removes](removing-values) -* [System Scripts](system-scripts) -* [Tokens](tokens) -* [HTTP support](http.download) +* [Custom Rules](Custom-Rules.md) (still experimental) +* [Makefile Projects](Makefile-Projects.md) +* [Modules](Developing-Modules.md) +* [Per-Configuration File Lists](files.md) +* [Per-File Configurations](configuration.md) +* [Per-Project Configurations](Configurations-and-Platforms.md) +* [Platforms](Configurations-and-Platforms.md) +* [Removes](Removing-Values.md) +* [System Scripts](System-Scripts.md) +* [Tokens](Tokens.md) +* [HTTP support](http.download.md) ## New or Modified Globals ## -* [_MAIN_SCRIPT](_main_script) -* [_MAIN_SCRIPT_DIR](_main_script_dir) -* [_PREMAKE_DIR](_premake_dir) +* [_MAIN_SCRIPT](_MAIN_SCRIPT.md) +* [_MAIN_SCRIPT_DIR](_MAIN_SCRIPT_DIR.md) +* [_PREMAKE_DIR](_PREMAKE_DIR.md) ## New or Modified API calls ## -* [architecture](architecture) (new) -* [buildaction](buildaction) (new values) -* [buildcommands](buildcommands) (new) -* [builddependencies](builddependencies) (new) -* [buildlog](buildlog) (new) -* [buildmessage](buildmessage) (new) -* [buildoutputs](buildoutputs) (new) -* [characterset](characterset) (new) -* [callingconvention](callingconvention) (new) -* [cleancommands](cleancommands) (new) -* [cleanextensions](cleanextensions) (new) -* [clr](clr) (new, replaces flags `Managed` and `Unsafe`) -* [configfile](configfile) (new) -* [configmap](configmap) (new) -* [configuration](configuration) (retired) -* [configurations](configurations) (modified) -* [copylocal](copylocal) (new) -* [debugcommand](debugcommand) (new) -* [debugconnectcommands](debugconnectcommands) (new) -* [debugextendedprotocol](debugextendedprotocol) (new) -* [debugport](debugport) (new) -* [debugremotehost](debugremotehost) (new) -* [debugsearchpaths](debugsearchpaths) (new) -* [debugstartupcommands](debugstartupcommands) (new) -* [dependson](dependson) (new) -* [disablewarnings](disablewarnings) (new) -* [dotnetframework](dotnetframework) (new) -* [editandcontinue](editandcontinue) (new, replaces flag `NoEditAndContinue`) -* [editorintegration](editorintegration) (new) -* [enablewarnings](enablewarnings) (new) -* [endian](endian) (new) -* [entrypoint](entrypoint) (new) -* [exceptionhandling](exceptionhandling) (new) -* [external](external) (new) -* [externalproject](externalproject) (new) -* [externalrule](externalrule) (new) -* [fatalwarnings](fatalwarnings) (new) -* [fileextension](fileextension) (new) -* [filename](filename) (new) -* [filter](filter) (new) -* [flags](flags) (new values) -* [floatingpoint](floatingpoint) (new, replaces flags `FloatFast` and `FloatStrict`) -* [forceincludes](forceincludes) (new) -* [forceusings](forceusings) (new) -* [fpu](fpu) (new) -* [gccprefix](gccprefix) (new) -* [group](group) (new) -* [icon](icon) (new) -* [inlining](inlining) (new) -* [kind](kind) (Makefile, None) -* [linkbuildoutputs](linkbuildoutputs) (new) -* [links](links) -* [language](language) (new values) -* [locale](locale) (new) -* [makesettings](makesettings) (new) -* [namespace](namespace) (new) -* [nativewchar](nativewchar) (new, replaces flag `NativeWChar`) -* [newaction](newaction) (modified) -* [nuget](nuget) (new) -* [objdir](objdir) (modified) -* [optimize](optimize) (new, replaces flags `OptimizeSize` and `OptimizeSpeed`) -* [pic](pic) (new) -* [platforms](platforms) (modified) -* [postbuildmessage](postbuildmessage) (new) -* [prebuildmessage](prebuildmessage) (new) -* [prelinkmessage](prelinkmessage) (new) -* [project](project) (modified) -* [propertydefinition](propertydefinition) (new) -* [rebuildcommands](rebuildcommands) (new) -* [rtti](rtti) (new, replaces flag `NoRTTI`) -* [rule](rule) (new) -* [rules](rules) (new) -* [runtime](runtime) (new) -* [solution](workspace) (name changed) -* [startproject](startproject) (new) -* [strictaliasing](strictaliasing) (new) -* [sysincludedirs](sysincludedirs) (new) -* [syslibdirs](syslibdirs) (new) -* [system](system) (new) -* [toolset](toolset) (new) -* [undefines](undefines) (new) -* [vectorextensions](vectorextensions) (new, replaces flags `EnableSSE` and `EnableSSE2`) -* [warnings](warnings) (new, replaces flags `ExtraWarnings` and `NoWarnings`) -* [workspace](workspace) (new) +* [architecture](architecture.md) (new) +* [buildaction](buildaction.md) (new values) +* [buildcommands](buildcommands.md) (new) +* [builddependencies](builddependencies.md) (new) +* [buildlog](buildlog.md) (new) +* [buildmessage](buildmessage.md) (new) +* [buildoutputs](buildoutputs.md) (new) +* [characterset](characterset.md) (new) +* [callingconvention](callingconvention.md) (new) +* [cleancommands](cleancommands.md) (new) +* [cleanextensions](cleanextensions.md) (new) +* [clr](clr.md) (new, replaces flags `Managed` and `Unsafe`) +* [configfile](configfile.md) (new) +* [configmap](configmap.md) (new) +* [configuration](configuration.md) (retired) +* [configurations](configurations.md) (modified) +* [copylocal](copylocal.md) (new) +* [debugcommand](debugcommand.md) (new) +* [debugconnectcommands](debugconnectcommands.md) (new) +* [debugextendedprotocol](debugextendedprotocol.md) (new) +* [debugport](debugport.md) (new) +* [debugremotehost](debugremotehost.md) (new) +* [debugsearchpaths](debugsearchpaths.md) (new) +* [debugstartupcommands](debugstartupcommands.md) (new) +* [dependson](dependson.md) (new) +* [disablewarnings](disablewarnings.md) (new) +* [dotnetframework](dotnetframework.md) (new) +* [editandcontinue](editAndContinue.md) (new, replaces flag `NoEditAndContinue`) +* [editorintegration](editorintegration.md) (new) +* [enablewarnings](enablewarnings.md) (new) +* [endian](endian.md) (new) +* [entrypoint](entrypoint.md) (new) +* [exceptionhandling](exceptionhandling.md) (new) +* [external](external.md) (new) +* [externalproject](externalproject.md) (new) +* [externalrule](externalrule.md) (new) +* [fatalwarnings](fatalwarnings.md) (new) +* [fileextension](fileextension.md) (new) +* [filename](filename.md) (new) +* [filter](filter.md) (new) +* [flags](flags.md) (new values) +* [floatingpoint](floatingpoint.md) (new, replaces flags `FloatFast` and `FloatStrict`) +* [forceincludes](forceincludes.md) (new) +* [forceusings](forceusings.md) (new) +* [fpu](fpu.md) (new) +* [gccprefix](gccprefix.md) (new) +* [group](group.md) (new) +* [icon](icon.md) (new) +* [inlining](inlining.md) (new) +* [kind](kind.md) (Makefile, None) +* [linkbuildoutputs](linkbuildoutputs.md) (new) +* [links](links.md) +* [language](language.md) (new values) +* [locale](locale.md) (new) +* [makesettings](makesettings.md) (new) +* [namespace](namespace.md) (new) +* [nativewchar](nativewchar.md) (new, replaces flag `NativeWChar`) +* [newaction](newaction.md) (modified) +* [nuget](nuget.md) (new) +* [objdir](objdir.md) (modified) +* [optimize](optimize.md) (new, replaces flags `OptimizeSize` and `OptimizeSpeed`) +* [pic](pic.md) (new) +* [platforms](platforms.md) (modified) +* [postbuildmessage](postbuildmessage.md) (new) +* [prebuildmessage](prebuildmessage.md) (new) +* [prelinkmessage](prelinkmessage.md) (new) +* [project](project.md) (modified) +* [propertydefinition](propertydefinition.md) (new) +* [rebuildcommands](rebuildcommands.md) (new) +* [rtti](rtti.md) (new, replaces flag `NoRTTI`) +* [rule](rule.md) (new) +* [rules](rules.md) (new) +* [runtime](runtime.md) (new) +* [solution](workspace.md) (name changed) +* [startproject](startproject.md) (new) +* [strictaliasing](strictaliasing.md) (new) +* [sysincludedirs](sysincludedirs.md) (new) +* [syslibdirs](syslibdirs.md) (new) +* [system](system.md) (new) +* [toolset](toolset.md) (new) +* [undefines](undefines.md) (new) +* [vectorextensions](vectorextensions.md) (new, replaces flags `EnableSSE` and `EnableSSE2`) +* [warnings](warnings.md) (new, replaces flags `ExtraWarnings` and `NoWarnings`) +* [workspace](workspace.md) (new) ## New or Modified Lua library calls ## -* [includeexternal](includeexternal) (new) -* [require](require) (modified) +* [includeexternal](includeexternal.md) (new) +* [require](require.md) (modified) -* [debug.prompt](debug.prompt) (new) +* [debug.prompt](debug.prompt.md) (new) -* [http.download](http.download) (new) -* [http.get](http.get) (new) +* [http.download](http.download.md) (new) +* [http.get](http.get.md) (new) -* [os.chmod](os.chmod) (new) -* [os.islink](os.islink) (new) -* [os.realpath](os.realpath) (new) -* [os.uuid](os.uuid) (can now generated deterministic name-based UUIDs) +* [os.chmod](os.chmod.md) (new) +* [os.islink](os.islink.md) (new) +* [os.realpath](os.realpath.md) (new) +* [os.uuid](os.uuid.md) (can now generated deterministic name-based UUIDs) -* [path.getabsolute](path.getabsolute) (new "relative to" argument) +* [path.getabsolute](path.getabsolute.md) (new "relative to" argument) -* [string.hash](string.hash) (new) +* [string.hash](string.hash.md) (new) ## Deprecated Values and Functions ## -* [buildrule](buildrule) -* [flags](flags): +* [buildrule](buildrule.md) +* [flags](flags.md): * Component - * EnableSSE, EnableSSE2: use [vectorextensions](vectorextensions) instead - * ExtraWarnings, NoWarnings: use [warnings](warnings) instead - * FloatFast, FloatStrict: use [floatingpoint](floatingpoint) instead - * Managed, Unsafe: use [clr](clr) instead - * NativeWChar: use [nativewchar](nativewchar) instead - * NoEditAndContinue: use [editandcontinue](editandcontinue) instead - * NoRTTI: use [rtti](rtti) instead. - * OptimizeSize, OptimizeSpeed: use [optimize](optimize) instead + * EnableSSE, EnableSSE2: use [vectorextensions](vectorextensions.md) instead + * ExtraWarnings, NoWarnings: use [warnings](warnings.md) instead + * FloatFast, FloatStrict: use [floatingpoint](floatingpoint.md) instead + * Managed, Unsafe: use [clr](clr.md) instead + * NativeWChar: use [nativewchar](nativewchar.md) instead + * NoEditAndContinue: use [editandcontinue](editAndContinue.md) instead + * NoRTTI: use [rtti](rtti.md) instead. + * OptimizeSize, OptimizeSpeed: use [optimize](optimize.md) instead diff --git a/website/docs/Workspaces-and-Projects.md b/website/docs/Workspaces-and-Projects.md index 7f047c95..fda1f9d4 100644 --- a/website/docs/Workspaces-and-Projects.md +++ b/website/docs/Workspaces-and-Projects.md @@ -9,16 +9,16 @@ For convenience, Premake follows the Visual Studio conventions for structuring a At the top level of every build is a *workspace*, acting as a container for *projects*. Other tools, notably Visual Studio, may use the term *solution*. -Workspaces define a common set of [build configurations and platforms](configurations-and-platforms) to be used across all of the contained projects. You may also specify additional build settings (defines, include paths, etc.) at this level which will be similarly inherited by the projects. +Workspaces define a common set of [build configurations and platforms](Configurations-and-Platforms.md) to be used across all of the contained projects. You may also specify additional build settings (defines, include paths, etc.) at this level which will be similarly inherited by the projects. -Workspaces are defined using the [`workspace`](workspace) function. Most builds will need only a single workspace, but you are free to create more if needed. Build configurations are specified using the [`configurations`](configurations) function and are required; see [Configurations and Platforms](configurations-and-platforms) for more information. +Workspaces are defined using the [`workspace`](workspace.md) function. Most builds will need only a single workspace, but you are free to create more if needed. Build configurations are specified using the [`configurations`](configurations.md) function and are required; see [Configurations and Platforms](Configurations-and-Platforms.md) for more information. ```lua workspace "HelloWorld" configurations { "Debug", "Release" } ``` -The workspace name, provided as a parameter to the function, is used as the default file name of the generated workspace file, so it is best to avoid special characters (spaces are okay). If you wish to use a different name use the [`filename`](filename) function to specify it. +The workspace name, provided as a parameter to the function, is used as the default file name of the generated workspace file, so it is best to avoid special characters (spaces are okay). If you wish to use a different name use the [`filename`](filename.md) function to specify it. ```lua workspace "Hello World" @@ -33,7 +33,7 @@ workspace "Hello World" The primary purpose of a workspace is to act as a container for projects. A *project* lists the settings and source files needed to build one binary target. Just about every IDE uses the term "project" for this. In the world of Make, you can think of projects as a makefile for one particular library or executable; the workspace is a meta-makefile that calls each project as needed. -Projects are defined using the [`project`](project) function. You must create the containing workspace first. +Projects are defined using the [`project`](project.md) function. You must create the containing workspace first. ```lua workspace "MyWorkspace" @@ -42,11 +42,11 @@ workspace "MyWorkspace" project "MyProject" ``` -The project name, like the workspace name, is used as the file name for the generated project file so avoid special characters, or use the [`filename`](filename) function to provide a different value. +The project name, like the workspace name, is used as the file name for the generated project file so avoid special characters, or use the [`filename`](filename.md) function to provide a different value. -Each project specifies a *kind* which determines what kind of output is generated, such as a console or windowed executable, or a shared or static library. The [`kind`](kind) function is used to specify this value. +Each project specifies a *kind* which determines what kind of output is generated, such as a console or windowed executable, or a shared or static library. The [`kind`](kind.md) function is used to specify this value. -Each project also specifies which programming language it uses, such as C++ or C#. The [`language`](language) function is used to set this value. +Each project also specifies which programming language it uses, such as C++ or C#. The [`language`](language.md) function is used to set this value. ```lua project "MyProject" @@ -59,7 +59,7 @@ project "MyProject" By default, Premake will place generated workspace and project files in the same directory as the script which defined them. If your Premake script is in `C:\Code\MyProject` then the generated files will also be in `C:\Code\MyProject`. -You can change the output location using the [location](location) function. +You can change the output location using the [location](location.md) function. ```lua workspace "MyWorkspace" @@ -70,4 +70,4 @@ project "MyProject" location "build/MyProject" ``` -Like all paths in Premake, the [location](location) should be specified relative to the script file. Using the example and script above, the generated workspace will be placed in `C:\Code\MyProject\build` and the project in `C:\Code\MyProject\build\MyProject`. +Like all paths in Premake, the [location](location.md) should be specified relative to the script file. Using the example and script above, the generated workspace will be placed in `C:\Code\MyProject\build` and the project in `C:\Code\MyProject\build\MyProject`. diff --git a/website/docs/Your-First-Script.md b/website/docs/Your-First-Script.md index 2901da7b..a194d39f 100644 --- a/website/docs/Your-First-Script.md +++ b/website/docs/Your-First-Script.md @@ -43,7 +43,7 @@ If you save this script as a file named `premake5.lua`, and place it in the same $ premake5 vs2013 ``` -This particular command will generate `HelloWorld.sln` and `HelloWorld.vcxproj` files for Visual Studio 2013 (see [Using Premake](using-premake) or run `premake --help` for a complete list of exporters). If you build the generated workspace, you will get a command line executable named `HelloWorld.exe` in the `bin/Debug` or `bin/Release` directory, depending on which configuration was selected within Visual Studio. +This particular command will generate `HelloWorld.sln` and `HelloWorld.vcxproj` files for Visual Studio 2013 (see [Using Premake](Using-Premake.md) or run `premake --help` for a complete list of exporters). If you build the generated workspace, you will get a command line executable named `HelloWorld.exe` in the `bin/Debug` or `bin/Release` directory, depending on which configuration was selected within Visual Studio. If you happened to be on Linux, you could generate and build a makefile like so: diff --git a/website/docs/os.translateCommands.md b/website/docs/os.translateCommands.md index e7f39282..d45a48ab 100644 --- a/website/docs/os.translateCommands.md +++ b/website/docs/os.translateCommands.md @@ -1,4 +1,4 @@ -Translate [command tokens](Tokens#command-tokens) into their OS or action specific equivalents. +Translate [command tokens](Tokens.md#command-tokens) into their OS or action specific equivalents. ```lua cmd = os.translateCommands("cmd", map) From 38458a362491f11609ad305aa84cc7a63eefe03d Mon Sep 17 00:00:00 2001 From: tempura-sukiyaki <10625603+tempura-sukiyaki@users.noreply.github.com> Date: Tue, 8 Jun 2021 07:03:59 +0900 Subject: [PATCH 04/19] Sort `buildinputs` and `buildoutputs` on xcode4 (#1631) * Sort `buildinputs` and `buildoutputs` on xcode4 * Fix `buildinputs` and `buildoutputs` for Xcode4 --- modules/xcode/tests/test_xcode_project.lua | 36 ++++++++++++++++++++++ modules/xcode/xcode_common.lua | 12 +++++--- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/modules/xcode/tests/test_xcode_project.lua b/modules/xcode/tests/test_xcode_project.lua index 275a2d35..fc853a81 100644 --- a/modules/xcode/tests/test_xcode_project.lua +++ b/modules/xcode/tests/test_xcode_project.lua @@ -1315,6 +1315,42 @@ end + function suite.PBXShellScriptBuildPhase_OnBuildInputsAnddOutputsOrder() + files { "file.a" } + filter { "files:file.a" } + buildcommands { "buildcmd" } + buildinputs { "file.3", "file.1", "file.2" } + buildoutputs { "file.5", "file.6", "file.4" } + prepare() + xcode.PBXShellScriptBuildPhase(tr) + test.capture [[ +/* Begin PBXShellScriptBuildPhase section */ + 0D594A1D2F24F74F6BDA205D /* Build "file.a" */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "file.a", + "file.3", + "file.1", + "file.2", + ); + name = "Build \"file.a\""; + outputPaths = ( + "file.5", + "file.6", + "file.4", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "set -e\nif [ \"${CONFIGURATION}\" = \"Debug\" ]; then\n\tbuildcmd\nfi\nif [ \"${CONFIGURATION}\" = \"Release\" ]; then\n\tbuildcmd\nfi"; + }; +/* End PBXShellScriptBuildPhase section */ + ]] + end + + --------------------------------------------------------------------------- -- PBXSourcesBuildPhase tests --------------------------------------------------------------------------- diff --git a/modules/xcode/xcode_common.lua b/modules/xcode/xcode_common.lua index 35209d71..b3057d35 100644 --- a/modules/xcode/xcode_common.lua +++ b/modules/xcode/xcode_common.lua @@ -1110,10 +1110,14 @@ end table.insert(commands, 'fi') for _, v in ipairs(filecfg.buildinputs) do - inputs[v] = true + if not table.indexof(inputs, v) then + table.insert(inputs, v) + end end for _, v in ipairs(filecfg.buildoutputs) do - outputs[v] = true + if not table.indexof(outputs, v) then + table.insert(outputs, v) + end end end end @@ -1129,13 +1133,13 @@ _p(level+1,');') _p(level+1,'inputPaths = ('); _p(level+2,'"%s",', xcode.escapeSetting(node.relpath)) - for v, _ in pairs(inputs) do + for _, v in ipairs(inputs) do _p(level+2,'"%s",', xcode.escapeSetting(project.getrelative(tr.project, v))) end _p(level+1,');') _p(level+1,'name = %s;', xcode.stringifySetting('Build "' .. node.name .. '"')) _p(level+1,'outputPaths = (') - for v, _ in pairs(outputs) do + for _, v in ipairs(outputs) do _p(level+2,'"%s",', xcode.escapeSetting(project.getrelative (tr.project, v))) end _p(level+1,');') From 07bddc14befdf15d394d96d36ce9f8a113c5652f Mon Sep 17 00:00:00 2001 From: Troplo Date: Thu, 10 Jun 2021 20:03:32 +1000 Subject: [PATCH 05/19] Fix spelling mistake --- website/docs/What-Is-Premake.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/What-Is-Premake.md b/website/docs/What-Is-Premake.md index 5d891f0e..b131f520 100644 --- a/website/docs/What-Is-Premake.md +++ b/website/docs/What-Is-Premake.md @@ -56,7 +56,7 @@ Done. The current development version of Premake 5.0 can generate C, C++, or C# projects targeting: -* Microsft Visual Studio 2005-2019 +* Microsoft Visual Studio 2005-2019 * GNU Make, including Cygwin and MinGW * Xcode * Codelite From fe98e430c5e8bcbc10f663afdb3f8d70a398fdfb Mon Sep 17 00:00:00 2001 From: KyrietS Date: Thu, 10 Jun 2021 22:08:43 +0200 Subject: [PATCH 06/19] Fix author name and update time on pages --- .github/workflows/website.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/website.yml b/.github/workflows/website.yml index 7cbc67f0..c57e28ab 100644 --- a/.github/workflows/website.yml +++ b/.github/workflows/website.yml @@ -24,6 +24,8 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 + with: + fetch-depth: 0 - uses: actions/setup-node@v2 with: node-version: '14' From a56444a3fe233c183d9595c61b3798d826774726 Mon Sep 17 00:00:00 2001 From: Jarod42 Date: Fri, 11 Jun 2021 20:15:33 +0200 Subject: [PATCH 07/19] Add missing support for prebuildmessage/postbuildmessage for Codelite. --- modules/codelite/codelite_project.lua | 16 +++++++++---- .../codelite/tests/test_codelite_config.lua | 23 +++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/modules/codelite/codelite_project.lua b/modules/codelite/codelite_project.lua index d427fe41..af356897 100755 --- a/modules/codelite/codelite_project.lua +++ b/modules/codelite/codelite_project.lua @@ -314,10 +314,14 @@ end function m.preBuild(cfg) - if #cfg.prebuildcommands > 0 then + if #cfg.prebuildcommands > 0 or cfg.prebuildmessage then _p(3, '') - local commands = os.translateCommandsAndPaths(cfg.prebuildcommands, cfg.project.basedir, cfg.project.location) p.escaper(codelite.escElementText) + if cfg.prebuildmessage then + local command = os.translateCommandsAndPaths("@{ECHO} " .. cfg.prebuildmessage, cfg.project.basedir, cfg.project.location) + _x(4, '%s', command) + end + local commands = os.translateCommandsAndPaths(cfg.prebuildcommands, cfg.project.basedir, cfg.project.location) for _, command in ipairs(commands) do _x(4, '%s', command) end @@ -327,10 +331,14 @@ end function m.postBuild(cfg) - if #cfg.postbuildcommands > 0 then + if #cfg.postbuildcommands > 0 or cfg.postbuildmessage then _p(3, '') - local commands = os.translateCommandsAndPaths(cfg.postbuildcommands, cfg.project.basedir, cfg.project.location) p.escaper(codelite.escElementText) + if cfg.postbuildmessage then + local command = os.translateCommandsAndPaths("@{ECHO} " .. cfg.postbuildmessage, cfg.project.basedir, cfg.project.location) + _x(4, '%s', command) + end + local commands = os.translateCommandsAndPaths(cfg.postbuildcommands, cfg.project.basedir, cfg.project.location) for _, command in ipairs(commands) do _x(4, '%s', command) end diff --git a/modules/codelite/tests/test_codelite_config.lua b/modules/codelite/tests/test_codelite_config.lua index e98c8b88..4a72da68 100644 --- a/modules/codelite/tests/test_codelite_config.lua +++ b/modules/codelite/tests/test_codelite_config.lua @@ -181,6 +181,29 @@ ]] end + function suite.OnProjectCfg_PreBuildMessage() + prebuildmessage "test" + prepare() + codelite.project.preBuild(cfg) + test.capture [[ + + @echo test + + ]] + end + + function suite.OnProjectCfg_PostBuildMessage() + postbuildmessage "test" + prepare() + codelite.project.postBuild(cfg) + test.capture [[ + + @echo test + + ]] + end + + function suite.OnProjectCfg_General() system "Windows" prepare() From 4da7825927e517c96dd2b656ecfcb2ded13d32cf Mon Sep 17 00:00:00 2001 From: Renaud Guillard Date: Mon, 14 Jun 2021 10:30:34 +0200 Subject: [PATCH 08/19] Fix curl header search path Consider curl include directory as system header search path to match #include directives with angle brackets. --- contrib/curl/premake5.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/curl/premake5.lua b/contrib/curl/premake5.lua index 9f5ff0d2..5a49939d 100644 --- a/contrib/curl/premake5.lua +++ b/contrib/curl/premake5.lua @@ -1,7 +1,8 @@ project "curl-lib" language "C" kind "StaticLib" - includedirs { "include", "lib", "../mbedtls/include/" } + sysincludedirs { "include" } + includedirs { "lib", "../mbedtls/include" } defines { "BUILDING_LIBCURL", "CURL_STATICLIB", "HTTP_ONLY" } warnings "off" From b48fd2c4e9138360a9db44456f335cfcf1bd569b Mon Sep 17 00:00:00 2001 From: abhiss <36640936+abhiss@users.noreply.github.com> Date: Mon, 14 Jun 2021 09:07:03 -0700 Subject: [PATCH 09/19] Update Using-Premake.md --- website/docs/Using-Premake.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/Using-Premake.md b/website/docs/Using-Premake.md index 39a19ede..275a633e 100644 --- a/website/docs/Using-Premake.md +++ b/website/docs/Using-Premake.md @@ -47,7 +47,7 @@ premake5 --help ## Using the Generated Projects -For toolsets like Visual Studio and Xcode, you can simply load the generated workspace or workspaces into your IDE and build as you normally would. +For toolsets like Visual Studio and Xcode, you can simply load the generated solution or workspace into your IDE and build as you normally would. If you have generated makefiles, running `make` with no options will build all targets using the default configuration, as set by the project author. To see the list of available configurations, type: From ffdee199697e54f326bc3803d415b4bf4367dad2 Mon Sep 17 00:00:00 2001 From: Nicholaus Clark Date: Wed, 23 Jun 2021 19:20:00 -0400 Subject: [PATCH 10/19] Added compiler version selection for visual studio projects --- modules/vstudio/tests/vc2010/test_globals.lua | 32 +++++++++++++++++++ modules/vstudio/vs2010_vcxproj.lua | 17 ++++++++-- src/_premake_init.lua | 13 ++++++-- website/docs/Project-API.md | 1 + website/docs/Whats-New-in-5.0.md | 1 + website/docs/toolsversion.md | 27 ++++++++++++++++ 6 files changed, 85 insertions(+), 6 deletions(-) create mode 100644 website/docs/toolsversion.md diff --git a/modules/vstudio/tests/vc2010/test_globals.lua b/modules/vstudio/tests/vc2010/test_globals.lua index e2f4019b..fe2bb956 100644 --- a/modules/vstudio/tests/vc2010/test_globals.lua +++ b/modules/vstudio/tests/vc2010/test_globals.lua @@ -411,3 +411,35 @@ end ]] end + + + function suite.setToolsVersion2015() + toolsversion "14.27.29110" + p.action.set("vs2015") + prepare() + test.capture [[ + + {42B5DBC6-AE1F-903D-F75D-41E363076E92} + true + Win32Proj + MyProject + + ]] + end + + + function suite.setToolsVersion2017() + toolsversion "14.27.29110" + p.action.set("vs2017") + prepare() + test.capture [[ + + {42B5DBC6-AE1F-903D-F75D-41E363076E92} + true + Win32Proj + MyProject + $([Microsoft.Build.Utilities.ToolLocationHelper]::GetLatestSDKTargetPlatformVersion('Windows', '10.0')) + 14.27.29110 + + ]] + end diff --git a/modules/vstudio/vs2010_vcxproj.lua b/modules/vstudio/vs2010_vcxproj.lua index 58e5676e..981aeeef 100644 --- a/modules/vstudio/vs2010_vcxproj.lua +++ b/modules/vstudio/vs2010_vcxproj.lua @@ -134,6 +134,7 @@ m.latestTargetPlatformVersion, m.windowsTargetPlatformVersion, m.fastUpToDateCheck, + m.toolsVersion, } end @@ -183,6 +184,7 @@ return { m.configurationType, m.platformToolset, + m.toolsVersion, } else return { @@ -193,6 +195,7 @@ m.clrSupport, m.characterSet, m.platformToolset, + m.toolsVersion, m.wholeProgramOptimization, m.nmakeOutDirs, m.windowsSDKDesktopARMSupport, @@ -1699,11 +1702,11 @@ m.element("CompileAs", condition, "CompileAsC") elseif p.languages.iscpp(cfg.compileas) then m.element("CompileAs", condition, "CompileAsCpp") - elseif cfg.compileas == "Module" then + elseif cfg.compileas == "Module" then m.element("CompileAs", condition, "CompileAsCppModule") - elseif cfg.compileas == "ModulePartition" then + elseif cfg.compileas == "ModulePartition" then m.element("CompileAs", condition, "CompileAsCppModuleInternalPartition") - elseif cfg.compileas == "HeaderUnit" then + elseif cfg.compileas == "HeaderUnit" then m.element("CompileAs", condition, "CompileAsHeaderUnit") end end @@ -2383,6 +2386,14 @@ end + function m.toolsVersion(cfg) + local version = cfg.toolsversion + if _ACTION >= "vs2017" and version then + m.element("VCToolsVersion", nil, version) + end + end + + function m.platformToolset(cfg) local tool, version = p.config.toolset(cfg) diff --git a/src/_premake_init.lua b/src/_premake_init.lua index 344969ba..951495fe 100644 --- a/src/_premake_init.lua +++ b/src/_premake_init.lua @@ -185,9 +185,9 @@ "C++", "Objective-C", "Objective-C++", - "Module", - "ModulePartition", - "HeaderUnit" + "Module", + "ModulePartition", + "HeaderUnit" } } @@ -1253,6 +1253,13 @@ end, } + api.register { + name = "toolsversion", + scope = "project", + kind = "string", + tokens = true, + } + api.register { name = "customtoolnamespace", scope = "config", diff --git a/website/docs/Project-API.md b/website/docs/Project-API.md index b62f4b55..a750bbf3 100644 --- a/website/docs/Project-API.md +++ b/website/docs/Project-API.md @@ -163,6 +163,7 @@ | [targetprefix](targetprefix.md) | | | [targetsuffix](targetsuffix.md) | | | [toolset](toolset.md) | | +| [toolsversion](toolsversion.md) | | | [undefines](undefines.md) | | | [usingdirs](usingdirs.md) | | | [uuid](uuid.md) | Set project GUID (for VS projects/workspaces) | diff --git a/website/docs/Whats-New-in-5.0.md b/website/docs/Whats-New-in-5.0.md index 4c812ab7..36c74541 100644 --- a/website/docs/Whats-New-in-5.0.md +++ b/website/docs/Whats-New-in-5.0.md @@ -116,6 +116,7 @@ title: What's New in 5.0 * [syslibdirs](syslibdirs.md) (new) * [system](system.md) (new) * [toolset](toolset.md) (new) +* [toolsversion](toolsversion.md) (new) * [undefines](undefines.md) (new) * [vectorextensions](vectorextensions.md) (new, replaces flags `EnableSSE` and `EnableSSE2`) * [warnings](warnings.md) (new, replaces flags `ExtraWarnings` and `NoWarnings`) diff --git a/website/docs/toolsversion.md b/website/docs/toolsversion.md new file mode 100644 index 00000000..b1ce76fe --- /dev/null +++ b/website/docs/toolsversion.md @@ -0,0 +1,27 @@ +Selects the tools version which is used to build a project. + +```lua +toolsversion ("identifier") +``` + +If no version is specified for a configuration, the build tool will define the a default version. + +### Parameters ### + +`identifier` is a string identifier for the toolset version. + +### Applies To ### + +Project configurations. + +### Availability ### + +Premake 5.0 and later. Versions are currently only implemented for Visual Studio 2017+. + +### Examples ### + +Specify tool version 14.27.29110 of the toolset. + +```lua +toolsversion "14.27.29110" +``` \ No newline at end of file From 076b9684af5466b27f65311cb1d78dcdf36fe7f6 Mon Sep 17 00:00:00 2001 From: Nicholaus Clark Date: Wed, 23 Jun 2021 20:03:18 -0400 Subject: [PATCH 11/19] Renormalized line endings in the repository --- .../scripts/data_files/vs6-app-template.dsp | 202 +-- .../scripts/data_files/vs6-main-template.dsp | 188 +- .../data_files/vs6-workspace-template.dsw | 36 +- contrib/mbedtls/scripts/windows_msbuild.bat | 40 +- .../tests/vc2010/test_compile_settings.lua | 10 +- modules/vstudio/vs2010_vcxproj.lua | 6 +- modules/xcode/tests/test_xcode4_workspace.lua | 266 +-- modules/xcode/xcode_project.lua | 536 +++--- src/_premake_init.lua | 6 +- src/base/os.lua | 1586 ++++++++--------- src/host/os_is64bit.c | 60 +- tests/_tests.lua | 132 +- tests/base/test_os.lua | 968 +++++----- tests/test.bat | 8 +- 14 files changed, 2022 insertions(+), 2022 deletions(-) diff --git a/contrib/mbedtls/scripts/data_files/vs6-app-template.dsp b/contrib/mbedtls/scripts/data_files/vs6-app-template.dsp index 87dbea24..ff7c00e5 100644 --- a/contrib/mbedtls/scripts/data_files/vs6-app-template.dsp +++ b/contrib/mbedtls/scripts/data_files/vs6-app-template.dsp @@ -1,101 +1,101 @@ -# Microsoft Developer Studio Project File - Name="" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Console Application" 0x0103 - -CFG= - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f ".mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f ".mak" CFG=" - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE " - Win32 Release" (based on "Win32 (x86) Console Application") -!MESSAGE " - Win32 Debug" (based on "Win32 (x86) Console Application") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == " - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "" -# PROP BASE Intermediate_Dir "temp" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "" -# PROP Intermediate_Dir "temp" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 - -!ELSEIF "$(CFG)" == " - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "" -# PROP BASE Intermediate_Dir "temp" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "" -# PROP Intermediate_Dir "temp" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /Gm /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /Gm /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept - -!ENDIF - -# Begin Target - -# Name " - Win32 Release" -# Name " - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=..\..\programs\.c -# ADD CPP /I "../../include" -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# End Group -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG= - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f ".mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f ".mak" CFG=" - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE " - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE " - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == " - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "" +# PROP BASE Intermediate_Dir "temp" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "temp" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +!ELSEIF "$(CFG)" == " - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "" +# PROP BASE Intermediate_Dir "temp" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "temp" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /Gm /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name " - Win32 Release" +# Name " - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=..\..\programs\.c +# ADD CPP /I "../../include" +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/contrib/mbedtls/scripts/data_files/vs6-main-template.dsp b/contrib/mbedtls/scripts/data_files/vs6-main-template.dsp index 89d3fc73..3f4d5c41 100644 --- a/contrib/mbedtls/scripts/data_files/vs6-main-template.dsp +++ b/contrib/mbedtls/scripts/data_files/vs6-main-template.dsp @@ -1,94 +1,94 @@ -# Microsoft Developer Studio Project File - Name="mbedtls" - Package Owner=<4> -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Static Library" 0x0104 - -CFG=mbedtls - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "mbedtls.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "mbedtls.mak" CFG="mbedtls - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "mbedtls - Win32 Release" (based on "Win32 (x86) Static Library") -!MESSAGE "mbedtls - Win32 Debug" (based on "Win32 (x86) Static Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -RSC=rc.exe - -!IF "$(CFG)" == "mbedtls - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "" -# PROP BASE Intermediate_Dir "temp" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "" -# PROP Intermediate_Dir "temp" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD CPP /nologo /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ELSEIF "$(CFG)" == "mbedtls - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "" -# PROP BASE Intermediate_Dir "temp" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "" -# PROP Intermediate_Dir "temp" -# PROP Target_Dir "" -# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD CPP /nologo /W3 /GX /Z7 /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LIB32=link.exe -lib -# ADD BASE LIB32 /nologo -# ADD LIB32 /nologo - -!ENDIF - -# Begin Target - -# Name "mbedtls - Win32 Release" -# Name "mbedtls - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -SOURCE_ENTRIES -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -HEADER_ENTRIES -# End Group -# End Target -# End Project +# Microsoft Developer Studio Project File - Name="mbedtls" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=mbedtls - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "mbedtls.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "mbedtls.mak" CFG="mbedtls - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "mbedtls - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "mbedtls - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "mbedtls - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "" +# PROP BASE Intermediate_Dir "temp" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "" +# PROP Intermediate_Dir "temp" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /W3 /GX /O2 /I "../../include" /D "NDEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x40c /d "NDEBUG" +# ADD RSC /l 0x40c /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ELSEIF "$(CFG)" == "mbedtls - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "" +# PROP BASE Intermediate_Dir "temp" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "" +# PROP Intermediate_Dir "temp" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /Z7 /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /W3 /GX /Z7 /Od /I "../../include" /D "_DEBUG" /D "WIN32" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x40c /d "_DEBUG" +# ADD RSC /l 0x40c /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo + +!ENDIF + +# Begin Target + +# Name "mbedtls - Win32 Release" +# Name "mbedtls - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +SOURCE_ENTRIES +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +HEADER_ENTRIES +# End Group +# End Target +# End Project diff --git a/contrib/mbedtls/scripts/data_files/vs6-workspace-template.dsw b/contrib/mbedtls/scripts/data_files/vs6-workspace-template.dsw index ef90098f..9b2e262d 100644 --- a/contrib/mbedtls/scripts/data_files/vs6-workspace-template.dsw +++ b/contrib/mbedtls/scripts/data_files/vs6-workspace-template.dsw @@ -1,18 +1,18 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -APP_ENTRIES -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +APP_ENTRIES +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/contrib/mbedtls/scripts/windows_msbuild.bat b/contrib/mbedtls/scripts/windows_msbuild.bat index e4199310..cfb5f013 100644 --- a/contrib/mbedtls/scripts/windows_msbuild.bat +++ b/contrib/mbedtls/scripts/windows_msbuild.bat @@ -1,20 +1,20 @@ -@rem Build and test Mbed TLS with Visual Studio using msbuild. -@rem Usage: windows_msbuild [RETARGET] -@rem RETARGET: version of Visual Studio to emulate -@rem https://docs.microsoft.com/en-us/cpp/build/how-to-modify-the-target-framework-and-platform-toolset - -@rem These parameters are hard-coded for now. -set "arch=x64" & @rem "x86" or "x64" -set "cfg=Release" & @rem "Debug" or "Release" -set "vcvarsall=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" - -if not "%~1"=="" set "retarget=,PlatformToolset=%1" - -@rem If the %USERPROFILE%\Source directory exists, then running -@rem vcvarsall.bat will silently change the directory to that directory. -@rem Setting the VSCMD_START_DIR environment variable causes it to change -@rem to that directory instead. -set "VSCMD_START_DIR=%~dp0\..\visualc\VS2010" - -"%vcvarsall%" x64 && ^ -msbuild /t:Rebuild /p:Configuration=%cfg%%retarget% /m mbedTLS.sln +@rem Build and test Mbed TLS with Visual Studio using msbuild. +@rem Usage: windows_msbuild [RETARGET] +@rem RETARGET: version of Visual Studio to emulate +@rem https://docs.microsoft.com/en-us/cpp/build/how-to-modify-the-target-framework-and-platform-toolset + +@rem These parameters are hard-coded for now. +set "arch=x64" & @rem "x86" or "x64" +set "cfg=Release" & @rem "Debug" or "Release" +set "vcvarsall=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" + +if not "%~1"=="" set "retarget=,PlatformToolset=%1" + +@rem If the %USERPROFILE%\Source directory exists, then running +@rem vcvarsall.bat will silently change the directory to that directory. +@rem Setting the VSCMD_START_DIR environment variable causes it to change +@rem to that directory instead. +set "VSCMD_START_DIR=%~dp0\..\visualc\VS2010" + +"%vcvarsall%" x64 && ^ +msbuild /t:Rebuild /p:Configuration=%cfg%%retarget% /m mbedTLS.sln diff --git a/modules/vstudio/tests/vc2010/test_compile_settings.lua b/modules/vstudio/tests/vc2010/test_compile_settings.lua index 808db07b..4f13aa04 100644 --- a/modules/vstudio/tests/vc2010/test_compile_settings.lua +++ b/modules/vstudio/tests/vc2010/test_compile_settings.lua @@ -1180,8 +1180,8 @@ ]] end - function suite.onCompileAsCppModule() - compileas 'Module' + function suite.onCompileAsCppModule() + compileas 'Module' prepare() test.capture [[ @@ -1193,8 +1193,8 @@ ]] end - function suite.onCompileAsCppModulePartition() - compileas 'ModulePartition' + function suite.onCompileAsCppModulePartition() + compileas 'ModulePartition' prepare() test.capture [[ @@ -1207,7 +1207,7 @@ end function suite.onCompileAsCppHeaderUnit() - compileas 'HeaderUnit' + compileas 'HeaderUnit' prepare() test.capture [[ diff --git a/modules/vstudio/vs2010_vcxproj.lua b/modules/vstudio/vs2010_vcxproj.lua index 58e5676e..f390b706 100644 --- a/modules/vstudio/vs2010_vcxproj.lua +++ b/modules/vstudio/vs2010_vcxproj.lua @@ -1699,11 +1699,11 @@ m.element("CompileAs", condition, "CompileAsC") elseif p.languages.iscpp(cfg.compileas) then m.element("CompileAs", condition, "CompileAsCpp") - elseif cfg.compileas == "Module" then + elseif cfg.compileas == "Module" then m.element("CompileAs", condition, "CompileAsCppModule") - elseif cfg.compileas == "ModulePartition" then + elseif cfg.compileas == "ModulePartition" then m.element("CompileAs", condition, "CompileAsCppModuleInternalPartition") - elseif cfg.compileas == "HeaderUnit" then + elseif cfg.compileas == "HeaderUnit" then m.element("CompileAs", condition, "CompileAsHeaderUnit") end end diff --git a/modules/xcode/tests/test_xcode4_workspace.lua b/modules/xcode/tests/test_xcode4_workspace.lua index 795f1e6c..702a3359 100644 --- a/modules/xcode/tests/test_xcode4_workspace.lua +++ b/modules/xcode/tests/test_xcode4_workspace.lua @@ -1,133 +1,133 @@ ---- --- xcode/tests/test_xcode4_workspace.lua --- Validate generation for Xcode workspaces. --- Author Mihai Sebea --- Modified by Jason Perkins --- Copyright (c) 2014-2015 Jason Perkins and the Premake project ---- - - local suite = test.declare("xcode4_workspace") - local p = premake - local xcode = p.modules.xcode - - --- --- Setup --- - - local wks, prj - - function suite.setup() - _TARGET_OS = "macosx" - p.action.set('xcode4') - wks = test.createWorkspace() - end - - local function prepare() - wks = test.getWorkspace(wks) - xcode.generateWorkspace(wks) - end - - --- --- Check the basic structure of a workspace. --- - - function suite.onEmptyWorkspace() - wks.projects = {} - prepare() - test.capture [[ - - - - ]] - end - - - function suite.onDefaultWorkspace() - prepare() - test.capture [[ - - - - - - ]] - end - - - function suite.onMultipleProjects() - test.createproject(wks) - prepare() - test.capture [[ - - - - - - - - ]] - end - - function suite.onMultipleProjectsGrouped() - test.createGroup(wks) - test.createproject(wks) - prepare() - test.capture [[ - - - - - - - - - - ]] - end - - - --- --- Projects should include relative path from workspace. --- - - function suite.onNestedProjectPath() - location "MyProject" - prepare() - test.capture [[ - - - - - - ]] - end - - function suite.onExternalProjectPath() - location "../MyProject" - prepare() - test.capture [[ - - - - - - ]] - end +--- +-- xcode/tests/test_xcode4_workspace.lua +-- Validate generation for Xcode workspaces. +-- Author Mihai Sebea +-- Modified by Jason Perkins +-- Copyright (c) 2014-2015 Jason Perkins and the Premake project +--- + + local suite = test.declare("xcode4_workspace") + local p = premake + local xcode = p.modules.xcode + + +-- +-- Setup +-- + + local wks, prj + + function suite.setup() + _TARGET_OS = "macosx" + p.action.set('xcode4') + wks = test.createWorkspace() + end + + local function prepare() + wks = test.getWorkspace(wks) + xcode.generateWorkspace(wks) + end + + +-- +-- Check the basic structure of a workspace. +-- + + function suite.onEmptyWorkspace() + wks.projects = {} + prepare() + test.capture [[ + + + + ]] + end + + + function suite.onDefaultWorkspace() + prepare() + test.capture [[ + + + + + + ]] + end + + + function suite.onMultipleProjects() + test.createproject(wks) + prepare() + test.capture [[ + + + + + + + + ]] + end + + function suite.onMultipleProjectsGrouped() + test.createGroup(wks) + test.createproject(wks) + prepare() + test.capture [[ + + + + + + + + + + ]] + end + + + +-- +-- Projects should include relative path from workspace. +-- + + function suite.onNestedProjectPath() + location "MyProject" + prepare() + test.capture [[ + + + + + + ]] + end + + function suite.onExternalProjectPath() + location "../MyProject" + prepare() + test.capture [[ + + + + + + ]] + end diff --git a/modules/xcode/xcode_project.lua b/modules/xcode/xcode_project.lua index 4612f880..5cb445df 100644 --- a/modules/xcode/xcode_project.lua +++ b/modules/xcode/xcode_project.lua @@ -1,268 +1,268 @@ ---- --- xcode/xcode4_project.lua --- Generate an Xcode project file. --- Author Jason Perkins --- Modified by Mihai Sebea --- Copyright (c) 2009-2015 Jason Perkins and the Premake project ---- - - local p = premake - local m = p.modules.xcode - - local xcode = p.modules.xcode - local project = p.project - local config = p.config - local fileconfig = p.fileconfig - local tree = p.tree - --- --- Checks if a node must be excluded completely from a target or not. It will --- return true only if the node has the "ExcludeFromBuild" flag in all the --- configurations. --- --- @param node --- The node to check. --- @param prj --- The project being generated. --- @returns --- A boolean, telling whether the node must be excluded from its target or not. --- - function xcode.mustExcludeFromTarget(node, prj) - if not node.configs then - return false - end - - local value - for cfg in premake.project.eachconfig(prj) do - local filecfg = premake.fileconfig.getconfig(node, cfg) - if filecfg then - local newValue = not not filecfg.flags.ExcludeFromBuild - if value == nil then - value = newValue - elseif value ~= newValue then - p.warn(node.name .. " is excluded in just some configurations. Autocompletion will not work correctly on this file in Xcode.") - return false - end - end - end - return value - end - --- --- Create a tree corresponding to what is shown in the Xcode project browser --- pane, with nodes for files and folders, resources, frameworks, and products. --- --- @param prj --- The project being generated. --- @returns --- A tree, loaded with metadata, which mirrors Xcode's view of the project. --- - - function xcode.buildprjtree(prj) - local tr = project.getsourcetree(prj, nil , false) - tr.project = prj - - -- create a list of build configurations and assign IDs - tr.configs = {} - - for cfg in project.eachconfig(prj) do - cfg.xcode = {} - cfg.xcode.targetid = xcode.newid(prj.xcode.projectnode.name, cfg.buildcfg, "target") - cfg.xcode.projectid = xcode.newid(tr.name, cfg.buildcfg) - table.insert(tr.configs, cfg) - end - - -- convert localized resources from their filesystem layout (English.lproj/MainMenu.xib) - -- to Xcode's display layout (MainMenu.xib/English). - tree.traverse(tr, { - onbranch = function(node) - if path.getextension(node.name) == ".lproj" then - local lang = path.getbasename(node.name) -- "English", "French", etc. - - -- create a new language group for each file it contains - for _, filenode in ipairs(node.children) do - local grpnode = node.parent.children[filenode.name] - if not grpnode then - grpnode = tree.insert(node.parent, tree.new(filenode.name)) - grpnode.kind = "vgroup" - end - - -- convert the file node to a language node and add to the group - filenode.name = path.getbasename(lang) - tree.insert(grpnode, filenode) - end - - -- remove this directory from the tree - tree.remove(node) - end - end - }) - - -- the special folder "Frameworks" lists all linked frameworks - tr.frameworks = tree.new("Frameworks") - for cfg in project.eachconfig(prj) do - for _, link in ipairs(config.getlinks(cfg, "system", "fullpath")) do - local name = path.getname(link) - if xcode.isframeworkordylib(name) and not tr.frameworks.children[name] then - node = tree.insert(tr.frameworks, tree.new(name)) - node.path = link - end - end - end - - -- only add it to the tree if there are frameworks to link - if #tr.frameworks.children > 0 then - tree.insert(tr, tr.frameworks) - end - - -- the special folder "Products" holds the target produced by the project; this - -- is populated below - tr.products = tree.insert(tr, tree.new("Products")) - - -- the special folder "Projects" lists sibling project dependencies - tr.projects = tree.new("Projects") - for _, dep in ipairs(project.getdependencies(prj, "linkOnly")) do - xcode.addDependency(prj, tr, dep, true) - end - for _, dep in ipairs(project.getdependencies(prj, "dependOnly")) do - xcode.addDependency(prj, tr, dep, false) - end - - if #tr.projects.children > 0 then - tree.insert(tr, tr.projects) - end - - -- Final setup - tree.traverse(tr, { - onnode = function(node) - local nodePath - if node.path then - nodePath = path.getrelative(tr.project.location, node.path) - end - -- assign IDs to every node in the tree - node.id = xcode.newid(node.name, nil, nodePath) - - node.isResource = xcode.isItemResource(prj, node) - - -- check to see if this file has custom build - if node.configs then - for cfg in project.eachconfig(prj) do - local filecfg = fileconfig.getconfig(node, cfg) - if fileconfig.hasCustomBuildRule(filecfg) then - if not node.buildcommandid then - node.buildcommandid = xcode.newid(node.name, "buildcommand", nodePath) - end - end - end - end - - -- assign build IDs to buildable files - if xcode.getbuildcategory(node) and not node.excludefrombuild and not xcode.mustExcludeFromTarget(node, tr.project) then - node.buildid = xcode.newid(node.name, "build", nodePath) - - if xcode.shouldembed(tr, node) then - node.embedid = xcode.newid(node.name, "embed", nodepath) - end - end - - -- remember key files that are needed elsewhere - if string.endswith(node.name, "Info.plist") then - tr.infoplist = node - end - end - }, true) - - -- Plug in the product node into the Products folder in the tree. The node - -- was built in xcode.prepareWorkspace() in xcode_common.lua; it contains IDs - -- that are necessary for inter-project dependencies - node = tree.insert(tr.products, prj.xcode.projectnode) - node.kind = "product" - node.path = node.cfg.buildtarget.fullpath - node.cfgsection = xcode.newid(node.name, "cfg") - node.resstageid = xcode.newid(node.name, "rez") - node.sourcesid = xcode.newid(node.name, "src") - node.fxstageid = xcode.newid(node.name, "fxs") - node.embedstageid = xcode.newid(node.name, "embed") - - return tr - end - - function xcode.addDependency(prj, tr, dep, build) - -- create a child node for the dependency's xcodeproj - local xcpath = xcode.getxcodeprojname(dep) - local xcnode = tree.insert(tr.projects, tree.new(path.getname(xcpath))) - xcnode.path = xcpath - xcnode.project = dep - xcnode.productgroupid = xcode.newid(xcnode.name, "prodgrp") - xcnode.productproxyid = xcode.newid(xcnode.name, "prodprox") - xcnode.targetproxyid = xcode.newid(xcnode.name, "targprox") - xcnode.targetdependid = xcode.newid(xcnode.name, "targdep") - - -- create a grandchild node for the dependency's link target - local lprj = p.workspace.findproject(prj.workspace, dep.name) - local cfg = project.findClosestMatch(lprj, prj.configurations[1]) - node = tree.insert(xcnode, tree.new(cfg.linktarget.name)) - node.path = cfg.linktarget.fullpath - node.cfg = cfg - - -- don't link the dependency if it's a dependency only - if build == false then - node.excludefrombuild = true - end - end - - ---- --- Generate an Xcode .xcodeproj for a Premake project. ---- - - m.elements.project = function(prj) - return { - m.header, - } - end - - function m.generateProject(prj) - local tr = xcode.buildprjtree(prj) - p.callArray(m.elements.project, prj) - xcode.PBXBuildFile(tr) - xcode.PBXContainerItemProxy(tr) - xcode.PBXFileReference(tr) - xcode.PBXFrameworksBuildPhase(tr) - xcode.PBXCopyFilesBuildPhaseForEmbedFrameworks(tr) - xcode.PBXGroup(tr) - xcode.PBXNativeTarget(tr) - xcode.PBXAggregateTarget(tr) - xcode.PBXProject(tr) - xcode.PBXReferenceProxy(tr) - xcode.PBXResourcesBuildPhase(tr) - xcode.PBXShellScriptBuildPhase(tr) - xcode.PBXSourcesBuildPhase(tr) - xcode.PBXTargetDependency(tr) - xcode.PBXVariantGroup(tr) - xcode.XCBuildConfiguration(tr) - xcode.XCBuildConfigurationList(tr) - xcode.footer(prj) - end - - - - function m.header(prj) - p.w('// !$*UTF8*$!') - p.push('{') - p.w('archiveVersion = 1;') - p.w('classes = {') - p.w('};') - p.w('objectVersion = 46;') - p.push('objects = {') - p.w() - end - - - - function xcode.footer(prj) - p.pop('};') - p.w('rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;') - p.pop('}') - end - +--- +-- xcode/xcode4_project.lua +-- Generate an Xcode project file. +-- Author Jason Perkins +-- Modified by Mihai Sebea +-- Copyright (c) 2009-2015 Jason Perkins and the Premake project +--- + + local p = premake + local m = p.modules.xcode + + local xcode = p.modules.xcode + local project = p.project + local config = p.config + local fileconfig = p.fileconfig + local tree = p.tree + +-- +-- Checks if a node must be excluded completely from a target or not. It will +-- return true only if the node has the "ExcludeFromBuild" flag in all the +-- configurations. +-- +-- @param node +-- The node to check. +-- @param prj +-- The project being generated. +-- @returns +-- A boolean, telling whether the node must be excluded from its target or not. +-- + function xcode.mustExcludeFromTarget(node, prj) + if not node.configs then + return false + end + + local value + for cfg in premake.project.eachconfig(prj) do + local filecfg = premake.fileconfig.getconfig(node, cfg) + if filecfg then + local newValue = not not filecfg.flags.ExcludeFromBuild + if value == nil then + value = newValue + elseif value ~= newValue then + p.warn(node.name .. " is excluded in just some configurations. Autocompletion will not work correctly on this file in Xcode.") + return false + end + end + end + return value + end + +-- +-- Create a tree corresponding to what is shown in the Xcode project browser +-- pane, with nodes for files and folders, resources, frameworks, and products. +-- +-- @param prj +-- The project being generated. +-- @returns +-- A tree, loaded with metadata, which mirrors Xcode's view of the project. +-- + + function xcode.buildprjtree(prj) + local tr = project.getsourcetree(prj, nil , false) + tr.project = prj + + -- create a list of build configurations and assign IDs + tr.configs = {} + + for cfg in project.eachconfig(prj) do + cfg.xcode = {} + cfg.xcode.targetid = xcode.newid(prj.xcode.projectnode.name, cfg.buildcfg, "target") + cfg.xcode.projectid = xcode.newid(tr.name, cfg.buildcfg) + table.insert(tr.configs, cfg) + end + + -- convert localized resources from their filesystem layout (English.lproj/MainMenu.xib) + -- to Xcode's display layout (MainMenu.xib/English). + tree.traverse(tr, { + onbranch = function(node) + if path.getextension(node.name) == ".lproj" then + local lang = path.getbasename(node.name) -- "English", "French", etc. + + -- create a new language group for each file it contains + for _, filenode in ipairs(node.children) do + local grpnode = node.parent.children[filenode.name] + if not grpnode then + grpnode = tree.insert(node.parent, tree.new(filenode.name)) + grpnode.kind = "vgroup" + end + + -- convert the file node to a language node and add to the group + filenode.name = path.getbasename(lang) + tree.insert(grpnode, filenode) + end + + -- remove this directory from the tree + tree.remove(node) + end + end + }) + + -- the special folder "Frameworks" lists all linked frameworks + tr.frameworks = tree.new("Frameworks") + for cfg in project.eachconfig(prj) do + for _, link in ipairs(config.getlinks(cfg, "system", "fullpath")) do + local name = path.getname(link) + if xcode.isframeworkordylib(name) and not tr.frameworks.children[name] then + node = tree.insert(tr.frameworks, tree.new(name)) + node.path = link + end + end + end + + -- only add it to the tree if there are frameworks to link + if #tr.frameworks.children > 0 then + tree.insert(tr, tr.frameworks) + end + + -- the special folder "Products" holds the target produced by the project; this + -- is populated below + tr.products = tree.insert(tr, tree.new("Products")) + + -- the special folder "Projects" lists sibling project dependencies + tr.projects = tree.new("Projects") + for _, dep in ipairs(project.getdependencies(prj, "linkOnly")) do + xcode.addDependency(prj, tr, dep, true) + end + for _, dep in ipairs(project.getdependencies(prj, "dependOnly")) do + xcode.addDependency(prj, tr, dep, false) + end + + if #tr.projects.children > 0 then + tree.insert(tr, tr.projects) + end + + -- Final setup + tree.traverse(tr, { + onnode = function(node) + local nodePath + if node.path then + nodePath = path.getrelative(tr.project.location, node.path) + end + -- assign IDs to every node in the tree + node.id = xcode.newid(node.name, nil, nodePath) + + node.isResource = xcode.isItemResource(prj, node) + + -- check to see if this file has custom build + if node.configs then + for cfg in project.eachconfig(prj) do + local filecfg = fileconfig.getconfig(node, cfg) + if fileconfig.hasCustomBuildRule(filecfg) then + if not node.buildcommandid then + node.buildcommandid = xcode.newid(node.name, "buildcommand", nodePath) + end + end + end + end + + -- assign build IDs to buildable files + if xcode.getbuildcategory(node) and not node.excludefrombuild and not xcode.mustExcludeFromTarget(node, tr.project) then + node.buildid = xcode.newid(node.name, "build", nodePath) + + if xcode.shouldembed(tr, node) then + node.embedid = xcode.newid(node.name, "embed", nodepath) + end + end + + -- remember key files that are needed elsewhere + if string.endswith(node.name, "Info.plist") then + tr.infoplist = node + end + end + }, true) + + -- Plug in the product node into the Products folder in the tree. The node + -- was built in xcode.prepareWorkspace() in xcode_common.lua; it contains IDs + -- that are necessary for inter-project dependencies + node = tree.insert(tr.products, prj.xcode.projectnode) + node.kind = "product" + node.path = node.cfg.buildtarget.fullpath + node.cfgsection = xcode.newid(node.name, "cfg") + node.resstageid = xcode.newid(node.name, "rez") + node.sourcesid = xcode.newid(node.name, "src") + node.fxstageid = xcode.newid(node.name, "fxs") + node.embedstageid = xcode.newid(node.name, "embed") + + return tr + end + + function xcode.addDependency(prj, tr, dep, build) + -- create a child node for the dependency's xcodeproj + local xcpath = xcode.getxcodeprojname(dep) + local xcnode = tree.insert(tr.projects, tree.new(path.getname(xcpath))) + xcnode.path = xcpath + xcnode.project = dep + xcnode.productgroupid = xcode.newid(xcnode.name, "prodgrp") + xcnode.productproxyid = xcode.newid(xcnode.name, "prodprox") + xcnode.targetproxyid = xcode.newid(xcnode.name, "targprox") + xcnode.targetdependid = xcode.newid(xcnode.name, "targdep") + + -- create a grandchild node for the dependency's link target + local lprj = p.workspace.findproject(prj.workspace, dep.name) + local cfg = project.findClosestMatch(lprj, prj.configurations[1]) + node = tree.insert(xcnode, tree.new(cfg.linktarget.name)) + node.path = cfg.linktarget.fullpath + node.cfg = cfg + + -- don't link the dependency if it's a dependency only + if build == false then + node.excludefrombuild = true + end + end + + +--- +-- Generate an Xcode .xcodeproj for a Premake project. +--- + + m.elements.project = function(prj) + return { + m.header, + } + end + + function m.generateProject(prj) + local tr = xcode.buildprjtree(prj) + p.callArray(m.elements.project, prj) + xcode.PBXBuildFile(tr) + xcode.PBXContainerItemProxy(tr) + xcode.PBXFileReference(tr) + xcode.PBXFrameworksBuildPhase(tr) + xcode.PBXCopyFilesBuildPhaseForEmbedFrameworks(tr) + xcode.PBXGroup(tr) + xcode.PBXNativeTarget(tr) + xcode.PBXAggregateTarget(tr) + xcode.PBXProject(tr) + xcode.PBXReferenceProxy(tr) + xcode.PBXResourcesBuildPhase(tr) + xcode.PBXShellScriptBuildPhase(tr) + xcode.PBXSourcesBuildPhase(tr) + xcode.PBXTargetDependency(tr) + xcode.PBXVariantGroup(tr) + xcode.XCBuildConfiguration(tr) + xcode.XCBuildConfigurationList(tr) + xcode.footer(prj) + end + + + + function m.header(prj) + p.w('// !$*UTF8*$!') + p.push('{') + p.w('archiveVersion = 1;') + p.w('classes = {') + p.w('};') + p.w('objectVersion = 46;') + p.push('objects = {') + p.w() + end + + + + function xcode.footer(prj) + p.pop('};') + p.w('rootObject = 08FB7793FE84155DC02AAC07 /* Project object */;') + p.pop('}') + end + diff --git a/src/_premake_init.lua b/src/_premake_init.lua index 344969ba..380b5424 100644 --- a/src/_premake_init.lua +++ b/src/_premake_init.lua @@ -185,9 +185,9 @@ "C++", "Objective-C", "Objective-C++", - "Module", - "ModulePartition", - "HeaderUnit" + "Module", + "ModulePartition", + "HeaderUnit" } } diff --git a/src/base/os.lua b/src/base/os.lua index c3308b9b..94a41bbd 100644 --- a/src/base/os.lua +++ b/src/base/os.lua @@ -1,793 +1,793 @@ --- --- os.lua --- Additions to the OS namespace. --- Copyright (c) 2002-2014 Jason Perkins and the Premake project --- - - ---- --- Extend Lua's built-in os.execute() with token expansion and --- path normalization. --- - - premake.override(os, "execute", function(base, cmd) - cmd = os.translateCommands(cmd) - return base(cmd) - end) - - - ---- --- Same as os.execute(), but accepts string formatting arguments. ---- - - function os.executef(cmd, ...) - cmd = string.format(cmd, ...) - return os.execute(cmd) - end - - - --- --- Scan the well-known system locations for a particular library. --- - - local function parse_ld_so_conf(conf_file) - -- Linux ldconfig file parser to find system library locations - local first, last - local dirs = { } - for line in io.lines(conf_file) do - -- ignore comments - first = line:find("#", 1, true) - if first ~= nil then - line = line:sub(1, first - 1) - end - - if line ~= "" then - -- check for include files - first, last = line:find("include%s+") - if first ~= nil then - -- found include glob - local include_glob = line:sub(last + 1) - local includes = os.matchfiles(include_glob) - for _, v in ipairs(includes) do - dirs = table.join(dirs, parse_ld_so_conf(v)) - end - else - -- found an actual ld path entry - table.insert(dirs, line) - end - end - end - return dirs - end - - local function get_library_search_path() - local path - if os.istarget("windows") then - path = os.getenv("PATH") or "" - elseif os.istarget("haiku") then - path = os.getenv("LIBRARY_PATH") or "" - else - if os.istarget("darwin") then - path = os.getenv("DYLD_LIBRARY_PATH") or "" - else - path = os.getenv("LD_LIBRARY_PATH") or "" - - for _, prefix in ipairs({"", "/opt"}) do - local conf_file = prefix .. "/etc/ld.so.conf" - if os.isfile(conf_file) then - for _, v in ipairs(parse_ld_so_conf(conf_file)) do - if (#path > 0) then - path = path .. ":" .. v - else - path = v - end - end - end - end - end - - path = path or "" - local archpath = "/lib:/usr/lib:/usr/local/lib" - if os.is64bit() and not (os.istarget("darwin")) then - archpath = "/lib64:/usr/lib64/:usr/local/lib64" .. ":" .. archpath - end - if (#path > 0) then - path = path .. ":" .. archpath - else - path = archpath - end - end - - return path - end - - function os.findlib(libname, libdirs) - -- libname: library name with or without prefix and suffix - -- libdirs: (array or string): A set of additional search paths - - local path = get_library_search_path() - local formats - - -- assemble a search path, depending on the platform - if os.istarget("windows") then - formats = { "%s.dll", "%s" } - elseif os.istarget("haiku") then - formats = { "lib%s.so", "%s.so" } - else - if os.istarget("darwin") then - formats = { "lib%s.dylib", "%s.dylib" } - else - formats = { "lib%s.so", "%s.so" } - end - - table.insert(formats, "%s") - end - - local userpath = "" - - if type(libdirs) == "string" then - userpath = libdirs - elseif type(libdirs) == "table" then - userpath = table.implode(libdirs, "", "", ":") - end - - if (#userpath > 0) then - if (#path > 0) then - path = userpath .. ":" .. path - else - path = userpath - end - end - - for _, fmt in ipairs(formats) do - local name = string.format(fmt, libname) - local result = os.pathsearch(name, path) - if result then return result end - end - end - - function os.findheader(headerpath, headerdirs) - -- headerpath: a partial header file path - -- headerdirs: additional header search paths - - local path = get_library_search_path() - - -- replace all /lib by /include - path = path .. ':' - path = path:gsub ('/lib[0-9]*([:/])', '/include%1') - path = path:sub (1, #path - 1) - - local userpath = "" - - if type(headerdirs) == "string" then - userpath = headerdirs - elseif type(headerdirs) == "table" then - userpath = table.implode(headerdirs, "", "", ":") - end - - if (#userpath > 0) then - if (#path > 0) then - path = userpath .. ":" .. path - else - path = userpath - end - end - - local result = os.pathsearch (headerpath, path) - return result - end - --- --- Retrieve the current target operating system ID string. --- - - function os.target() - return _OPTIONS.os or _TARGET_OS - end - - function os.get() - local caller = filelineinfo(2) - premake.warnOnce(caller, "os.get() is deprecated, use 'os.target()' or 'os.host()'.\n @%s\n", caller) - return os.target() - end - - -- deprecate _OS - _G_metatable = { - __index = function(t, k) - if (k == '_OS') then - premake.warnOnce("_OS+get", "_OS is deprecated, use '_TARGET_OS'.") - return rawget(t, "_TARGET_OS") - else - return rawget(t, k) - end - end, - - __newindex = function(t, k, v) - if (k == '_OS') then - premake.warnOnce("_OS+set", "_OS is deprecated, use '_TARGET_OS'.") - rawset(t, "_TARGET_OS", v) - else - rawset(t, k, v) - end - end - } - setmetatable(_G, _G_metatable) - - - --- --- Check the current target operating system; may be set with the /os command line flag. --- - - function os.istarget(id) - local tags = os.getSystemTags(os.target()) - return table.contains(tags, id:lower()) - end - - function os.is(id) - local caller = filelineinfo(2) - premake.warnOnce(caller, "os.is() is deprecated, use 'os.istarget()' or 'os.ishost()'.\n @%s\n", caller) - return os.istarget(id) - end - - --- --- Check the current host operating system. --- - - function os.ishost(id) - local tags = os.getSystemTags(os.host()) - return table.contains(tags, id:lower()) - end - - ---- --- Determine if a directory exists on the file system, and that it is a --- directory and not a file. --- --- @param p --- The path to check. --- @return --- True if a directory exists at the given path. ---- - - premake.override(os, "isdir", function(base, p) - p = path.normalize(p) - return base(p) - end) - - - ---- --- Determine if a file exists on the file system, and that it is a --- file and not a directory. --- --- @param p --- The path to check. --- @return --- True if a file exists at the given path. ---- - - premake.override(os, "isfile", function(base, p) - p = path.normalize(p) - return base(p) - end) - - - --- --- Determine if the current system is running a 64-bit architecture. --- - - local _is64bit - - local _64BitHostTypes = { - "x86_64", - "ia64", - "amd64", - "ppc64", - "powerpc64", - "sparc64" - } - - function os.is64bit() - -- This can be expensive to compute, so cache and reuse the response - if _is64bit ~= nil then - return _is64bit - end - - _is64bit = false - - -- Call the native code implementation. If this returns true then - -- we're 64-bit, otherwise do more checking locally - if (os._is64bit()) then - _is64bit = true - else - -- Identify the system - local arch - if os.ishost("windows") then - arch = os.getenv("PROCESSOR_ARCHITECTURE") - elseif os.ishost("macosx") then - arch = os.outputof("echo $HOSTTYPE") - else - arch = os.outputof("uname -m") - end - - -- Check our known 64-bit identifiers - arch = arch:lower() - for _, hosttype in ipairs(_64BitHostTypes) do - if arch:find(hosttype) then - _is64bit = true - end - end - end - - return _is64bit - end - - ---- --- Perform a wildcard search for files and directories. --- --- @param mask --- The file search pattern. Use "*" to match any part of a file or --- directory name, "**" to recurse into subdirectories. --- @return --- A table containing the matched file or directory names. ---- - - function os.match(mask) - mask = path.normalize(mask) - local starpos = mask:find("%*") - local before = path.getdirectory(starpos and mask:sub(1, starpos - 1) or mask) - local slashpos = starpos and mask:find("/", starpos) - local after = slashpos and mask:sub(slashpos + 1) - - -- Only recurse for path components starting with '**': - local recurse = starpos and - mask:sub(starpos + 1, starpos + 1) == '*' and - (starpos == 1 or mask:sub(starpos - 1, starpos - 1) == '/') - - local results = { } - - if recurse then - local submask = mask:sub(1, starpos) .. mask:sub(starpos + 2) - results = os.match(submask) - - local pattern = mask:sub(1, starpos) - local m = os.matchstart(pattern) - while os.matchnext(m) do - if not os.matchisfile(m) then - local matchpath = path.join(before, os.matchname(m), mask:sub(starpos)) - results = table.join(results, os.match(matchpath)) - end - end - os.matchdone(m) - else - local pattern = mask:sub(1, slashpos and slashpos - 1) - local m = os.matchstart(pattern) - while os.matchnext(m) do - if not (slashpos and os.matchisfile(m)) then - local matchpath = path.join(before, matchpath, os.matchname(m)) - if after then - results = table.join(results, os.match(path.join(matchpath, after))) - else - table.insert(results, matchpath) - end - end - end - os.matchdone(m) - end - - return results - end - - ---- --- Perform a wildcard search for directories. --- --- @param mask --- The search pattern. Use "*" to match any part of a directory --- name, "**" to recurse into subdirectories. --- @return --- A table containing the matched directory names. ---- - - function os.matchdirs(mask) - local results = os.match(mask) - for i = #results, 1, -1 do - if not os.isdir(results[i]) then - table.remove(results, i) - end - end - return results - end - - ---- --- Perform a wildcard search for files. --- --- @param mask --- The search pattern. Use "*" to match any part of a file --- name, "**" to recurse into subdirectories. --- @return --- A table containing the matched directory names. ---- - - function os.matchfiles(mask) - local results = os.match(mask) - for i = #results, 1, -1 do - if not os.isfile(results[i]) then - table.remove(results, i) - end - end - return results - end - --- --- An overload of the os.mkdir() function, which will create any missing --- subdirectories along the path. --- - - local builtin_mkdir = os.mkdir - function os.mkdir(p) - p = path.normalize(p) - - local dir = iif(p:startswith("/"), "/", "") - for part in p:gmatch("[^/]+") do - dir = dir .. part - - if (part ~= "" and not path.isabsolute(part) and not os.isdir(dir)) then - local ok, err = builtin_mkdir(dir) - if (not ok) then - return nil, err - end - end - - dir = dir .. "/" - end - - return true - end - - --- --- Run a shell command and return the output. --- --- @param cmd Command to execute --- @param streams Standard stream(s) to output --- Must be one of --- - "both" (default) --- - "output" Return standard output stream content only --- - "error" Return standard error stream content only --- - - function os.outputof(cmd, streams) - cmd = path.normalize(cmd) - streams = streams or "both" - local redirection - if streams == "both" then - redirection = " 2>&1" - elseif streams == "output" then - redirection = " 2>/dev/null" - elseif streams == "error" then - redirection = " 2>&1 1>/dev/null" - else - error ('Invalid stream(s) selection. "output", "error", or "both" expected.') - end - - local pipe = io.popen(cmd .. redirection) - local result = pipe:read('*a') - local success, what, code = pipe:close() - if success then - -- chomp trailing newlines - if result then - result = string.gsub(result, "[\r\n]+$", "") - end - - return result, code, what - else - return nil, code, what - end - end - - --- --- @brief An overloaded os.remove() that will be able to handle list of files, --- as well as wildcards for files. Uses the syntax os.matchfiles() for --- matching pattern wildcards. --- --- @param f A file, a wildcard, or a list of files or wildcards to be removed --- --- @return true on success, false and an appropriate error message on error --- --- @example ok, err = os.remove{"**.bak", "**.log"} --- if not ok then --- error(err) --- end --- - - local builtin_remove = os.remove - function os.remove(f) - -- in case of string, just match files - if type(f) == "string" then - local p = os.matchfiles(f) - for _, v in pairs(p) do - local ok, err, code = builtin_remove(v) - if not ok then - return ok, err, code - end - end - if #p == 0 then - return nil, "Couldn't find any file matching: " .. f, 1 - end - -- in case of table, match files for every table entry - elseif type(f) == "table" then - for _, v in pairs(f) do - local ok, err, code = os.remove(v) - if not ok then - return ok, err, code - end - end - end - - return true - end - - --- --- Remove a directory, along with any contained files or subdirectories. --- --- @return true on success, false and an appropriate error message on error - - local builtin_rmdir = os.rmdir - function os.rmdir(p) - -- recursively remove subdirectories - local dirs = os.matchdirs(p .. "/*") - for _, dname in ipairs(dirs) do - local ok, err = os.rmdir(dname) - if not ok then - return ok, err - end - end - - -- remove any files - local files = os.matchfiles(p .. "/*") - for _, fname in ipairs(files) do - local ok, err = os.remove(fname) - if not ok then - return ok, err - end - end - - -- remove this directory - return builtin_rmdir(p) - end - - ---- --- Return information about a file. ---- - - premake.override(os, "stat", function(base, p) - p = path.normalize(p) - return base(p) - end) - - - ---- --- Translate command tokens into their OS or action specific equivalents. ---- - - os.commandTokens = { - _ = { - chdir = function(v) - return "cd " .. path.normalize(v) - end, - copy = function(v) - return "cp -rf " .. path.normalize(v) - end, - copyfile = function(v) - return "cp -f " .. path.normalize(v) - end, - copydir = function(v) - return "cp -rf " .. path.normalize(v) - end, - delete = function(v) - return "rm -f " .. path.normalize(v) - end, - echo = function(v) - return "echo " .. v - end, - mkdir = function(v) - return "mkdir -p " .. path.normalize(v) - end, - move = function(v) - return "mv -f " .. path.normalize(v) - end, - rmdir = function(v) - return "rm -rf " .. path.normalize(v) - end, - touch = function(v) - return "touch " .. path.normalize(v) - end, - }, - windows = { - chdir = function(v) - return "chdir " .. path.translate(path.normalize(v)) - end, - copy = function(v) - v = path.translate(path.normalize(v)) - - -- Detect if there's multiple parts to the input, if there is grab the first part else grab the whole thing - local src = string.match(v, '^".-"') or string.match(v, '^.- ') or v - - -- Strip the trailing space from the second condition so that we don't have a space between src and '\\NUL' - src = string.match(src, '^.*%S') - - return "IF EXIST " .. src .. "\\ (xcopy /Q /E /Y /I " .. v .. " > nul) ELSE (xcopy /Q /Y /I " .. v .. " > nul)" - end, - copyfile = function(v) - v = path.translate(path.normalize(v)) - -- XCOPY doesn't have a switch to assume destination is a file when it doesn't exist. - -- A trailing * will suppress the prompt but requires the file extensions be the same length. - -- Just use COPY instead, it actually works. - return "copy /B /Y " .. v - end, - copydir = function(v) - v = path.translate(path.normalize(v)) - return "xcopy /Q /E /Y /I " .. v - end, - delete = function(v) - return "del " .. path.translate(path.normalize(v)) - end, - echo = function(v) - return "echo " .. v - end, - mkdir = function(v) - v = path.translate(path.normalize(v)) - return "IF NOT EXIST " .. v .. " (mkdir " .. v .. ")" - end, - move = function(v) - return "move /Y " .. path.translate(path.normalize(v)) - end, - rmdir = function(v) - return "rmdir /S /Q " .. path.translate(path.normalize(v)) - end, - touch = function(v) - v = path.translate(path.normalize(v)) - return string.format("type nul >> %s && copy /b %s+,, %s", v, v, v) - end, - } - } - - function os.translateCommands(cmd, map) - map = map or os.target() - if type(map) == "string" then - map = os.commandTokens[map] or os.commandTokens["_"] - end - - local processOne = function(cmd) - local i, j, prev - repeat - i, j = cmd:find("{.-}") - if i then - if i == prev then - break - end - - local token = cmd:sub(i + 1, j - 1):lower() - local args = cmd:sub(j + 2) - local func = map[token] or os.commandTokens["_"][token] - if func then - cmd = cmd:sub(1, i -1) .. func(args) - end - - prev = i - end - until i == nil - return cmd - end - - if type(cmd) == "table" then - local result = {} - for i = 1, #cmd do - result[i] = processOne(cmd[i]) - end - return result - else - return processOne(cmd) - end - end - - - ---- --- Apply os slashes for decorated command paths. ---- - function os.translateCommandAndPath(dir, map) - if map == 'windows' then - return path.translate(dir) - end - return dir - end - ---- --- Translate decorated command paths into their OS equivalents. ---- - function os.translateCommandsAndPaths(cmds, basedir, location, map) - local translatedBaseDir = path.getrelative(location, basedir) - - map = map or os.target() - - local translateFunction = function(value) - local result = path.join(translatedBaseDir, value) - result = os.translateCommandAndPath(result, map) - if value:endswith('/') or value:endswith('\\') or -- if orginal path ends with a slash then ensure the same - value:endswith('/"') or value:endswith('\\"') then - result = result .. '/' - end - return result - end - - local processOne = function(cmd) - local replaceFunction = function(value) - value = value:sub(3, #value - 1) - return '"' .. translateFunction(value) .. '"' - end - return string.gsub(cmd, "%%%[[^%]\r\n]*%]", replaceFunction) - end - - if type(cmds) == "table" then - local result = {} - for i = 1, #cmds do - result[i] = processOne(cmds[i]) - end - return os.translateCommands(result, map) - else - return os.translateCommands(processOne(cmds), map) - end - end - - --- --- Generate a UUID. --- - - os._uuids = {} - - local builtin_uuid = os.uuid - function os.uuid(name) - local id = builtin_uuid(name) - if name then - if os._uuids[id] and os._uuids[id] ~= name then - premake.warnOnce(id, "UUID clash between %s and %s", os._uuids[id], name) - end - os._uuids[id] = name - end - return id - end - - --- --- Get a set of tags for different 'platforms' --- - - os.systemTags = - { - ["aix"] = { "aix", "posix" }, - ["bsd"] = { "bsd", "posix" }, - ["haiku"] = { "haiku", "posix" }, - ["ios"] = { "ios", "darwin", "posix", "mobile" }, - ["linux"] = { "linux", "posix" }, - ["macosx"] = { "macosx", "darwin", "posix" }, - ["solaris"] = { "solaris", "posix" }, - ["windows"] = { "windows", "win32" }, - } - - function os.getSystemTags(name) - return os.systemTags[name:lower()] or { name:lower() } - end +-- +-- os.lua +-- Additions to the OS namespace. +-- Copyright (c) 2002-2014 Jason Perkins and the Premake project +-- + + +--- +-- Extend Lua's built-in os.execute() with token expansion and +-- path normalization. +-- + + premake.override(os, "execute", function(base, cmd) + cmd = os.translateCommands(cmd) + return base(cmd) + end) + + + +--- +-- Same as os.execute(), but accepts string formatting arguments. +--- + + function os.executef(cmd, ...) + cmd = string.format(cmd, ...) + return os.execute(cmd) + end + + + +-- +-- Scan the well-known system locations for a particular library. +-- + + local function parse_ld_so_conf(conf_file) + -- Linux ldconfig file parser to find system library locations + local first, last + local dirs = { } + for line in io.lines(conf_file) do + -- ignore comments + first = line:find("#", 1, true) + if first ~= nil then + line = line:sub(1, first - 1) + end + + if line ~= "" then + -- check for include files + first, last = line:find("include%s+") + if first ~= nil then + -- found include glob + local include_glob = line:sub(last + 1) + local includes = os.matchfiles(include_glob) + for _, v in ipairs(includes) do + dirs = table.join(dirs, parse_ld_so_conf(v)) + end + else + -- found an actual ld path entry + table.insert(dirs, line) + end + end + end + return dirs + end + + local function get_library_search_path() + local path + if os.istarget("windows") then + path = os.getenv("PATH") or "" + elseif os.istarget("haiku") then + path = os.getenv("LIBRARY_PATH") or "" + else + if os.istarget("darwin") then + path = os.getenv("DYLD_LIBRARY_PATH") or "" + else + path = os.getenv("LD_LIBRARY_PATH") or "" + + for _, prefix in ipairs({"", "/opt"}) do + local conf_file = prefix .. "/etc/ld.so.conf" + if os.isfile(conf_file) then + for _, v in ipairs(parse_ld_so_conf(conf_file)) do + if (#path > 0) then + path = path .. ":" .. v + else + path = v + end + end + end + end + end + + path = path or "" + local archpath = "/lib:/usr/lib:/usr/local/lib" + if os.is64bit() and not (os.istarget("darwin")) then + archpath = "/lib64:/usr/lib64/:usr/local/lib64" .. ":" .. archpath + end + if (#path > 0) then + path = path .. ":" .. archpath + else + path = archpath + end + end + + return path + end + + function os.findlib(libname, libdirs) + -- libname: library name with or without prefix and suffix + -- libdirs: (array or string): A set of additional search paths + + local path = get_library_search_path() + local formats + + -- assemble a search path, depending on the platform + if os.istarget("windows") then + formats = { "%s.dll", "%s" } + elseif os.istarget("haiku") then + formats = { "lib%s.so", "%s.so" } + else + if os.istarget("darwin") then + formats = { "lib%s.dylib", "%s.dylib" } + else + formats = { "lib%s.so", "%s.so" } + end + + table.insert(formats, "%s") + end + + local userpath = "" + + if type(libdirs) == "string" then + userpath = libdirs + elseif type(libdirs) == "table" then + userpath = table.implode(libdirs, "", "", ":") + end + + if (#userpath > 0) then + if (#path > 0) then + path = userpath .. ":" .. path + else + path = userpath + end + end + + for _, fmt in ipairs(formats) do + local name = string.format(fmt, libname) + local result = os.pathsearch(name, path) + if result then return result end + end + end + + function os.findheader(headerpath, headerdirs) + -- headerpath: a partial header file path + -- headerdirs: additional header search paths + + local path = get_library_search_path() + + -- replace all /lib by /include + path = path .. ':' + path = path:gsub ('/lib[0-9]*([:/])', '/include%1') + path = path:sub (1, #path - 1) + + local userpath = "" + + if type(headerdirs) == "string" then + userpath = headerdirs + elseif type(headerdirs) == "table" then + userpath = table.implode(headerdirs, "", "", ":") + end + + if (#userpath > 0) then + if (#path > 0) then + path = userpath .. ":" .. path + else + path = userpath + end + end + + local result = os.pathsearch (headerpath, path) + return result + end + +-- +-- Retrieve the current target operating system ID string. +-- + + function os.target() + return _OPTIONS.os or _TARGET_OS + end + + function os.get() + local caller = filelineinfo(2) + premake.warnOnce(caller, "os.get() is deprecated, use 'os.target()' or 'os.host()'.\n @%s\n", caller) + return os.target() + end + + -- deprecate _OS + _G_metatable = { + __index = function(t, k) + if (k == '_OS') then + premake.warnOnce("_OS+get", "_OS is deprecated, use '_TARGET_OS'.") + return rawget(t, "_TARGET_OS") + else + return rawget(t, k) + end + end, + + __newindex = function(t, k, v) + if (k == '_OS') then + premake.warnOnce("_OS+set", "_OS is deprecated, use '_TARGET_OS'.") + rawset(t, "_TARGET_OS", v) + else + rawset(t, k, v) + end + end + } + setmetatable(_G, _G_metatable) + + + +-- +-- Check the current target operating system; may be set with the /os command line flag. +-- + + function os.istarget(id) + local tags = os.getSystemTags(os.target()) + return table.contains(tags, id:lower()) + end + + function os.is(id) + local caller = filelineinfo(2) + premake.warnOnce(caller, "os.is() is deprecated, use 'os.istarget()' or 'os.ishost()'.\n @%s\n", caller) + return os.istarget(id) + end + + +-- +-- Check the current host operating system. +-- + + function os.ishost(id) + local tags = os.getSystemTags(os.host()) + return table.contains(tags, id:lower()) + end + + +--- +-- Determine if a directory exists on the file system, and that it is a +-- directory and not a file. +-- +-- @param p +-- The path to check. +-- @return +-- True if a directory exists at the given path. +--- + + premake.override(os, "isdir", function(base, p) + p = path.normalize(p) + return base(p) + end) + + + +--- +-- Determine if a file exists on the file system, and that it is a +-- file and not a directory. +-- +-- @param p +-- The path to check. +-- @return +-- True if a file exists at the given path. +--- + + premake.override(os, "isfile", function(base, p) + p = path.normalize(p) + return base(p) + end) + + + +-- +-- Determine if the current system is running a 64-bit architecture. +-- + + local _is64bit + + local _64BitHostTypes = { + "x86_64", + "ia64", + "amd64", + "ppc64", + "powerpc64", + "sparc64" + } + + function os.is64bit() + -- This can be expensive to compute, so cache and reuse the response + if _is64bit ~= nil then + return _is64bit + end + + _is64bit = false + + -- Call the native code implementation. If this returns true then + -- we're 64-bit, otherwise do more checking locally + if (os._is64bit()) then + _is64bit = true + else + -- Identify the system + local arch + if os.ishost("windows") then + arch = os.getenv("PROCESSOR_ARCHITECTURE") + elseif os.ishost("macosx") then + arch = os.outputof("echo $HOSTTYPE") + else + arch = os.outputof("uname -m") + end + + -- Check our known 64-bit identifiers + arch = arch:lower() + for _, hosttype in ipairs(_64BitHostTypes) do + if arch:find(hosttype) then + _is64bit = true + end + end + end + + return _is64bit + end + + +--- +-- Perform a wildcard search for files and directories. +-- +-- @param mask +-- The file search pattern. Use "*" to match any part of a file or +-- directory name, "**" to recurse into subdirectories. +-- @return +-- A table containing the matched file or directory names. +--- + + function os.match(mask) + mask = path.normalize(mask) + local starpos = mask:find("%*") + local before = path.getdirectory(starpos and mask:sub(1, starpos - 1) or mask) + local slashpos = starpos and mask:find("/", starpos) + local after = slashpos and mask:sub(slashpos + 1) + + -- Only recurse for path components starting with '**': + local recurse = starpos and + mask:sub(starpos + 1, starpos + 1) == '*' and + (starpos == 1 or mask:sub(starpos - 1, starpos - 1) == '/') + + local results = { } + + if recurse then + local submask = mask:sub(1, starpos) .. mask:sub(starpos + 2) + results = os.match(submask) + + local pattern = mask:sub(1, starpos) + local m = os.matchstart(pattern) + while os.matchnext(m) do + if not os.matchisfile(m) then + local matchpath = path.join(before, os.matchname(m), mask:sub(starpos)) + results = table.join(results, os.match(matchpath)) + end + end + os.matchdone(m) + else + local pattern = mask:sub(1, slashpos and slashpos - 1) + local m = os.matchstart(pattern) + while os.matchnext(m) do + if not (slashpos and os.matchisfile(m)) then + local matchpath = path.join(before, matchpath, os.matchname(m)) + if after then + results = table.join(results, os.match(path.join(matchpath, after))) + else + table.insert(results, matchpath) + end + end + end + os.matchdone(m) + end + + return results + end + + +--- +-- Perform a wildcard search for directories. +-- +-- @param mask +-- The search pattern. Use "*" to match any part of a directory +-- name, "**" to recurse into subdirectories. +-- @return +-- A table containing the matched directory names. +--- + + function os.matchdirs(mask) + local results = os.match(mask) + for i = #results, 1, -1 do + if not os.isdir(results[i]) then + table.remove(results, i) + end + end + return results + end + + +--- +-- Perform a wildcard search for files. +-- +-- @param mask +-- The search pattern. Use "*" to match any part of a file +-- name, "**" to recurse into subdirectories. +-- @return +-- A table containing the matched directory names. +--- + + function os.matchfiles(mask) + local results = os.match(mask) + for i = #results, 1, -1 do + if not os.isfile(results[i]) then + table.remove(results, i) + end + end + return results + end + +-- +-- An overload of the os.mkdir() function, which will create any missing +-- subdirectories along the path. +-- + + local builtin_mkdir = os.mkdir + function os.mkdir(p) + p = path.normalize(p) + + local dir = iif(p:startswith("/"), "/", "") + for part in p:gmatch("[^/]+") do + dir = dir .. part + + if (part ~= "" and not path.isabsolute(part) and not os.isdir(dir)) then + local ok, err = builtin_mkdir(dir) + if (not ok) then + return nil, err + end + end + + dir = dir .. "/" + end + + return true + end + + +-- +-- Run a shell command and return the output. +-- +-- @param cmd Command to execute +-- @param streams Standard stream(s) to output +-- Must be one of +-- - "both" (default) +-- - "output" Return standard output stream content only +-- - "error" Return standard error stream content only +-- + + function os.outputof(cmd, streams) + cmd = path.normalize(cmd) + streams = streams or "both" + local redirection + if streams == "both" then + redirection = " 2>&1" + elseif streams == "output" then + redirection = " 2>/dev/null" + elseif streams == "error" then + redirection = " 2>&1 1>/dev/null" + else + error ('Invalid stream(s) selection. "output", "error", or "both" expected.') + end + + local pipe = io.popen(cmd .. redirection) + local result = pipe:read('*a') + local success, what, code = pipe:close() + if success then + -- chomp trailing newlines + if result then + result = string.gsub(result, "[\r\n]+$", "") + end + + return result, code, what + else + return nil, code, what + end + end + + +-- +-- @brief An overloaded os.remove() that will be able to handle list of files, +-- as well as wildcards for files. Uses the syntax os.matchfiles() for +-- matching pattern wildcards. +-- +-- @param f A file, a wildcard, or a list of files or wildcards to be removed +-- +-- @return true on success, false and an appropriate error message on error +-- +-- @example ok, err = os.remove{"**.bak", "**.log"} +-- if not ok then +-- error(err) +-- end +-- + + local builtin_remove = os.remove + function os.remove(f) + -- in case of string, just match files + if type(f) == "string" then + local p = os.matchfiles(f) + for _, v in pairs(p) do + local ok, err, code = builtin_remove(v) + if not ok then + return ok, err, code + end + end + if #p == 0 then + return nil, "Couldn't find any file matching: " .. f, 1 + end + -- in case of table, match files for every table entry + elseif type(f) == "table" then + for _, v in pairs(f) do + local ok, err, code = os.remove(v) + if not ok then + return ok, err, code + end + end + end + + return true + end + + +-- +-- Remove a directory, along with any contained files or subdirectories. +-- +-- @return true on success, false and an appropriate error message on error + + local builtin_rmdir = os.rmdir + function os.rmdir(p) + -- recursively remove subdirectories + local dirs = os.matchdirs(p .. "/*") + for _, dname in ipairs(dirs) do + local ok, err = os.rmdir(dname) + if not ok then + return ok, err + end + end + + -- remove any files + local files = os.matchfiles(p .. "/*") + for _, fname in ipairs(files) do + local ok, err = os.remove(fname) + if not ok then + return ok, err + end + end + + -- remove this directory + return builtin_rmdir(p) + end + + +--- +-- Return information about a file. +--- + + premake.override(os, "stat", function(base, p) + p = path.normalize(p) + return base(p) + end) + + + +--- +-- Translate command tokens into their OS or action specific equivalents. +--- + + os.commandTokens = { + _ = { + chdir = function(v) + return "cd " .. path.normalize(v) + end, + copy = function(v) + return "cp -rf " .. path.normalize(v) + end, + copyfile = function(v) + return "cp -f " .. path.normalize(v) + end, + copydir = function(v) + return "cp -rf " .. path.normalize(v) + end, + delete = function(v) + return "rm -f " .. path.normalize(v) + end, + echo = function(v) + return "echo " .. v + end, + mkdir = function(v) + return "mkdir -p " .. path.normalize(v) + end, + move = function(v) + return "mv -f " .. path.normalize(v) + end, + rmdir = function(v) + return "rm -rf " .. path.normalize(v) + end, + touch = function(v) + return "touch " .. path.normalize(v) + end, + }, + windows = { + chdir = function(v) + return "chdir " .. path.translate(path.normalize(v)) + end, + copy = function(v) + v = path.translate(path.normalize(v)) + + -- Detect if there's multiple parts to the input, if there is grab the first part else grab the whole thing + local src = string.match(v, '^".-"') or string.match(v, '^.- ') or v + + -- Strip the trailing space from the second condition so that we don't have a space between src and '\\NUL' + src = string.match(src, '^.*%S') + + return "IF EXIST " .. src .. "\\ (xcopy /Q /E /Y /I " .. v .. " > nul) ELSE (xcopy /Q /Y /I " .. v .. " > nul)" + end, + copyfile = function(v) + v = path.translate(path.normalize(v)) + -- XCOPY doesn't have a switch to assume destination is a file when it doesn't exist. + -- A trailing * will suppress the prompt but requires the file extensions be the same length. + -- Just use COPY instead, it actually works. + return "copy /B /Y " .. v + end, + copydir = function(v) + v = path.translate(path.normalize(v)) + return "xcopy /Q /E /Y /I " .. v + end, + delete = function(v) + return "del " .. path.translate(path.normalize(v)) + end, + echo = function(v) + return "echo " .. v + end, + mkdir = function(v) + v = path.translate(path.normalize(v)) + return "IF NOT EXIST " .. v .. " (mkdir " .. v .. ")" + end, + move = function(v) + return "move /Y " .. path.translate(path.normalize(v)) + end, + rmdir = function(v) + return "rmdir /S /Q " .. path.translate(path.normalize(v)) + end, + touch = function(v) + v = path.translate(path.normalize(v)) + return string.format("type nul >> %s && copy /b %s+,, %s", v, v, v) + end, + } + } + + function os.translateCommands(cmd, map) + map = map or os.target() + if type(map) == "string" then + map = os.commandTokens[map] or os.commandTokens["_"] + end + + local processOne = function(cmd) + local i, j, prev + repeat + i, j = cmd:find("{.-}") + if i then + if i == prev then + break + end + + local token = cmd:sub(i + 1, j - 1):lower() + local args = cmd:sub(j + 2) + local func = map[token] or os.commandTokens["_"][token] + if func then + cmd = cmd:sub(1, i -1) .. func(args) + end + + prev = i + end + until i == nil + return cmd + end + + if type(cmd) == "table" then + local result = {} + for i = 1, #cmd do + result[i] = processOne(cmd[i]) + end + return result + else + return processOne(cmd) + end + end + + + +--- +-- Apply os slashes for decorated command paths. +--- + function os.translateCommandAndPath(dir, map) + if map == 'windows' then + return path.translate(dir) + end + return dir + end + +--- +-- Translate decorated command paths into their OS equivalents. +--- + function os.translateCommandsAndPaths(cmds, basedir, location, map) + local translatedBaseDir = path.getrelative(location, basedir) + + map = map or os.target() + + local translateFunction = function(value) + local result = path.join(translatedBaseDir, value) + result = os.translateCommandAndPath(result, map) + if value:endswith('/') or value:endswith('\\') or -- if orginal path ends with a slash then ensure the same + value:endswith('/"') or value:endswith('\\"') then + result = result .. '/' + end + return result + end + + local processOne = function(cmd) + local replaceFunction = function(value) + value = value:sub(3, #value - 1) + return '"' .. translateFunction(value) .. '"' + end + return string.gsub(cmd, "%%%[[^%]\r\n]*%]", replaceFunction) + end + + if type(cmds) == "table" then + local result = {} + for i = 1, #cmds do + result[i] = processOne(cmds[i]) + end + return os.translateCommands(result, map) + else + return os.translateCommands(processOne(cmds), map) + end + end + + +-- +-- Generate a UUID. +-- + + os._uuids = {} + + local builtin_uuid = os.uuid + function os.uuid(name) + local id = builtin_uuid(name) + if name then + if os._uuids[id] and os._uuids[id] ~= name then + premake.warnOnce(id, "UUID clash between %s and %s", os._uuids[id], name) + end + os._uuids[id] = name + end + return id + end + + +-- +-- Get a set of tags for different 'platforms' +-- + + os.systemTags = + { + ["aix"] = { "aix", "posix" }, + ["bsd"] = { "bsd", "posix" }, + ["haiku"] = { "haiku", "posix" }, + ["ios"] = { "ios", "darwin", "posix", "mobile" }, + ["linux"] = { "linux", "posix" }, + ["macosx"] = { "macosx", "darwin", "posix" }, + ["solaris"] = { "solaris", "posix" }, + ["windows"] = { "windows", "win32" }, + } + + function os.getSystemTags(name) + return os.systemTags[name:lower()] or { name:lower() } + end diff --git a/src/host/os_is64bit.c b/src/host/os_is64bit.c index 31347512..13bb9959 100644 --- a/src/host/os_is64bit.c +++ b/src/host/os_is64bit.c @@ -1,30 +1,30 @@ -/** - * \file os_is64bit.c - * \brief Native code-side checking for a 64-bit architecture. - * \author Copyright (c) 2011 Jason Perkins and the Premake project - */ - -#include "premake.h" - -int os_is64bit(lua_State* L) -{ - // If this code returns true, then the platform is 64-bit. If it - // returns false, the platform might still be 64-bit, but more - // checking will need to be done on the Lua side of things. -#if PLATFORM_WINDOWS - typedef BOOL (WINAPI* WowFuncSig)(HANDLE, PBOOL); - WowFuncSig func = (WowFuncSig)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process"); - if (func) - { - BOOL isWow = FALSE; - if (func(GetCurrentProcess(), &isWow)) - { - lua_pushboolean(L, isWow); - return 1; - } - } -#endif - - lua_pushboolean(L, 0); - return 1; -} +/** + * \file os_is64bit.c + * \brief Native code-side checking for a 64-bit architecture. + * \author Copyright (c) 2011 Jason Perkins and the Premake project + */ + +#include "premake.h" + +int os_is64bit(lua_State* L) +{ + // If this code returns true, then the platform is 64-bit. If it + // returns false, the platform might still be 64-bit, but more + // checking will need to be done on the Lua side of things. +#if PLATFORM_WINDOWS + typedef BOOL (WINAPI* WowFuncSig)(HANDLE, PBOOL); + WowFuncSig func = (WowFuncSig)GetProcAddress(GetModuleHandle(TEXT("kernel32")), "IsWow64Process"); + if (func) + { + BOOL isWow = FALSE; + if (func(GetCurrentProcess(), &isWow)) + { + lua_pushboolean(L, isWow); + return 1; + } + } +#endif + + lua_pushboolean(L, 0); + return 1; +} diff --git a/tests/_tests.lua b/tests/_tests.lua index a44b3044..f0450999 100644 --- a/tests/_tests.lua +++ b/tests/_tests.lua @@ -1,66 +1,66 @@ -return { - -- Base API tests - "test_string.lua", - "base/test_aliasing.lua", - "base/test_binmodules.lua", - "base/test_configset.lua", - "base/test_context.lua", - "base/test_criteria.lua", - "base/test_detoken.lua", - "base/test_include.lua", - "base/test_module_loader.lua", - "base/test_option.lua", - "base/test_os.lua", - "base/test_override.lua", - "base/test_path.lua", - "base/test_premake_command.lua", - "base/test_table.lua", - "base/test_tree.lua", - "base/test_uuid.lua", - "base/test_versions.lua", - "base/test_http.lua", - "base/test_json.lua", - - -- Workspace object tests - "workspace/test_eachconfig.lua", - "workspace/test_location.lua", - "workspace/test_objdirs.lua", - - -- Project object tests - "project/test_config_maps.lua", - "project/test_eachconfig.lua", - "project/test_getconfig.lua", - "project/test_location.lua", - "project/test_sources.lua", - "project/test_vpaths.lua", - - -- Configuration object tests - "config/test_linkinfo.lua", - "config/test_links.lua", - "config/test_targetinfo.lua", - - -- Baking tests - "oven/test_filtering.lua", - "oven/test_objdirs.lua", - - -- API tests - "api/test_boolean_kind.lua", - "api/test_containers.lua", - "api/test_directory_kind.lua", - "api/test_list_kind.lua", - "api/test_path_kind.lua", - "api/test_register.lua", - "api/test_string_kind.lua", - "api/test_table_kind.lua", - "api/test_deprecations.lua", - - -- Control system tests - "test_premake.lua", - "base/test_validation.lua", - - -- -- Toolset tests - "tools/test_dotnet.lua", - "tools/test_gcc.lua", - "tools/test_clang.lua", - "tools/test_msc.lua", -} +return { + -- Base API tests + "test_string.lua", + "base/test_aliasing.lua", + "base/test_binmodules.lua", + "base/test_configset.lua", + "base/test_context.lua", + "base/test_criteria.lua", + "base/test_detoken.lua", + "base/test_include.lua", + "base/test_module_loader.lua", + "base/test_option.lua", + "base/test_os.lua", + "base/test_override.lua", + "base/test_path.lua", + "base/test_premake_command.lua", + "base/test_table.lua", + "base/test_tree.lua", + "base/test_uuid.lua", + "base/test_versions.lua", + "base/test_http.lua", + "base/test_json.lua", + + -- Workspace object tests + "workspace/test_eachconfig.lua", + "workspace/test_location.lua", + "workspace/test_objdirs.lua", + + -- Project object tests + "project/test_config_maps.lua", + "project/test_eachconfig.lua", + "project/test_getconfig.lua", + "project/test_location.lua", + "project/test_sources.lua", + "project/test_vpaths.lua", + + -- Configuration object tests + "config/test_linkinfo.lua", + "config/test_links.lua", + "config/test_targetinfo.lua", + + -- Baking tests + "oven/test_filtering.lua", + "oven/test_objdirs.lua", + + -- API tests + "api/test_boolean_kind.lua", + "api/test_containers.lua", + "api/test_directory_kind.lua", + "api/test_list_kind.lua", + "api/test_path_kind.lua", + "api/test_register.lua", + "api/test_string_kind.lua", + "api/test_table_kind.lua", + "api/test_deprecations.lua", + + -- Control system tests + "test_premake.lua", + "base/test_validation.lua", + + -- -- Toolset tests + "tools/test_dotnet.lua", + "tools/test_gcc.lua", + "tools/test_clang.lua", + "tools/test_msc.lua", +} diff --git a/tests/base/test_os.lua b/tests/base/test_os.lua index 62315dea..07d39957 100644 --- a/tests/base/test_os.lua +++ b/tests/base/test_os.lua @@ -1,484 +1,484 @@ ---- --- tests/base/test_os.lua --- Automated test suite for the new OS functions. --- Copyright (c) 2008-2017 Jason Perkins and the Premake project ---- - - local suite = test.declare("base_os") - - local cwd - - function suite.setup() - cwd = os.getcwd() - os.chdir(_TESTS_DIR) - end - - function suite.teardown() - os.chdir(cwd) - end - - --- --- os.findlib() tests --- - - function suite.findlib_FindSystemLib() - if os.istarget("windows") then - test.istrue(os.findlib("user32")) - elseif os.istarget("haiku") then - test.istrue(os.findlib("root")) - else - test.istrue(os.findlib("m")) - end - end - - function suite.findlib_FailsOnBadLibName() - test.isfalse(os.findlib("NoSuchLibraryAsThisOneHere")) - end - - function suite.findheader_stdheaders() - if not os.istarget("windows") and not os.istarget("macosx") then - test.istrue(os.findheader("stdlib.h")) - end - end - - function suite.findheader_failure() - test.isfalse(os.findheader("Knights/who/say/Ni.hpp")) - end - - --- --- os.isfile() tests --- - - function suite.isfile_ReturnsTrue_OnExistingFile() - test.istrue(os.isfile("_tests.lua")) - end - - function suite.isfile_ReturnsFalse_OnNonexistantFile() - test.isfalse(os.isfile("no_such_file.lua")) - end - - - --- --- os.matchdirs() tests --- - - function suite.matchdirs_skipsDottedDirs() - local result = os.matchdirs("*") - test.isfalse(table.contains(result, "..")) - end - - - --- --- os.matchfiles() tests --- - - function suite.matchfiles_OnNonRecursive() - local result = os.matchfiles("*.lua") - test.istrue(table.contains(result, "_tests.lua")) - test.isfalse(table.contains(result, "folder/ok.lua")) - end - - function suite.matchfiles_Recursive() - local result = os.matchfiles("**.lua") - test.istrue(table.contains(result, "folder/ok.lua")) - end - - function suite.matchfiles_SkipsDotDirs_OnRecursive() - local result = os.matchfiles("**.lua") - test.isfalse(table.contains(result, ".svn/text-base/testfx.lua.svn-base")) - end - - function suite.matchfiles_OnSubfolderMatch() - local result = os.matchfiles("**/subfolder/*") - test.istrue(table.contains(result, "folder/subfolder/hello.txt")) - test.isfalse(table.contains(result, "premake4.lua")) - end - - function suite.matchfiles_OnDotSlashPrefix() - local result = os.matchfiles("./**.lua") - test.istrue(table.contains(result, "folder/ok.lua")) - end - - function suite.matchfiles_OnImplicitEndOfString() - local result = os.matchfiles("folder/*.lua") - test.istrue(table.contains(result, "folder/ok.lua")) - test.isfalse(table.contains(result, "folder/ok.lua.2")) - end - - function suite.matchfiles_OnLeadingDotSlashWithPath() - local result = os.matchfiles("./folder/*.lua") - test.istrue(table.contains(result, "folder/ok.lua")) - end - - function suite.matchfiles_OnDottedFile() - local result = os.matchfiles("base/.*") - test.istrue(table.contains(result, "base/.testDotFile")) - end - - function suite.matchfiles_onComboSearch() - local result = os.matchfiles("folder/**/*.txt") - test.istrue(table.contains(result, "folder/subfolder/hello.txt")) - end - - function suite.matchfiles_onSymbolicLink() - if os.istarget("macosx") - or os.istarget("linux") - or os.istarget("solaris") - or os.istarget("bsd") - then - os.execute("cd folder && ln -s subfolder symlinkfolder && cd ..") - local result = os.matchfiles("folder/**/*.txt") - os.execute("rm folder/symlinkfolder") - premake.modules.self_test.print(table.tostring(result)) - test.istrue(table.contains(result, "folder/symlinkfolder/hello.txt")) - end - end - - --- --- os.pathsearch() tests --- - - function suite.pathsearch_ReturnsNil_OnNotFound() - test.istrue(os.pathsearch("nosuchfile", "aaa;bbb;ccc") == nil) - end - - function suite.pathsearch_ReturnsPath_OnFound() - test.isequal(_TESTS_DIR, os.pathsearch("_tests.lua", _TESTS_DIR)) - end - - function suite.pathsearch_FindsFile_OnComplexPath() - test.isequal(_TESTS_DIR, os.pathsearch("_tests.lua", "aaa;" .. _TESTS_DIR .. ";bbb")) - end - - function suite.pathsearch_NilPathsAllowed() - test.isequal(_TESTS_DIR, os.pathsearch("_tests.lua", nil, _TESTS_DIR, nil)) - end - - --- --- os.outputof() tests --- - - -- Check if outputof returns the command exit code - -- in addition of the command output - function suite.outputof_commandExitCode() - if os.istarget("macosx") - or os.istarget("linux") - or os.istarget("solaris") - or os.istarget("bsd") - then - -- Assumes 'true' and 'false' commands exist - -- which should be the case on all *nix platforms - for cmd, exitcode in pairs ({ - ["true"] = 0, - ["false"] = 1 - }) - do - local o, e = os.outputof(cmd) - test.isequal(e, exitcode) - end - end - end - - -- Check outputof content - function suite.outputof_streams_output() - if (os.istarget("macosx") - or os.istarget("linux") - or os.istarget("solaris") - or os.istarget("bsd")) - and os.isdir (_TESTS_DIR) - then - local ob, e = os.outputof ("ls " .. _TESTS_DIR .. "/base") - local oo, e = os.outputof ("ls " .. _TESTS_DIR .. "/base", "output") - test.isequal (oo, ob) - local s, e = string.find (oo, "test_os.lua") - test.istrue(s ~= nil) - - local o, e = os.outputof ("ls " .. cwd .. "/base", "error") - test.istrue(o == nil or #o == 0) - end - end - --- --- os.translateCommand() tests --- - - function suite.translateCommand_onNoToken() - test.isequal("cp a b", os.translateCommands("cp a b")) - end - - function suite.translateCommand_callsProcessor() - os.commandTokens.test = { - copy = function(value) return "test " .. value end - } - test.isequal("test a b", os.translateCommands("{COPY} a b", "test")) - end - - function suite.translateCommand_callsProcessor_multipleTokens() - os.commandTokens.test = { - copy = function(value) return "test " .. value end - } - test.isequal("test a b; test c d; test e f;", os.translateCommands("{COPY} a b; {COPY} c d; {COPY} e f;", "test")) - end - --- --- os.translateCommand() windows COPY tests --- - - function suite.translateCommand_windowsCopyNoDst() - test.isequal('IF EXIST a\\ (xcopy /Q /E /Y /I a > nul) ELSE (xcopy /Q /Y /I a > nul)', os.translateCommands('{COPY} a', "windows")) - end - - function suite.translateCommand_windowsCopyNoDst_ExtraSpace() - test.isequal('IF EXIST a\\ (xcopy /Q /E /Y /I a > nul) ELSE (xcopy /Q /Y /I a > nul)', os.translateCommands('{COPY} a ', "windows")) - end - - function suite.translateCommand_windowsCopyNoQuotes() - test.isequal('IF EXIST a\\ (xcopy /Q /E /Y /I a b > nul) ELSE (xcopy /Q /Y /I a b > nul)', os.translateCommands('{COPY} a b', "windows")) - end - - function suite.translateCommand_windowsCopyNoQuotes_ExtraSpace() - test.isequal('IF EXIST a\\ (xcopy /Q /E /Y /I a b > nul) ELSE (xcopy /Q /Y /I a b > nul)', os.translateCommands('{COPY} a b ', "windows")) - end - - function suite.translateCommand_windowsCopyQuotes() - test.isequal('IF EXIST "a a"\\ (xcopy /Q /E /Y /I "a a" "b" > nul) ELSE (xcopy /Q /Y /I "a a" "b" > nul)', os.translateCommands('{COPY} "a a" "b"', "windows")) - end - - function suite.translateCommand_windowsCopyQuotes_ExtraSpace() - test.isequal('IF EXIST "a a"\\ (xcopy /Q /E /Y /I "a a" "b" > nul) ELSE (xcopy /Q /Y /I "a a" "b" > nul)', os.translateCommands('{COPY} "a a" "b" ', "windows")) - end - - function suite.translateCommand_windowsCopyNoQuotesDst() - test.isequal('IF EXIST "a a"\\ (xcopy /Q /E /Y /I "a a" b > nul) ELSE (xcopy /Q /Y /I "a a" b > nul)', os.translateCommands('{COPY} "a a" b', "windows")) - end - - function suite.translateCommand_windowsCopyNoQuotesDst_ExtraSpace() - test.isequal('IF EXIST "a a"\\ (xcopy /Q /E /Y /I "a a" b > nul) ELSE (xcopy /Q /Y /I "a a" b > nul)', os.translateCommands('{COPY} "a a" b ', "windows")) - end - - function suite.translateCommand_windowsCopyNoQuotesSrc() - test.isequal('IF EXIST a\\ (xcopy /Q /E /Y /I a "b" > nul) ELSE (xcopy /Q /Y /I a "b" > nul)', os.translateCommands('{COPY} a "b"', "windows")) - end - - function suite.translateCommand_windowsCopyNoQuotesSrc_ExtraSpace() - test.isequal('IF EXIST a\\ (xcopy /Q /E /Y /I a "b" > nul) ELSE (xcopy /Q /Y /I a "b" > nul)', os.translateCommands('{COPY} a "b" ', "windows")) - end - --- --- os.getWindowsRegistry windows tests --- - function suite.getreg_nonExistentValue() - if os.ishost("windows") then - local x = os.getWindowsRegistry("HKCU:Should\\Not\\Exist\\At\\All") - test.isequal(nil, x) - end - end - - function suite.getreg_nonExistentDefaultValue() - if os.ishost("windows") then - local x = os.getWindowsRegistry("HKCU:Should\\Not\\Exist\\At\\All\\") - test.isequal(nil, x) - end - end - - function suite.getreg_noSeparators() - if os.ishost("windows") then - local x = os.getWindowsRegistry("HKCU:ShouldNotExistAtAll") - test.isequal(nil, x) - end - end - - function suite.getreg_namedValue() - if os.ishost("windows") then - local x = os.getWindowsRegistry("HKCU:Environment\\TEMP") - test.istrue(x ~= nil) - end - end - - function suite.getreg_namedValueOptSeparator() - if os.ishost("windows") then - local x = os.getWindowsRegistry("HKCU:\\Environment\\TEMP") - test.istrue(x ~= nil) - end - end - - function suite.getreg_defaultValue() - if os.ishost("windows") then - local x = os.getWindowsRegistry("HKLM:SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Minimal\\AppInfo\\") - test.isequal("Service", x) - end - end - - --- --- os.listWindowsRegistry windows tests --- - function suite.listreg_nonExistentKey() - if os.ishost("windows") then - local x = os.listWindowsRegistry("HKCU:Should\\Not\\Exist\\At\\All") - test.isequal(nil, x) - end - end - - function suite.listreg_nonExistentKeyTrailingBackslash() - if os.ishost("windows") then - local x = os.listWindowsRegistry("HKCU:Should\\Not\\Exist\\At\\All\\") - test.isequal(nil, x) - end - end - - function suite.listreg_noSeparators() - if os.ishost("windows") then - local x = os.listWindowsRegistry("HKCU:ShouldNotExistAtAll") - test.isequal(nil, x) - end - end - - function suite.listreg_noSeparatorExistingPath() - if os.ishost("windows") then - local x = os.listWindowsRegistry("HKCU:Environment") - test.istrue(x ~= nil and x["TEMP"] ~= nil) - end - end - - function suite.listreg_optSeparators() - if os.ishost("windows") then - local x = os.listWindowsRegistry("HKCU:\\Environment\\") - test.istrue(x ~= nil and x["TEMP"] ~= nil) - end - end - - function suite.listreg_keyDefaultValueAndStringValueFormat() - if os.ishost("windows") then - local x = os.listWindowsRegistry("HKLM:SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Minimal\\AppInfo") - test.isequal(x[""]["value"], "Service") - test.isequal(x[""]["type"], "REG_SZ") - end - end - - function suite.listreg_numericValueFormat() - if os.ishost("windows") then - local x = os.listWindowsRegistry("HKCU:Console") - test.isequal(type(x["FullScreen"]["value"]), "number") - test.isequal(x["FullScreen"]["type"], "REG_DWORD") - end - end - - function suite.listreg_subkeyFormat() - if os.ishost("windows") then - local x = os.listWindowsRegistry("HKLM:") - test.isequal(type(x["SOFTWARE"]), "table") - test.isequal(next(x["SOFTWARE"]), nil) - end - end - --- --- os.getversion tests. --- - - function suite.getversion() - local version = os.getversion(); - test.istrue(version ~= nil) - end - - - --- --- os.translateCommandsAndPaths. --- - - function suite.translateCommandsAndPaths() - test.isequal('cmdtool "../foo/path1"', os.translateCommandsAndPaths("cmdtool %[path1]", '../foo', '.', 'osx')) - end - - function suite.translateCommandsAndPaths_PreserveSlash() - test.isequal('cmdtool "../foo/path1/"', os.translateCommandsAndPaths("cmdtool %[path1/]", '../foo', '.', 'osx')) - end - - function suite.translateCommandsAndPaths_MultipleTokens() - test.isequal('cmdtool "../foo/path1" "../foo/path2/"', os.translateCommandsAndPaths("cmdtool %[path1] %[path2/]", '../foo', '.', 'osx')) - end - - --- --- Helpers --- - - local tmpname = function() - local p = os.tmpname() - os.remove(p) -- just needed on POSIX - return p - end - - local tmpfile = function() - local p = tmpname() - if os.ishost("windows") then - os.execute("type nul >" .. p) - else - os.execute("touch " .. p) - end - return p - end - - local tmpdir = function() - local p = tmpname() - os.mkdir(p) - return p - end - - --- --- os.remove() tests. --- - - function suite.remove_ReturnsError_OnNonExistingPath() - local ok, err, exitcode = os.remove(tmpname()) - test.isnil(ok) - test.isequal("string", type(err)) - test.isequal("number", type(exitcode)) - test.istrue(0 ~= exitcode) - end - - function suite.remove_ReturnsError_OnDirectory() - local ok, err, exitcode = os.remove(tmpdir()) - test.isnil(ok) - test.isequal("string", type(err)) - test.isequal("number", type(exitcode)) - test.istrue(0 ~= exitcode) - end - - function suite.remove_ReturnsTrue_OnFile() - local ok, err, exitcode = os.remove(tmpfile()) - test.isequal(true, ok) - test.isnil(err) - test.isnil(exitcode) - end - - --- --- os.rmdir() tests. --- - - function suite.rmdir_ReturnsError_OnNonExistingPath() - local ok, err = os.rmdir(tmpname()) - test.isnil(ok) - test.isequal("string", type(err)) - end - - function suite.rmdir_ReturnsError_OnFile() - local ok, err = os.rmdir(tmpfile()) - test.isnil(ok) - test.isequal("string", type(err)) - end - - function suite.rmdir_ReturnsTrue_OnDirectory() - local ok, err = os.rmdir(tmpdir()) - test.isequal(true, ok) - test.isnil(err) - end +--- +-- tests/base/test_os.lua +-- Automated test suite for the new OS functions. +-- Copyright (c) 2008-2017 Jason Perkins and the Premake project +--- + + local suite = test.declare("base_os") + + local cwd + + function suite.setup() + cwd = os.getcwd() + os.chdir(_TESTS_DIR) + end + + function suite.teardown() + os.chdir(cwd) + end + + +-- +-- os.findlib() tests +-- + + function suite.findlib_FindSystemLib() + if os.istarget("windows") then + test.istrue(os.findlib("user32")) + elseif os.istarget("haiku") then + test.istrue(os.findlib("root")) + else + test.istrue(os.findlib("m")) + end + end + + function suite.findlib_FailsOnBadLibName() + test.isfalse(os.findlib("NoSuchLibraryAsThisOneHere")) + end + + function suite.findheader_stdheaders() + if not os.istarget("windows") and not os.istarget("macosx") then + test.istrue(os.findheader("stdlib.h")) + end + end + + function suite.findheader_failure() + test.isfalse(os.findheader("Knights/who/say/Ni.hpp")) + end + + +-- +-- os.isfile() tests +-- + + function suite.isfile_ReturnsTrue_OnExistingFile() + test.istrue(os.isfile("_tests.lua")) + end + + function suite.isfile_ReturnsFalse_OnNonexistantFile() + test.isfalse(os.isfile("no_such_file.lua")) + end + + + +-- +-- os.matchdirs() tests +-- + + function suite.matchdirs_skipsDottedDirs() + local result = os.matchdirs("*") + test.isfalse(table.contains(result, "..")) + end + + + +-- +-- os.matchfiles() tests +-- + + function suite.matchfiles_OnNonRecursive() + local result = os.matchfiles("*.lua") + test.istrue(table.contains(result, "_tests.lua")) + test.isfalse(table.contains(result, "folder/ok.lua")) + end + + function suite.matchfiles_Recursive() + local result = os.matchfiles("**.lua") + test.istrue(table.contains(result, "folder/ok.lua")) + end + + function suite.matchfiles_SkipsDotDirs_OnRecursive() + local result = os.matchfiles("**.lua") + test.isfalse(table.contains(result, ".svn/text-base/testfx.lua.svn-base")) + end + + function suite.matchfiles_OnSubfolderMatch() + local result = os.matchfiles("**/subfolder/*") + test.istrue(table.contains(result, "folder/subfolder/hello.txt")) + test.isfalse(table.contains(result, "premake4.lua")) + end + + function suite.matchfiles_OnDotSlashPrefix() + local result = os.matchfiles("./**.lua") + test.istrue(table.contains(result, "folder/ok.lua")) + end + + function suite.matchfiles_OnImplicitEndOfString() + local result = os.matchfiles("folder/*.lua") + test.istrue(table.contains(result, "folder/ok.lua")) + test.isfalse(table.contains(result, "folder/ok.lua.2")) + end + + function suite.matchfiles_OnLeadingDotSlashWithPath() + local result = os.matchfiles("./folder/*.lua") + test.istrue(table.contains(result, "folder/ok.lua")) + end + + function suite.matchfiles_OnDottedFile() + local result = os.matchfiles("base/.*") + test.istrue(table.contains(result, "base/.testDotFile")) + end + + function suite.matchfiles_onComboSearch() + local result = os.matchfiles("folder/**/*.txt") + test.istrue(table.contains(result, "folder/subfolder/hello.txt")) + end + + function suite.matchfiles_onSymbolicLink() + if os.istarget("macosx") + or os.istarget("linux") + or os.istarget("solaris") + or os.istarget("bsd") + then + os.execute("cd folder && ln -s subfolder symlinkfolder && cd ..") + local result = os.matchfiles("folder/**/*.txt") + os.execute("rm folder/symlinkfolder") + premake.modules.self_test.print(table.tostring(result)) + test.istrue(table.contains(result, "folder/symlinkfolder/hello.txt")) + end + end + + +-- +-- os.pathsearch() tests +-- + + function suite.pathsearch_ReturnsNil_OnNotFound() + test.istrue(os.pathsearch("nosuchfile", "aaa;bbb;ccc") == nil) + end + + function suite.pathsearch_ReturnsPath_OnFound() + test.isequal(_TESTS_DIR, os.pathsearch("_tests.lua", _TESTS_DIR)) + end + + function suite.pathsearch_FindsFile_OnComplexPath() + test.isequal(_TESTS_DIR, os.pathsearch("_tests.lua", "aaa;" .. _TESTS_DIR .. ";bbb")) + end + + function suite.pathsearch_NilPathsAllowed() + test.isequal(_TESTS_DIR, os.pathsearch("_tests.lua", nil, _TESTS_DIR, nil)) + end + + +-- +-- os.outputof() tests +-- + + -- Check if outputof returns the command exit code + -- in addition of the command output + function suite.outputof_commandExitCode() + if os.istarget("macosx") + or os.istarget("linux") + or os.istarget("solaris") + or os.istarget("bsd") + then + -- Assumes 'true' and 'false' commands exist + -- which should be the case on all *nix platforms + for cmd, exitcode in pairs ({ + ["true"] = 0, + ["false"] = 1 + }) + do + local o, e = os.outputof(cmd) + test.isequal(e, exitcode) + end + end + end + + -- Check outputof content + function suite.outputof_streams_output() + if (os.istarget("macosx") + or os.istarget("linux") + or os.istarget("solaris") + or os.istarget("bsd")) + and os.isdir (_TESTS_DIR) + then + local ob, e = os.outputof ("ls " .. _TESTS_DIR .. "/base") + local oo, e = os.outputof ("ls " .. _TESTS_DIR .. "/base", "output") + test.isequal (oo, ob) + local s, e = string.find (oo, "test_os.lua") + test.istrue(s ~= nil) + + local o, e = os.outputof ("ls " .. cwd .. "/base", "error") + test.istrue(o == nil or #o == 0) + end + end + +-- +-- os.translateCommand() tests +-- + + function suite.translateCommand_onNoToken() + test.isequal("cp a b", os.translateCommands("cp a b")) + end + + function suite.translateCommand_callsProcessor() + os.commandTokens.test = { + copy = function(value) return "test " .. value end + } + test.isequal("test a b", os.translateCommands("{COPY} a b", "test")) + end + + function suite.translateCommand_callsProcessor_multipleTokens() + os.commandTokens.test = { + copy = function(value) return "test " .. value end + } + test.isequal("test a b; test c d; test e f;", os.translateCommands("{COPY} a b; {COPY} c d; {COPY} e f;", "test")) + end + +-- +-- os.translateCommand() windows COPY tests +-- + + function suite.translateCommand_windowsCopyNoDst() + test.isequal('IF EXIST a\\ (xcopy /Q /E /Y /I a > nul) ELSE (xcopy /Q /Y /I a > nul)', os.translateCommands('{COPY} a', "windows")) + end + + function suite.translateCommand_windowsCopyNoDst_ExtraSpace() + test.isequal('IF EXIST a\\ (xcopy /Q /E /Y /I a > nul) ELSE (xcopy /Q /Y /I a > nul)', os.translateCommands('{COPY} a ', "windows")) + end + + function suite.translateCommand_windowsCopyNoQuotes() + test.isequal('IF EXIST a\\ (xcopy /Q /E /Y /I a b > nul) ELSE (xcopy /Q /Y /I a b > nul)', os.translateCommands('{COPY} a b', "windows")) + end + + function suite.translateCommand_windowsCopyNoQuotes_ExtraSpace() + test.isequal('IF EXIST a\\ (xcopy /Q /E /Y /I a b > nul) ELSE (xcopy /Q /Y /I a b > nul)', os.translateCommands('{COPY} a b ', "windows")) + end + + function suite.translateCommand_windowsCopyQuotes() + test.isequal('IF EXIST "a a"\\ (xcopy /Q /E /Y /I "a a" "b" > nul) ELSE (xcopy /Q /Y /I "a a" "b" > nul)', os.translateCommands('{COPY} "a a" "b"', "windows")) + end + + function suite.translateCommand_windowsCopyQuotes_ExtraSpace() + test.isequal('IF EXIST "a a"\\ (xcopy /Q /E /Y /I "a a" "b" > nul) ELSE (xcopy /Q /Y /I "a a" "b" > nul)', os.translateCommands('{COPY} "a a" "b" ', "windows")) + end + + function suite.translateCommand_windowsCopyNoQuotesDst() + test.isequal('IF EXIST "a a"\\ (xcopy /Q /E /Y /I "a a" b > nul) ELSE (xcopy /Q /Y /I "a a" b > nul)', os.translateCommands('{COPY} "a a" b', "windows")) + end + + function suite.translateCommand_windowsCopyNoQuotesDst_ExtraSpace() + test.isequal('IF EXIST "a a"\\ (xcopy /Q /E /Y /I "a a" b > nul) ELSE (xcopy /Q /Y /I "a a" b > nul)', os.translateCommands('{COPY} "a a" b ', "windows")) + end + + function suite.translateCommand_windowsCopyNoQuotesSrc() + test.isequal('IF EXIST a\\ (xcopy /Q /E /Y /I a "b" > nul) ELSE (xcopy /Q /Y /I a "b" > nul)', os.translateCommands('{COPY} a "b"', "windows")) + end + + function suite.translateCommand_windowsCopyNoQuotesSrc_ExtraSpace() + test.isequal('IF EXIST a\\ (xcopy /Q /E /Y /I a "b" > nul) ELSE (xcopy /Q /Y /I a "b" > nul)', os.translateCommands('{COPY} a "b" ', "windows")) + end + +-- +-- os.getWindowsRegistry windows tests +-- + function suite.getreg_nonExistentValue() + if os.ishost("windows") then + local x = os.getWindowsRegistry("HKCU:Should\\Not\\Exist\\At\\All") + test.isequal(nil, x) + end + end + + function suite.getreg_nonExistentDefaultValue() + if os.ishost("windows") then + local x = os.getWindowsRegistry("HKCU:Should\\Not\\Exist\\At\\All\\") + test.isequal(nil, x) + end + end + + function suite.getreg_noSeparators() + if os.ishost("windows") then + local x = os.getWindowsRegistry("HKCU:ShouldNotExistAtAll") + test.isequal(nil, x) + end + end + + function suite.getreg_namedValue() + if os.ishost("windows") then + local x = os.getWindowsRegistry("HKCU:Environment\\TEMP") + test.istrue(x ~= nil) + end + end + + function suite.getreg_namedValueOptSeparator() + if os.ishost("windows") then + local x = os.getWindowsRegistry("HKCU:\\Environment\\TEMP") + test.istrue(x ~= nil) + end + end + + function suite.getreg_defaultValue() + if os.ishost("windows") then + local x = os.getWindowsRegistry("HKLM:SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Minimal\\AppInfo\\") + test.isequal("Service", x) + end + end + + +-- +-- os.listWindowsRegistry windows tests +-- + function suite.listreg_nonExistentKey() + if os.ishost("windows") then + local x = os.listWindowsRegistry("HKCU:Should\\Not\\Exist\\At\\All") + test.isequal(nil, x) + end + end + + function suite.listreg_nonExistentKeyTrailingBackslash() + if os.ishost("windows") then + local x = os.listWindowsRegistry("HKCU:Should\\Not\\Exist\\At\\All\\") + test.isequal(nil, x) + end + end + + function suite.listreg_noSeparators() + if os.ishost("windows") then + local x = os.listWindowsRegistry("HKCU:ShouldNotExistAtAll") + test.isequal(nil, x) + end + end + + function suite.listreg_noSeparatorExistingPath() + if os.ishost("windows") then + local x = os.listWindowsRegistry("HKCU:Environment") + test.istrue(x ~= nil and x["TEMP"] ~= nil) + end + end + + function suite.listreg_optSeparators() + if os.ishost("windows") then + local x = os.listWindowsRegistry("HKCU:\\Environment\\") + test.istrue(x ~= nil and x["TEMP"] ~= nil) + end + end + + function suite.listreg_keyDefaultValueAndStringValueFormat() + if os.ishost("windows") then + local x = os.listWindowsRegistry("HKLM:SYSTEM\\CurrentControlSet\\Control\\SafeBoot\\Minimal\\AppInfo") + test.isequal(x[""]["value"], "Service") + test.isequal(x[""]["type"], "REG_SZ") + end + end + + function suite.listreg_numericValueFormat() + if os.ishost("windows") then + local x = os.listWindowsRegistry("HKCU:Console") + test.isequal(type(x["FullScreen"]["value"]), "number") + test.isequal(x["FullScreen"]["type"], "REG_DWORD") + end + end + + function suite.listreg_subkeyFormat() + if os.ishost("windows") then + local x = os.listWindowsRegistry("HKLM:") + test.isequal(type(x["SOFTWARE"]), "table") + test.isequal(next(x["SOFTWARE"]), nil) + end + end + +-- +-- os.getversion tests. +-- + + function suite.getversion() + local version = os.getversion(); + test.istrue(version ~= nil) + end + + + +-- +-- os.translateCommandsAndPaths. +-- + + function suite.translateCommandsAndPaths() + test.isequal('cmdtool "../foo/path1"', os.translateCommandsAndPaths("cmdtool %[path1]", '../foo', '.', 'osx')) + end + + function suite.translateCommandsAndPaths_PreserveSlash() + test.isequal('cmdtool "../foo/path1/"', os.translateCommandsAndPaths("cmdtool %[path1/]", '../foo', '.', 'osx')) + end + + function suite.translateCommandsAndPaths_MultipleTokens() + test.isequal('cmdtool "../foo/path1" "../foo/path2/"', os.translateCommandsAndPaths("cmdtool %[path1] %[path2/]", '../foo', '.', 'osx')) + end + + +-- +-- Helpers +-- + + local tmpname = function() + local p = os.tmpname() + os.remove(p) -- just needed on POSIX + return p + end + + local tmpfile = function() + local p = tmpname() + if os.ishost("windows") then + os.execute("type nul >" .. p) + else + os.execute("touch " .. p) + end + return p + end + + local tmpdir = function() + local p = tmpname() + os.mkdir(p) + return p + end + + +-- +-- os.remove() tests. +-- + + function suite.remove_ReturnsError_OnNonExistingPath() + local ok, err, exitcode = os.remove(tmpname()) + test.isnil(ok) + test.isequal("string", type(err)) + test.isequal("number", type(exitcode)) + test.istrue(0 ~= exitcode) + end + + function suite.remove_ReturnsError_OnDirectory() + local ok, err, exitcode = os.remove(tmpdir()) + test.isnil(ok) + test.isequal("string", type(err)) + test.isequal("number", type(exitcode)) + test.istrue(0 ~= exitcode) + end + + function suite.remove_ReturnsTrue_OnFile() + local ok, err, exitcode = os.remove(tmpfile()) + test.isequal(true, ok) + test.isnil(err) + test.isnil(exitcode) + end + + +-- +-- os.rmdir() tests. +-- + + function suite.rmdir_ReturnsError_OnNonExistingPath() + local ok, err = os.rmdir(tmpname()) + test.isnil(ok) + test.isequal("string", type(err)) + end + + function suite.rmdir_ReturnsError_OnFile() + local ok, err = os.rmdir(tmpfile()) + test.isnil(ok) + test.isequal("string", type(err)) + end + + function suite.rmdir_ReturnsTrue_OnDirectory() + local ok, err = os.rmdir(tmpdir()) + test.isequal(true, ok) + test.isnil(err) + end diff --git a/tests/test.bat b/tests/test.bat index f80ac6ea..1f6cd44d 100644 --- a/tests/test.bat +++ b/tests/test.bat @@ -1,4 +1,4 @@ -@echo off -pushd "%~dp0" -..\bin\debug\premake5.exe /scripts=.. /file=..\premake5.lua %* test -popd +@echo off +pushd "%~dp0" +..\bin\debug\premake5.exe /scripts=.. /file=..\premake5.lua %* test +popd From 371b3d02e705117845bffa91da3bc909f9a551dd Mon Sep 17 00:00:00 2001 From: Nicholaus Clark Date: Thu, 24 Jun 2021 11:53:10 -0400 Subject: [PATCH 12/19] Fix D compiler output for gmake and visual studio --- modules/d/_preload.lua | 5 +++++ modules/d/actions/gmake.lua | 10 +++++++++- modules/d/actions/visuald.lua | 7 ++++++- modules/d/tests/test_gmake.lua | 29 ++++++++++++++++++++++++++++- src/base/api.lua | 24 ++++++++++++++++++++++++ 5 files changed, 72 insertions(+), 3 deletions(-) diff --git a/modules/d/_preload.lua b/modules/d/_preload.lua index 44cf11ce..ed14b5b0 100644 --- a/modules/d/_preload.lua +++ b/modules/d/_preload.lua @@ -54,6 +54,11 @@ "ShowDependencies", }) + api.addAllowed("toolset", { + "dmd", + "gdc", + "ldc", + }) -- -- Register some D specific properties diff --git a/modules/d/actions/gmake.lua b/modules/d/actions/gmake.lua index 75bebc03..edb64171 100644 --- a/modules/d/actions/gmake.lua +++ b/modules/d/actions/gmake.lua @@ -205,7 +205,7 @@ -- identify the toolset used by this configurations (would be nicer if -- this were computed and stored with the configuration up front) - local toolset = p.tools[_OPTIONS.dc or cfg.toolset or "dmd"] + local toolset = m.make.getToolset(cfg) if not toolset then error("Invalid toolset '" + (_OPTIONS.dc or cfg.toolset) + "'") end @@ -217,6 +217,14 @@ end end + function m.make.getToolset(cfg) + local toolset, err = p.api.checkValue(p.fields.toolset, _OPTIONS.dc or cfg.toolset or "dmd") + if err then + error { msg=err } + end + return p.tools[toolset] + end + function m.make.dTools(cfg, toolset) local tool = toolset.gettoolname(cfg, "dc") if tool then diff --git a/modules/d/actions/visuald.lua b/modules/d/actions/visuald.lua index 5f8612c6..fef70c59 100644 --- a/modules/d/actions/visuald.lua +++ b/modules/d/actions/visuald.lua @@ -175,7 +175,12 @@ _p(2,'0') local compiler = { dmd="0", gdc="1", ldc="2" } - m.visuald.element(2, "compiler", compiler[_OPTIONS.dc or cfg.toolset or "dmd"]) + local compilerName, err = p.api.checkValue(p.fields.toolset, _OPTIONS.dc or cfg.toolset or "dmd") + if err then + error { msg=err } + end + + m.visuald.element(2, "compiler", compiler[compilerName]) m.visuald.element(2, "otherDMD", '0') m.visuald.element(2, "program", '$(DMDInstallDir)windows\\bin\\dmd.exe') diff --git a/modules/d/tests/test_gmake.lua b/modules/d/tests/test_gmake.lua index 9ef2f787..6604b091 100644 --- a/modules/d/tests/test_gmake.lua +++ b/modules/d/tests/test_gmake.lua @@ -30,7 +30,7 @@ local function prepare_cfg(calls) prj = p.workspace.getproject(wks, 1) local cfg = test.getconfig(prj, "Debug") - local toolset = p.tools.dmd + local toolset = m.make.getToolset(cfg) or p.tools.dmd p.callArray(calls, cfg, toolset) end @@ -193,3 +193,30 @@ all: $(TARGETDIR) $(OBJDIR) prebuild prelink $(TARGET) @: ]] end + + function suite.make_dTools_dmd() + toolset "dmd" + + prepare_cfg({ m.make.dTools }) + test.capture [[ + DC = dmd + ]] + end + + function suite.make_dTools_gdc() + toolset "gdc" + + prepare_cfg({ m.make.dTools }) + test.capture [[ + DC = gdc + ]] + end + + function suite.make_dTools_ldc() + toolset "ldc" + + prepare_cfg({ m.make.dTools }) + test.capture [[ + DC = ldc2 + ]] + end \ No newline at end of file diff --git a/src/base/api.lua b/src/base/api.lua index 3332f0dd..1623ff05 100755 --- a/src/base/api.lua +++ b/src/base/api.lua @@ -350,6 +350,13 @@ end else field.allowed = field.allowed or {} + + -- If we are trying to add where the current value is a function, + -- put the function in a table + if type(field.allowed) == "function" then + field.allowed = { field.allowed } + end + if field.allowed[value:lower()] == nil then table.insert(field.allowed, value) field.allowed[value:lower()] = value @@ -647,6 +654,23 @@ end end + + -- If a tool was not found, check to see if there is a function in the + -- table to check against. For each function in the table, check if + -- the value is allowed (break early if so). + if not canonical then + for _, allow in ipairs(field.allowed) + do + if type(allow) == "function" then + canonical = allow(value, kind or "string") + end + + if canonical then + break + end + end + end + if not canonical then return nil, "invalid value '" .. value .. "' for " .. field.name end From 1ce82af4d9885ff9d7f886cdcee97b9b445ce9ea Mon Sep 17 00:00:00 2001 From: Renaud Guillard Date: Mon, 21 Jun 2021 15:19:26 +0200 Subject: [PATCH 13/19] xcode4: Fix missing link of sibling project with custom targetextension When a node category cannot be determined by extension, use the configuration kind when available. Add unit test to illustrate the case. --- .../xcode/tests/test_xcode_dependencies.lua | 18 ++++++++++++++++++ modules/xcode/xcode_common.lua | 2 ++ 2 files changed, 20 insertions(+) diff --git a/modules/xcode/tests/test_xcode_dependencies.lua b/modules/xcode/tests/test_xcode_dependencies.lua index d6a55ad0..829c6c73 100644 --- a/modules/xcode/tests/test_xcode_dependencies.lua +++ b/modules/xcode/tests/test_xcode_dependencies.lua @@ -198,6 +198,24 @@ ]] end +function suite.PBXFrameworksBuildPhase_ListsDependencies_OnSharedLibWithTargetExtension() + kind "SharedLib" + targetextension ".plugin" + prepare() + xcode.PBXFrameworksBuildPhase(tr) + test.capture [[ +/* Begin PBXFrameworksBuildPhase section */ + 9FDD37564328C0885DF98D96 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6B7205267D294518F2973366 /* libMyProject2-d.plugin in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + ]] + end --------------------------------------------------------------------------- -- PBXCopyFilesBuildPhaseForEmbedFrameworks tests --------------------------------------------------------------------------- diff --git a/modules/xcode/xcode_common.lua b/modules/xcode/xcode_common.lua index b3057d35..b4373763 100644 --- a/modules/xcode/xcode_common.lua +++ b/modules/xcode/xcode_common.lua @@ -46,6 +46,8 @@ } if node.isResource then return "Resources" + elseif node.cfg and (node.cfg.kind == p.SHAREDLIB or node.cfg.kind == p.STATICLIB) then + return "Frameworks" end return categories[path.getextension(node.name)] end From 32ba709ffadc2dcf69ed6a532e0b1dea5556e211 Mon Sep 17 00:00:00 2001 From: Nicholaus Clark Date: Wed, 30 Jun 2021 00:30:53 -0400 Subject: [PATCH 14/19] Added D toolsets to documentation --- website/docs/toolset.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/website/docs/toolset.md b/website/docs/toolset.md index 77ebfd41..f083459c 100644 --- a/website/docs/toolset.md +++ b/website/docs/toolset.md @@ -10,12 +10,15 @@ If no toolset is specified for a configuration, the system or IDE default will b `identifier` is a string identifier for the toolset. Premake includes the following toolsets by default. -| **Toolset identifier** | **Description** | -|------------|------------------------------------------------| -| `clang` | [Clang](http://clang.llvm.org) | -| `dotnet` | The system's default C# compiler | -| `gcc` | [GNU Compiler Collection](https://gcc.gnu.org) | -| `msc` | Microsoft C/C++ compiler | +| **Toolset identifier** | **Description** | +|------------|---------------------------------------------------------------| +| `clang` | [Clang](http://clang.llvm.org) | +| `dmd` | [Reference D Compiler](https://dlang.org/dmd-windows.html) | +| `dotnet` | The system's default C# compiler | +| `gcc` | [GNU Compiler Collection](https://gcc.gnu.org) | +| `gdc` | [GNU Compiler Collection D Compiler](https://gdcproject.org/) | +| `ldc` | [LLVM D Compiler](https://wiki.dlang.org/LDC) | +| `msc` | Microsoft C/C++ compiler | If a specific toolset version is desired, it may be specified as part of the identifer, separated by a dash. See the examples below. From a70c67b7e78d63a852a56d9886e7c01a9b5df1d7 Mon Sep 17 00:00:00 2001 From: Jarod42 Date: Sun, 4 Jul 2021 00:22:22 +0200 Subject: [PATCH 15/19] compilebuildoutputs make some comments obsolete. --- website/docs/Custom-Build-Commands.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/website/docs/Custom-Build-Commands.md b/website/docs/Custom-Build-Commands.md index 979d6d54..8624f5e8 100644 --- a/website/docs/Custom-Build-Commands.md +++ b/website/docs/Custom-Build-Commands.md @@ -48,7 +48,8 @@ The basic syntax follows Visual Studio's model, but it should be easy to see how Build rules follow the same configuration scoping as the rest of the Premake API. You can apply rules to a specific platform or build configuration, to specific files or all files, or to any combination. And you can use [Tokens](Tokens.md) to create generic commands that will work across platforms and configurations. -If the outputs include any object files, they will be automatically added to the link step. Ideally, any source code files included in the outputs would be fed back into the build, but that is not the case currently. +If the outputs include any object files, they will be automatically added to the link step. +Any source code files included in the outputs might be fed back into the build with [compilebuildoutputs](compilebuildoutputs.md). Custom build commands currently have a few shortcomings. Help fixing these issues, or any other gaps, would be most appreciated! From d01e1179518962989f6f4d1f28e1cbd164239da8 Mon Sep 17 00:00:00 2001 From: Jarod42 Date: Sat, 3 Jul 2021 13:29:43 +0200 Subject: [PATCH 16/19] Handle `buildcommand` for Codelite. --- modules/codelite/codelite_project.lua | 36 ++++++++++++++- .../codelite/tests/test_codelite_config.lua | 45 +++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/modules/codelite/codelite_project.lua b/modules/codelite/codelite_project.lua index af356897..4396f0c0 100755 --- a/modules/codelite/codelite_project.lua +++ b/modules/codelite/codelite_project.lua @@ -377,7 +377,41 @@ _p(3, '') _p(4, '') - _p(4, '') + + local dependencies = {} + local rules = {} + local function addrule(dependencies, rules, config, filename) + if #config.buildcommands == 0 or #config.buildOutputs == 0 then + return + end + local inputs = table.implode(config.buildInputs,"",""," ") + if filename ~= "" and inputs ~= "" then + filename = filename .. " " + end + local outputs = config.buildOutputs[1] + local buildmessage = "" + if config.buildmessage then + buildmessage = "\t@{ECHO} " .. config.buildmessage .. "\n" + end + local commands = table.implode(config.buildCommands,"\t","\n","") + table.insert(rules, os.translateCommandsAndPaths(outputs .. ": " .. filename .. inputs .. "\n" .. buildmessage .. commands, cfg.project.basedir, cfg.project.location)) + table.insertflat(dependencies, config.buildOutputs[1]) + end + local tr = project.getsourcetree(cfg.project) + p.tree.traverse(tr, { + onleaf = function(node, depth) + local filecfg = p.fileconfig.getconfig(node, cfg) + addrule(dependencies, rules, filecfg, node.relpath) + end + }) + addrule(dependencies, rules, cfg, "") + + if #rules == 0 and #dependencies == 0 then + _p(4, '') + else + _p(4, '' .. table.implode(dependencies,"",""," ")) + _p(0, table.implode(rules,"","","\n") .. '') + end _p(3, '') end diff --git a/modules/codelite/tests/test_codelite_config.lua b/modules/codelite/tests/test_codelite_config.lua index 4a72da68..193e335e 100644 --- a/modules/codelite/tests/test_codelite_config.lua +++ b/modules/codelite/tests/test_codelite_config.lua @@ -203,6 +203,51 @@ ]] end + function suite.OnProjectCfg_BuildCommand() + files {"/c/foo.txt", "/c/bar.txt"} + buildinputs { "/c/toto.txt", "/c/extra_dependency" } + buildoutputs { "/c/toto.c" } + buildcommands { "test", "test /c/toto.c" } + buildmessage "Some message" + prepare() + codelite.project.additionalRules(cfg) + test.capture [[ + + + /c/toto.c +/c/toto.c: /c/toto.txt /c/extra_dependency + @echo Some message + test + test /c/toto.c + + ]] + end + + function suite.OnProjectCfg_BuildCommandPerFile() + files {"/c/foo.txt", "/c/bar.txt"} + filter "files:**.txt" + buildinputs { "/c/%{file.basename}.h", "/c/extra_dependency" } + buildoutputs { "/c/%{file.basename}.c" } + buildcommands { "test", "test /c/%{file.basename}" } + buildmessage "Some message" + prepare() + codelite.project.additionalRules(cfg) + test.capture [[ + + + /c/bar.c /c/foo.c +/c/bar.c: /c/bar.txt /c/bar.h /c/extra_dependency + @echo Some message + test + test /c/bar + +/c/foo.c: /c/foo.txt /c/foo.h /c/extra_dependency + @echo Some message + test + test /c/foo + + ]] + end function suite.OnProjectCfg_General() system "Windows" From 871057e688f2ca4bece091d4ffd38ab7233d240a Mon Sep 17 00:00:00 2001 From: starkos Date: Wed, 14 Jul 2021 13:53:17 -0400 Subject: [PATCH 17/19] Prefer embedded modules during release build bootstrapping --- src/_premake_main.lua | 19 ++++++++++++++----- src/host/os_locate.c | 6 ++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/_premake_main.lua b/src/_premake_main.lua index ce6c2e43..a19fcbe6 100644 --- a/src/_premake_main.lua +++ b/src/_premake_main.lua @@ -68,6 +68,12 @@ name .. ".lua" } + -- If this module is being requested by an embedded script, favor embedded modules. + -- This helps prevent local scripts from interfering with release build bootstrapping. + if string.startswith(_SCRIPT_DIR, '$/') then + table.insert(paths, 1, '$/' .. full) + end + -- try to locate the module for _, p in ipairs(paths) do local file = os.locate(p) @@ -118,8 +124,9 @@ local preloader = name .. "/_preload.lua" preloader = os.locate("modules/" .. preloader) or os.locate(preloader) if preloader then - m._preloaded[name] = include(preloader) - if not m._preloaded[name] then + local modulePath = path.getdirectory(preloader) + m._preloaded[modulePath] = include(preloader) + if not m._preloaded[modulePath] then p.warn("module '%s' should return function from _preload.lua", name) end else @@ -306,9 +313,11 @@ end -- any modules need to load to support this project? - for module, func in pairs(m._preloaded) do - if not package.loaded[module] and shouldLoad(func) then - require(module) + for modulePath, func in pairs(m._preloaded) do + local moduleName = path.getbasename(modulePath) + if not package.loaded[moduleName] and shouldLoad(func) then + _SCRIPT_DIR = modulePath + require(moduleName) end end end diff --git a/src/host/os_locate.c b/src/host/os_locate.c index b72b1576..e1fab7d8 100644 --- a/src/host/os_locate.c +++ b/src/host/os_locate.c @@ -36,6 +36,12 @@ int os_locate(lua_State* L) for (i = 1; i <= nArgs; ++i) { const char* name = lua_tostring(L, i); + /* Direct path to an embedded file? */ + if (name[0] == '$' && name[1] == '/' && premake_find_embedded_script(name + 2)) { + lua_pushvalue(L, i); + return 1; + } + /* Direct path to file? Return as absolute path */ if (do_isfile(L, name)) { lua_pushcfunction(L, path_getabsolute); From 2cc5eff84f878bc039a6c349fc4ad57b48792c85 Mon Sep 17 00:00:00 2001 From: Nicholaus Clark Date: Mon, 26 Jul 2021 13:52:52 -0400 Subject: [PATCH 18/19] Updated sidebar to include toolsversion link --- website/sidebars.js | 1 + 1 file changed, 1 insertion(+) diff --git a/website/sidebars.js b/website/sidebars.js index f160448e..4e996b35 100644 --- a/website/sidebars.js +++ b/website/sidebars.js @@ -219,6 +219,7 @@ module.exports = { 'targetprefix', 'targetsuffix', 'toolset', + 'toolsversion', 'undefines', 'usingdirs', 'uuid', From 142abd70a561aa67c4ba726542ce15c2d51f8b4d Mon Sep 17 00:00:00 2001 From: starkos Date: Sat, 31 Jul 2021 12:43:07 -0400 Subject: [PATCH 19/19] Add Community Update #9 --- website/blog/2021-08-01-community-update-9.md | 61 +++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 website/blog/2021-08-01-community-update-9.md diff --git a/website/blog/2021-08-01-community-update-9.md b/website/blog/2021-08-01-community-update-9.md new file mode 100644 index 00000000..5f28db45 --- /dev/null +++ b/website/blog/2021-08-01-community-update-9.md @@ -0,0 +1,61 @@ +--- +title: "Community Update #9" +tags: [community-updates] +author: starkos +author_url: https://github.com/starkos +author_image_url: https://avatars.githubusercontent.com/u/249247?v=4 +author_title: Premake Admin & Developer +--- + +I can't believe we're already eight months into 2021, how did this happen. + +### **Branch, don't backport** + +In the last update, I asked for input on where the work going into [premake-next](https://github.com/starkos/premake-next) should end up: branch a new 6.x major version, or backport the changes to 5.x? There was [solid consensus](https://github.com/premake/premake-core/discussions/1616) that premake-next should be treated as a new major version, with v5 upgraded to a stable release for on-going support. Thanks to everyone who participated and offered feedback! + +With that settled, I've archived the premake-next repository and moved all development to [a new 6.x branch on premake-core](https://github.com/premake/premake-core/tree/6.x). As of the next release, I'll be upgrading the status of 5.0 from alpha to beta, with the intention of making the first stable release shortly. + +### The Path to 5.0 + +Premake's perpetual alpha status [causes confusion](https://github.com/premake/premake-core/issues/1536) and makes it [difficult for some people to adopt](https://github.com/premake/premake-core/issues/1423). We've been hanging on to that label in the hope we'd get a chance to overhaul the makefile and Xcode exporters. But now that we have a v6 branch it makes sense break things over there instead, and get v5 to a stable release sooner rather than later. + +I've [opened a 5.0 milestone](https://github.com/premake/premake-core/milestone/3) on the project and will be assigning a few issues to myself there. If you have a backward-compatibility breaking change that you feel must get in before 5.0 becomes stable, open or escalate an issue ASAP so we can get it on the roadmap. And as ever, we're all really busy, so any help getting this over the finish line is much appreciated! + +### Premake6 + +In other news, Premake6 can now generate its own Visual Studio project files and bootstrap itself. That doesn't sound very impressive, but it does means that all of the under the hood stuff is now online and working as intended, and a full vertical slice has been completed. 🎉 + +[@nickclark2016](https://github.com/nickclark2016) has volunteered to begin looking into a new-and-improved makefile exporter, which frees me up to start looking at Xcode and improving the way we represent toolsets like Clang and GCC. The stable release of 5.0 is likely to take up all the air in the room for a bit, but hopefully I can report progress on those soon. + +### Community Contributions + +The community keeps things rolling—many thanks to everyone listed here! + +- [#1570](https://github.com/premake/premake-core/pull/1570) Initial C++20 module support for Visual Studio ([@hannes-harnisch](https://github.com/hannes-harnisch)) +- [#1625](https://github.com/premake/premake-core/pull/1625) Remove "*ng" action deprecation and auto-fix ([@noresources](https://github.com/noresources)) +- [#1635](https://github.com/premake/premake-core/pull/1635) Fix typo in Using Premake documentation ([@abhiss](https://github.com/abhiss)) +- [#1638](https://github.com/premake/premake-core/pull/1638) Fix broken links in docs ([@KyrietS](https://github.com/KyrietS)) +- [#1642](https://github.com/premake/premake-core/pull/1642) Fix spelling mistake ([@Troplo](https://github.com/Troplo)) +- [#1644](https://github.com/premake/premake-core/pull/1644) Fix author name and update time on pages ([@KyrietS](https://github.com/KyrietS)) +- [#1645](https://github.com/premake/premake-core/pull/1645) Add missing support for prebuildmessage/postbuildmessage for Codelite ([@Jarod42](https://github.com/Jarod42)) +- [#1649](https://github.com/premake/premake-core/pull/1649) Fix curl header search path ([@depinxi](https://github.com/depinxi)) +- [#1654](https://github.com/premake/premake-core/pull/1654) xcode4: Fix missing link of sibling project with custom targetextension ([@depinxi](https://github.com/depinxi)) +- [#1655](https://github.com/premake/premake-core/pull/1655) Compiler Version support for Visual Studion 2017+ ([@nickclark2016](https://github.com/nickclark2016)) +- [#1657](https://github.com/premake/premake-core/pull/1657) Renormalize line endings ([@nickclark2016](https://github.com/nickclark2016)) +- [#1663](https://github.com/premake/premake-core/pull/1663) compilebuildoutputs make some comments obsolete ([@Jarod42](https://github.com/Jarod42)) +- [#1668](https://github.com/premake/premake-core/pull/1668) Fix v6 bootstrapping from v5 ([@starkos](https://github.com/starkos)) +- [#1673](https://github.com/premake/premake-core/pull/1673) Updated sidebar to include toolsversion link ([@nickclark2016](https://github.com/nickclark2016)) +- [#1662](https://github.com/premake/premake-core/pull/1662) Handle buildcommand for Codelite ([@Jarod42](https://github.com/Jarod42)) +- [#1658](https://github.com/premake/premake-core/pull/1658) Fix D module compiler output for visual studio ([@nickclark2016](https://github.com/nickclark2016)) + +Additional gratitude and good wishes to everyone who helped review pull requests and triage issues this cycle. Projects like this don't work without you. + + + +A big shout out to our premier sponsor **[Cfx.re](https://opencollective.com/_fivem)** and all [our monthly backers](https://opencollective.com/premake#section-contributors)—be sure to check out their work and support them back if you can! + +I welcome questions, suggestions, and concerns. Message or DM me at [@premakeapp](https://twitter.com/premakeapp), email at [starkos@industriousone.com](mailto:starkos@industriousone.com), or [open a discussion on GitHub](https://github.com/premake/premake-core/discussions).