premake / premake-core

Premake
https://premake.github.io/
BSD 3-Clause "New" or "Revised" License
3.22k stars 620 forks source link

Gmake(/2) not linking static libraries #1308

Closed detly closed 5 years ago

detly commented 5 years ago

I have this permake5.lua:

workspace "test"

    configurations { "Debug", "Release" }
    location "build"

    project "project_a"
        kind "StaticLib"
        language "C"
        files "a.c"

    project "project_b"
        kind "StaticLib"
        language "C"
        files "b.c"

    project "project_c"
        kind "StaticLib"
        language "C"
        files "c.c"

    project "test"
        kind "StaticLib"
        language "C"
        links {"project_a", "project_b", "project_c"}

The files a.c etc. just contain voif f_a(void). Running premake5 (v. 5.0.0-alpha14) and then make shows:

$ make verbose=true config=debug -B -C build test
make: Entering directory '/home/[...]/Code/premake-test/build'
==== Building project_a (debug) ====
Creating obj/Debug/project_a
mkdir -p obj/Debug/project_a
a.c
cc   -MMD -MP    -o "obj/Debug/project_a/a.o" -MF "obj/Debug/project_a/a.d" -c "../a.c"
Creating bin/Debug
mkdir -p bin/Debug
Linking project_a
ar -rcs "bin/Debug/libproject_a.a"  obj/Debug/project_a/a.o
==== Building project_b (debug) ====
Creating obj/Debug/project_b
mkdir -p obj/Debug/project_b
b.c
cc   -MMD -MP    -o "obj/Debug/project_b/b.o" -MF "obj/Debug/project_b/b.d" -c "../b.c"
Creating bin/Debug
mkdir -p bin/Debug
Linking project_b
ar -rcs "bin/Debug/libproject_b.a"  obj/Debug/project_b/b.o
==== Building project_c (debug) ====
Creating obj/Debug/project_c
mkdir -p obj/Debug/project_c
c.c
cc   -MMD -MP    -o "obj/Debug/project_c/c.o" -MF "obj/Debug/project_c/c.d" -c "../c.c"
Creating bin/Debug
mkdir -p bin/Debug
Linking project_c
ar -rcs "bin/Debug/libproject_c.a"  obj/Debug/project_c/c.o
==== Building test (debug) ====
Creating bin/Debug
mkdir -p bin/Debug
Linking test
ar -rcs "bin/Debug/libtest.a" 
make: Leaving directory '/home/[...]/Code/premake-test/build'

I was hoping to end up with a static library containing code from a, b and c. I may have misunderstood how linking a static library works. How to I achieve that?

(Alternatively I could have some config that results in building a bunch of .o files and then linking those into a library in the final stage, but I don't think that's easy to do.)

samsinsane commented 5 years ago

How to I achieve that?

If you want a single static library, the best way to achieve this is to have a single static library. What you attempted to do isn't supported by GCC and Clang, so I'm going to close this as Premake won't be supporting this either.

detly commented 5 years ago

So does that mean I have to duplicate all of the files calls up to the top level project? I don't think Premake supports any kind of "object library" style of arranging modular dependencies, does it?

samsinsane commented 5 years ago

So does that mean I have to duplicate all of the files calls up to the top level project?

You can, don't forget you do have Lua available to you, so you can utilize the language to avoid duplicating the actual lines by duplicating the data at runtime instead.

I don't think Premake supports any kind of "object library" style of arranging modular dependencies, does it?

If you mean some way to say "anything that links this library, also needs this stuff", Premake doesn't support that. It has been a discussion item for a number of years, but it's a non-trivial system that nobody has had time to invest in.

detly commented 5 years ago

You can, don't forget you do have Lua available to you, so you can utilize the language to avoid duplicating the actual lines by duplicating the data at runtime instead.

Perhaps a set of get_a_sources(), get_b_sources() functions that return the data in question would be the way to go (I have a similar thing for project generation elsewhere).

If you mean some way to say "anything that links this library, also needs this stuff", Premake doesn't support that. It has been a discussion item for a number of years, but it's a non-trivial system that nobody has had time to invest in.

I was thinking more "this needs the source (or object) files from module A B and C, module A also needs the code from module D, if is built as a static library or executable then build all those into it, if it's built as a shared library then build them all as shared libraries". I called it an object library because (a) there's sort of a CMake concept like that (but without the dependencies part) with that name and (b) it's possible to do this by building all the modules into .o files as a first pass, and then later archiving/linking them as needed.