premake-core: 'links' doesn't follow dependency on static libs projects

project "A"
  kind "StaticLib"
...
project "B"
  kind "StaticLib"
  links {"A"}
...
project "C"
  kind "StaticLib"
  links {"B"}

project "App"
  kind "ConsoleApp
  links {"C"} --> not going to be built, since B and A are not included

When there is links dependency on another project, which is a static lib, premake should include all the static lib dependencies of that as well. Otherwise user has to include all of them explicitly in the resulting app or DLL. ( links {"C", "A", "B"} for the App in the example above) Which is troublesome, since the list of libs might be conditional (platform dependent, for example) and user will have to copy/paste the conditions several times over. Note, this isn’t a problem for dlls, only for static libraries. Since dll has all it’s dependencies built in already.

About this issue

  • Original URL
  • State: open
  • Created 8 years ago
  • Reactions: 7
  • Comments: 17 (13 by maintainers)

Most upvoted comments

@dsvi it sounds like you’ve found the right tool for your task. Thank you for sharing your opinion on CMake and Premake with us. However, I have to ask you to refrain from posting antagonistic comments otherwise we’ll be forced to block you from the project.

Also seen this issue, it is specific in gmake, in Visual Studio this problem does not happen.

Oh yeah, we tried this, and made a commit for that… which got quickly rolled back because premake times for some of @starkos his projects went from seconds to minutes. I’m sure we did something wrong…

Arguably however a static lib linking against another static lib creates a hard order dependency on build order and a sync point… which in a paralllel build isn’t really very efficient…

For example, in the example provided above… project B can’t start compiling until project A is done compiling. Although technically not entirely true, since all projects could easily compile, they just have to wait linking… but that is just not how Visual Studio treats these dependencies… so in practice what you’ll see is that B waits for A to finish then C waits for B to finish, and then App compiles and links… For a small project not really a big deal… but now throw a 5 million line codebase at it, and try building it through XGE (Incredibuild), and the entire project serializes…

So our solution at the time (what we tried to merge, but failed at), was to treat “links” in libs are “virtual dependencies” in premake, and resolve them down to the application. So despite you writing what you wrote above, premake would treat it as if you wrote

project "App"
  kind "ConsoleApp
  links {"A", "B", "C"}

because from a parallel build perspective that is most efficient… A, B, and C would all be order independent, and only App would have to wait for all three to finish…

Anyway, ultimately I think with whatever solution we end up with, this is a very important consideration. I’d be happy to make another attempt some day… but it’s non-trivial to get right and fast…

The reason why it does not happen in VS, is because VS does it itself. From quick look at the sources of premake the function config.getlinks(cfg, kind, part, linkage) simply doesn’t follow any dependencies for a static lib In general premake lacks the notion of dependencies at all. You can’t tell it “to use this library add those defines, include paths, and libs” like you can in more modern build systems.