Differentiate between static and shared prebuilt libraries

349 views
Skip to first unread message

Brian Riis

unread,
Aug 24, 2015, 10:13:07 AM8/24/15
to Premake Development
Hi,

In this SO post you mention that using both static and shared libraries is not hard to fix.

As for others, I'm sure, this functionality is fairly essential to me, and I thought I might take a look at implementing it. I see a couple of issues to be tackled:
  1. `links()` merely takes a list of libraries to link to. To differentiate we need to tell premake if the given library is static or shared.
  2. When outputting `-lLibrary` to make, we need to group static libraries and prefix them with `-Wl,-Bstatic`, then the shared libraries prefixes with `-Wl,-Bdynamic`. I don't know if similar considerations are necessary for other toolchains than clang and gcc, but I expect so.
To differentiate, I see two immediate options: Either we specify it in the call to `links()` or we pre-declare the prebuilt library and specify the kind at declaration-time. The first option is fairly easy, if we only use the link once, but becomes verbose. The second option seems cleaner to me. I imagine a declaration like this:

project "PrebuiltLibrary"
   kind
"StaticLib"
   file
"prebuilt_lib"

project
"PrebuiltLibrary2"
   kind
"SharedLib"
   file
"prebuilt_lib2"

project
"MyProgram"
   kind
"ConsoleApp"
   language
"C++"
   files
{ "src/*.cpp" }
   links
{ "PrebuiltLibrary", "PrebuiltLibrary2" }

For gcc this would output `gcc -o MyProgram <object files> -Wl,-Bstatic -lprebuilt_lib -Wl,-Bdynamic -lprebuild_lib2`.

Thoughts...?

 /Brian

starkos

unread,
Aug 24, 2015, 12:00:55 PM8/24/15
to Premake Development
The previous proposal was a syntax like:

links { "PrebuiltLibrary:static", "PrebuiltLibrary2:shared" }


I could have sworn that I did some work to support the ":<value>" modifiers syntax on API calls but I can't seem to locate it. It must have been for a client project; I'll see if I can dig it up.

Brian Riis

unread,
Aug 24, 2015, 3:46:56 PM8/24/15
to Premake Development
Yep, that was what I meant by "specify it in the call to `links()`". My concern is that it may get overly verbose. On the other hand, it seems fairly easy to do.

Jeremiah Ong

unread,
Aug 24, 2015, 4:14:05 PM8/24/15
to Premake Development
Personally, I dislike this syntax proposal. If the project is defined
elsewhere and already declared to be static or dynamic, why would we
want to specify it as such again later on?

(@Brian sorry if you receive this twice. I replied first via email. Is there a reason this is disallowed?)

starkos

unread,
Aug 24, 2015, 4:24:39 PM8/24/15
to Premake Development
If you are linking to one of your own projects you should not have to specify any decorators. This would only be for system or third-party libraries which you are not building yourself.

And, for convenience and backwards compatibility, Premake ought to do something sensible if no decorator is specified for those libraries too. Presumably treat them as shared?

Brian Riis

unread,
Aug 24, 2015, 4:24:57 PM8/24/15
to Premake Development
I did get it twice. Nevermind. :-)

I'm not sure, what you're saying though. Which syntax proposal don't you like? Both?

For the record, this is about prebuilt libraries, not your own internal projects. For those, you already have control. The question is what to do when you need to link to a prebuilt library, maybe even one where both static and dynamic versions are available. I need a way to say that I want to link to - say - libboost_filesystem.a, not libboost_filesystem.so. Also, gcc is picky about being told which is which. This is the problem we're trying to solve, and saying `links { "boost_filesystem" }` is not enough.

If neither syntax is good (which is OK by me! :-)) do you have an alternative suggestion? I prefer the explicit version, where we pre-declare each library, but `links { "boost_filesystem:static" }` would work too. You only need to specify the "decoration" if it matters.

Jeremiah Ong

unread,
Aug 24, 2015, 4:30:18 PM8/24/15
to Premake Development
@starkos Makes sense I was basing my opinion on what was shown in the stack overflow post.

I imagine premake could actually try to guess based on file extension (so lib vs dy lib or dll) but otherwise the decorator seems reasonable.

Bastien Brunnenstein

unread,
Aug 25, 2015, 4:15:00 AM8/25/15
to Premake Development
@starkos The default behaviour for gcc's ld is to link shared libraries first, and "static link" means "do not look for shared libraries". So yes, shared link by default seems good to me.

In my Android.mk premake module, I have "staticlinks" and "sharedlinks" for libraries that are declared externally, but it would probably not work for a normal premake because you often need to order your libraries.
For now on I've got away with it by having all my static dependencies built with a "s" suffix (there's a build option for boost for example), but the decorator solution makes sense, and could be easily used in complex projects.

local BOOST_STATIC = _OPTIONS["boost-static"] and "static" or "shared"

links
{ "boost_filesystem:"..BOOST_STATIC }

Reply all
Reply to author
Forward
0 new messages