premake / premake-4.x Goto Github PK
View Code? Open in Web Editor NEWPremake 4
License: BSD 3-Clause "New" or "Revised" License
Premake 4
License: BSD 3-Clause "New" or "Revised" License
This took me a while to track down.
In path_translate
from path_translate.c
the handling is wrong in cases where a table is passed. The lua_next
function requires that the keys in the table not be changed (or new values inserted, which also means a change of keys).
However, the luaL_checkstring
will just do that in cases where the key is not a string and convert it into a string.
Reference: http://stackoverflow.com/a/6142700
The error would then be invalid key to 'next'
which indicates that the key of a table was changed mid-iteration:
invalid key to 'next'
stack traceback:
[C]: in function 'builtin_translate'
src/base/path.lua:148: in function 'translate'
D:/premake-wds/src/actions/vstudio/vs200x_vcproj.lua:366: in function '?'
D:/premake-wds/src/actions/vstudio/vs200x_vcproj.lua:743: in function 'callback'
D:/premake-wds/src/base/premake.lua:32: in function 'orig_generate'
D:/premake-wds/premake4.lua:72: in function 'generate'
D:/premake-wds/src/actions/vstudio/_vstudio.lua:322: in function 'onproject'
D:/premake-wds/src/base/action.lua:59: in function 'call'
src/_premake_main.lua:155: in function <src/_premake_main.lua:53>
(it's from my fork of premake4, but the same generally applies to other premake4 flavors and possibly even premake5).
The fix is trivial. Take a copy of the key, then use luaL_checkstring
on the copy and pop 2 values from the stack instead of one.
Here's the changed condition:
if (lua_istable(L, 1)) {
int i = 0;
lua_newtable(L);
lua_pushnil(L);
while (lua_next(L, 1)) {
const char* key;
lua_pushvalue(L, 4); // copy the key
key = luaL_checkstring(L, 5);
translate(buffer, key, sep[0]);
lua_pop(L, 2);
lua_pushstring(L, buffer);
lua_rawseti(L, -3, ++i);
}
return 1;
}
I noticed this because .hgignore
always ended up in the ["Header Files/*"] = { "*.hpp", "*.h", },
vpaths-mapping, despite there being another mapping with which I attempted to map .hgignore
without any wildcard characters. The same evidently happens/happened for .clang-format
.
The path.wilcards()
function returns a match string that isn't anchored to the beginning and end of the string respectively, so returning matches when it would not be expected.
I think the appropriate way would be (or rather have been) to have path.wildcards()
return patterns anchored between ^
and $
, i.e. the beginning and end of a string respectively. But in this particular case it's rather finicky to work around this from the outside.
The issue with that seems to be that -- for obvious reasons -- the name path.wildcards
is already bound by the time I try to manipulate it.
Essentially I have replace this single line by something along the lines of (not knowing, however, how much else this may influence or how many existing premake4.lua
files it'd break):
local wildcards = "^" .. path.wildcards(pattern) .. "$"
local i = abspath:find(wildcards)
... to get my proverbial foot in the door. Still, only thanks to the way Premake4 was designed, it's possible without having to patch the C part of it.
This does not happen when replacement
(the key in the vpaths
table) is an empty string, btw.
Somewhere in your premake4.lua
place this code:
do
local orig_getvpath = premake.project.getvpath
premake.project.getvpath = function(prj, abspath)
for replacement, patterns in pairs(prj.vpaths or {}) do
for _, pattern in ipairs(patterns) do
if abspath == pattern then
local stem, _ = replacement:gsub("%*", "")
return path.join(stem, abspath)
end
end
end
return orig_getvpath(prj, abspath)
end
end
What it does is to replace premake.project.getvpath()
with our own code, retaining a "function pointer" to the original function.
Then it goes through all replacements and respective patterns, looking for exact matches between patterns and path -- which should reasonably only happen whenever the pattern (and path) contain no wildcard characters anyway -- and if that was found uses a stripped down version of the logic in the original getvpath()
and returns its result at the first match. This is exactly the behavior I would have expected when there are no wildcard characters in the pattern, but which wasn't the case due to using string.find
without anchors.
FYI: I don't expect anyone but myself to fix/address this. However, perhaps it helps someone else who still uses Premake4 or raises awareness on that issue for Premake5 (I don't know how related the code bases truly are).
Here's one failed attempt:
do
if premake.project.getvpath then
local orig_getvpath = premake.project.getvpath
premake.project.getvpath = function(prj, abspath)
local orig_wildcards = path.wildcards
-- just for a single call, fix up the wildcards() function
path.wildcards = function(pattern)
return "^" .. orig_wildcards(pattern) .. ""
end
local retval = orig_getvpath(prj, abspath)
path.wildcards = orig_wildcards -- reset back to the original value
return retval
end
end
end
This method also fails (filteridgroup
and getfilegroup
respectively use the premake.project.eachfile
function, which I hoped to influence this way):
do
local orig_wildcards = path.wildcards
local orig_filteridgroup = premake.vstudio.vc2010.filteridgroup
local orig_getfilegroup = premake.vstudio.vc2010.getfilegroup
local replacement_wildcards = function(pattern)
return "^" .. orig_wildcards(pattern) .. ""
end
premake.vstudio.vc2010.filteridgroup = function(prj)
path.wildcards = replacement_wildcards -- just for a single call, fix up the wildcards() function
local retval = orig_filteridgroup(prj)
path.wildcards = orig_wildcards -- reset back to the original value
return retval
end
premake.vstudio.vc2010.getfilegroup = function(prj, group)
path.wildcards = replacement_wildcards -- just for a single call, fix up the wildcards() function
local retval = orig_getfilegroup(prj, group)
path.wildcards = orig_wildcards -- reset back to the original value
return retval
end
end
Bazel is a powerful build system made by Google: https://bazel.build/
Is it planned to support it, by adding a Bazel action?
If not, would be the contribution of such an action accepted? Before acceptance, how is an action is tested for correctness?
Bazel uses BUILD files to describe the project. The same action logic could be used to support Facebooks build system, Buck, which uses BUCK files, which shares the syntax and semantics.
In https://github.com/premake/premake-4.x/blob/master/BUILD.txt, a mere mention of the following:
If you pulled the sources from BitBucket, you'll need to generate your
own project files before you can build.
when I pulled it from GitHub... too bad, we can't find the build subdirectory.
premake4 cannot be built as downloaded into a CentOS 6.5 without intensive out-reach to pull in packages to build this.
A non-starter, no?
solution "TestSolution"
configurations {"Debug", "Release"}
location "codeblocks"
project "Test"
kind "ConsoleApp"
language "C++"
files {"**.cpp", "**.h"}
links {"GL", "glfw", "GLEW"}
includedirs {"/usr/local/include", "/usr/include", "src/headers"}
libdirs {"/usr/lib", "/usr/local/lib64"}
location "codeblocks/Test"
file = io.open("codeblocks/run.sh", "w");
file:write("export LIBGL_ALWAYS_SOFTWARE=1\n./bin/Debug/Test")
file:close()
I will refer as $ROOT as the directory where premake4.lua exists.
When I build the project, codeblocks generates the debug/release binaries in the $ROOT
directory. Why is that? Shouldn't it build them in $ROOT/codeblocks/bin/Debug or Release/ directory?
I open the codeblock workspace from the .workspace file inside $ROOT/codeblocks/TestSolution.workspace which is generated by premake.
Thanks.
There are 3 pages in the wiki with incorrect links to Premake4 download page:
The first two of them point to "http://premake.github.io/premake-core/download.html" and the third one has a link to "http://premake.github.io/download.html".
All of them are incorrect. It's not possible to download Premake4 binary from our new website. I don't even now how to get a binary of Premake4 at this moment π
The current code, namely vs2010_vcxproj.lua doesn't use resdefines
at all. I just noticed this by accident. I'll definitely write a Lua-only workaround for this, but I still need to set up myself to contribute back changes from my (still Mercurial based) repo.
Unfortunately the function preprocessor
is a local
one, which makes the planned workaround more cumbersome than it would otherwise be. Likely another case where io.capture()
is called for.
When creating a shared library (MathLib.dll) on Windows using premake4, and running the generated makefile, in fact 2 targets are created: MathLib.dll (25 KB) and a file (libMath.a of 2 KB size). The libMath.a file seems to be a dummy (empty) static library, since it is only of 2K size. Also it isnβt cleaned up when executing premake clean.
What's happening is that when I create a shared library using premake4, it creates it alright, but it also creates a dummy static library! In fact, this is more serious than it sounds, because if there had been a (genuine) static library of that name in the directory containing the libraries, then when I run premake to create a shared library, the new (dummy/empty) static library erroneously created by premake, OVERWRITES AND REPLACES the genuine static library of the same name that was already existing in the dir.
A workaround may be to avoid creating the libraries in a common dir initially, but instead create in a separate (local) dir, perhaps the same as the one containing the (shared library creation) source files and then copy the (genuine) library to the final common library dir.
Is there any way to prevent creation of this spurious static library?
The premake file contains:
`solution "MathLib"
configurations { "Debug", "Release" }
-- A project defines one build target
project "MathLib"
kind "SharedLib"
language "C++"
files { ".h", ".cpp" }
-- Create target library in Files > C > SW >
-- Applications > ProgramLibraries
targetdir "../../../ProgramLibraries/"
configuration "Debug"
defines { "DEBUG" }
flags { "Symbols" }
configuration "Release"
defines { "NDEBUG" }
flags { "Optimize" }
-- Register the "runmakefile" action.
newaction
{
trigger = "runmakefile",
description = "run the generated makefile to create the executable using the default (debug config)",
execute = function()
os.execute("make")
end
}
-- Register the "runmakefilerelease" action.
newaction
{
trigger = "runmakefilerelease",
description = "run the generated makefile to create the executable using the 'release' config)",
execute = function()
os.execute("make config=release")
end
}`
The links
function blindly appends .lib
to the dependencies when the action is one of the vs*
values. Unfortunately this collides with the desire to sometimes link to object files provided directly by Microsoft. Examples are thrownew.obj
(and nothrownew.obj
), hotpatch.obj
, pnoarg.obj
and setargv.obj
(setargv.obj
etc). The latter is useful to link POSIX utilities which expect the command line arguments to already be expanded, whereas on Windows the application itself is usually expected to handle wild cards.
As a side-note, my fix to the issue is this one (pure Lua):
-- Fix up premake.getlinks() to not do stupid stuff with object files we pass
local orig_premake_getlinks = premake.getlinks
premake.getlinks = function(cfg, kind, part)
local origret = orig_premake_getlinks(cfg, kind, part)
local ret = {}
for k,v in ipairs(origret) do
local dep = v:gsub(".obj.lib", ".obj")
dep = dep:gsub(".lib.lib", ".lib")
table.insert(ret, dep)
end
return ret
end
Running precompiled Windows version of premake with a simple target, e.g.
premake codeblocks
gives an error:
No Premake script (premake4.lua) found!
I would like premake to simply generate something like a .bat file with the cl
command that would compile the project. I don't want to generate an entire Visual Studio solution. I find that to be completely unnecessary. I just want Premake to build the cl
command for me.
Thank you.
There are clearly pages in that section, but if you follow the link, you get a 'new page' creation page.
While trying to build Google Test on OS X, using http://jimgarrison.org/techblog/googletest-premake4.html, I ran into "ld: internal error: atom not found in symbolIndex ..." error. As seen before in http://industriousone.com/topic/how-remove-flags-ldflags, removal of the flags in the makefiles fixes the issue. gcc.lua has been updated since the last issue, but it seems to be an issue with Yosemite. I commented out lines 140-146 ("if not cfg.flags.Symbols then" ...) in gcc.lua, but I'm sure a more elegant solution would check for the OS version. After commenting those lines out, everything has worked.
OS:
System Version: OS X 10.10.3 (14D136)
Kernel Version: Darwin 14.3.0
Clang:
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.3.0
Thread model: posix
Thanks for your hard work! I really enjoy using Premake.
Hey,
Really sorry if this is documented, I couldn't for the life of me find out if this is or isn't possible....
I have a project file generated by another build system in a project, and I'd like to know if it's possible to link that project into the solution I generate with premake?
Specifically I'm generating a vs2015 project of a dependency GYP, and I'd like to be able to manage this from the VS2017 solution I generate with premake4.
If I have to downgrade one or upgrade the other to make them match, I can live with that so long as it's possible. If this isn't possible at all, that's fine too - would just be good to know!
Thanks :) π
The file src\actions\vstudio\vs2010_vcxproj.lua
contains this:
if cfg.flags.Symbols then
_p(3,'<ProgramDataBaseFileName>$(OutDir)%s.pdb</ProgramDataBaseFileName>'
, path.getbasename(cfg.buildtarget.name))
end
There are two issues with this. For starters instead of retrieving the base name, the code should arguably make use of the $(TargetName)
macro. If possible incompatibilities of pre-VS2010 versus VS2010+ are of concern here, one could implement a shallow function using a map (Lua table
) to transform macro names (see bottom). So arguably it should have read:
if cfg.flags.Symbols then
_p(3,'<ProgramDataBaseFileName>$(OutDir)$(TargetName)</ProgramDataBaseFileName>')
end
The second issue is the bigger one. There are two PDBs usually involved during compilation. One by the linker and one by the compiler. This explains why we receive a C1052 error.
The instance of <ProgramDataBaseFileName />
is meant to be the compiler one (inside <ClCompile />
). However, its default value is normally $(IntDir)vc$(PlatformToolsetVersion).pdb
(as per the above linked MSDN resource).
So when Premake sets it to what amounts to $(OutDir)$(TargetName)
that clashes with the implicit value used for the linker PDB. That's why if I change a single source file - e.g. during debugging - and then press F5, instead of compiling, linking and debugging, I get the above mentioned error C1052.
The solution is to leave out the <ProgramDataBaseFileName />
element altogether and have it use its default. However, when looking for flags.Symbols
in aforementioned .lua file, there's a second instance with a similar condition. That one positively must stay for otherwise we can't control whether a PDB file gets generated at all.
Best regards,
Oliver
PS: I found a mention of this issue over here. What struck me as odd, at best, was the lack of mentioning @starkos in the copyright notice of the README for that project, albeit claiming to be (and visibly being) a fork of Premake4.
PPS: I've made use of the following function to translate macro names in my own premake4.lua files for quite some time now:
local function transformMN(input) -- transform the macro names for older Visual Studio versions
local new_map = { vs2002 = 0, vs2003 = 0, vs2005 = 0, vs2008 = 0 }
local replacements = { Platform = "PlatformName", Configuration = "ConfigurationName" }
if new_map[action] ~= nil then
for k,v in pairs(replacements) do
if input:find(k) then
input = input:gsub(k, v)
end
end
end
return input
end
With gmake, when I build a shared library and an executable that links to it, the resulting makefile uses static linking to the .so file instead of using "-l" to link to it. The resulting executable will work with the .so file but only under very specific conditions. If I hand edit the makefile to use "-l" and move the .so file somewhere in my search path the executable works then.
Sorry if this isn't clear but it's a little hard to explain.
I have a tar.gz file with a complete project with source files to demonstrate this problem. Unfortunately I can't attach it here. I'll send it via email if you want.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. πππ
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google β€οΈ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.