Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 23 |
Nodes: | 6 (0 / 6) |
Uptime: | 54:07:33 |
Calls: | 583 |
Files: | 1,139 |
D/L today: |
179 files (27,921K bytes) |
Messages: | 111,699 |
I don't think this is a pure C programming question, but it's related.
I don't think this is a pure C programming question, but it's related.
I'm building a static library mylib.a with all the object files except main.o, and the final executable linking together main.o and mylib.a.
I want to remove from the final exe everything present in mylib.a that
is not used in main.o.
Suppose only mod1.o is present in mylib.a. foo1() and bar1() are defined
in mod1.c. main() is the only function in main.c and only foo1() is
called from main().
gcc -O2 -ffunction-sections -fdata-sections -c -o mod1.o mod1.c
ar rcs mylib.a mod1.o
gcc -O2 -ffunction-sections -fdata-sections -c -o main.o main.c
gcc -Wl,--gc-sections,--print-gc-sections -o main[.exe] main.o mylib.a objdump -d main[.exe] | grep bar1
MinGW in Windows build a main.exe that contains bar1(), while gcc in WSL doesn't.
Why?
pozz <pozzugno@gmail.com> wrote:
I don't think this is a pure C programming question, but it's related.
I'm building a static library mylib.a with all the object files except
main.o, and the final executable linking together main.o and mylib.a.
I want to remove from the final exe everything present in mylib.a that
is not used in main.o.
Suppose only mod1.o is present in mylib.a. foo1() and bar1() are defined
in mod1.c. main() is the only function in main.c and only foo1() is
called from main().
gcc -O2 -ffunction-sections -fdata-sections -c -o mod1.o mod1.c
ar rcs mylib.a mod1.o
gcc -O2 -ffunction-sections -fdata-sections -c -o main.o main.c
gcc -Wl,--gc-sections,--print-gc-sections -o main[.exe] main.o mylib.a
objdump -d main[.exe] | grep bar1
MinGW in Windows build a main.exe that contains bar1(), while gcc in WSL
doesn't.
Why?
Support for '-ffunction-sections' and '-fdata-sections' is target
platform dependent (and version dependent). Also there may be
platform specific quirks. If your toolchain does not properly
support them, then you need to use old method, that is define each
function in a separate file.
I don't think this is a pure C programming question, but it's related.
I'm building a static library mylib.a with all the object files except main.o, and the final executable linking together main.o and mylib.a.
I want to remove from the final exe everything present in mylib.a that
is not used in main.o.
Suppose only mod1.o is present in mylib.a. foo1() and bar1() are defined
in mod1.c. main() is the only function in main.c and only foo1() is
called from main().
gcc -O2 -ffunction-sections -fdata-sections -c -o mod1.o mod1.c
ar rcs mylib.a mod1.o
gcc -O2 -ffunction-sections -fdata-sections -c -o main.o main.c
gcc -Wl,--gc-sections,--print-gc-sections -o main[.exe] main.o mylib.a objdump -d main[.exe] | grep bar1
MinGW in Windows build a main.exe that contains bar1(), while gcc in WSL doesn't.
Why?
I don't think this is a pure C programming question, but it's related.
I'm building a static library mylib.a with all the object files
except main.o, and the final executable linking together main.o and
mylib.a.
I want to remove from the final exe everything present in mylib.a
that is not used in main.o.
Suppose only mod1.o is present in mylib.a. foo1() and bar1() are
defined in mod1.c. main() is the only function in main.c and only
foo1() is called from main().
gcc -O2 -ffunction-sections -fdata-sections -c -o mod1.o mod1.c
ar rcs mylib.a mod1.o
gcc -O2 -ffunction-sections -fdata-sections -c -o main.o main.c
gcc -Wl,--gc-sections,--print-gc-sections -o main[.exe] main.o mylib.a objdump -d main[.exe] | grep bar1
MinGW in Windows build a main.exe that contains bar1(), while gcc in
WSL doesn't.
Why?
On 28/08/2025 18:12, pozz wrote:
I don't think this is a pure C programming question, but it's related.
I'm building a static library mylib.a with all the object files except
main.o, and the final executable linking together main.o and mylib.a.
My first question is "Why?"-a Why not simply link all the object files together?
I want to remove from the final exe everything present in mylib.a that
is not used in main.o.
My second question is "Why?"-a When you are working on embedded targets, saving space like this in the executable is often a very good idea.-a On
a PC, it is rarely worth the effort.
Suppose only mod1.o is present in mylib.a. foo1() and bar1() are
defined in mod1.c. main() is the only function in main.c and only
foo1() is called from main().
gcc -O2 -ffunction-sections -fdata-sections -c -o mod1.o mod1.c
ar rcs mylib.a mod1.o
gcc -O2 -ffunction-sections -fdata-sections -c -o main.o main.c
gcc -Wl,--gc-sections,--print-gc-sections -o main[.exe] main.o mylib.a
objdump -d main[.exe] | grep bar1
MinGW in Windows build a main.exe that contains bar1(), while gcc in
WSL doesn't.
Why?
Why are you using "-ffunction-sections" and "-fdata-sections" ?
They
can be helpful in some ways for omitting code and data that is defined
in the code, but not actually used in the executable.-a But they can also make linking slower, and "-fdata-sections" can reduce optimisations (especially if you have "-fcommon", which was the default in older gcc).
Il 29/08/2025 11:05, David Brown ha scritto:
On 28/08/2025 18:12, pozz wrote:
I don't think this is a pure C programming question, but it's related.
I'm building a static library mylib.a with all the object files
except main.o, and the final executable linking together main.o and
mylib.a.
My first question is "Why?"-a Why not simply link all the object files
together?
Because I want to start creating tests on my projects and one simple approach is what I have described. All is in a static library (a
collection of object files), except main.o where is only main().
If I want to create test1.c (with its main), I have to only link test1.o with library.
I want to remove from the final exe everything present in mylib.a
that is not used in main.o.
My second question is "Why?"-a When you are working on embedded
targets, saving space like this in the executable is often a very good
idea.-a On a PC, it is rarely worth the effort.
This question was born because I found another problem.
I have a library distributed in source codes. One function in one source code needs to access a global array that *must* be defined somewhere in
the project.
As I wrote, I'm creating some tests. Not all the tests use that
function, so I thought it would be safe to not have the definition of
the global array, but this isn't true in my project and building system.
The linker complains because it doesn't find the global array.
I expected the unused function, with its references, would have been
removed by the linker.
Suppose only mod1.o is present in mylib.a. foo1() and bar1() are
defined in mod1.c. main() is the only function in main.c and only
foo1() is called from main().
gcc -O2 -ffunction-sections -fdata-sections -c -o mod1.o mod1.c
ar rcs mylib.a mod1.o
gcc -O2 -ffunction-sections -fdata-sections -c -o main.o main.c
gcc -Wl,--gc-sections,--print-gc-sections -o main[.exe] main.o mylib.a
objdump -d main[.exe] | grep bar1
MinGW in Windows build a main.exe that contains bar1(), while gcc in
WSL doesn't.
Why?
Why are you using "-ffunction-sections" and "-fdata-sections" ?
Because each function is in its section and can be removed if unused by
the garbage collector of the linker (at least, so I understood).
They can be helpful in some ways for omitting code and data that is
defined in the code, but not actually used in the executable.-a But
they can also make linking slower, and "-fdata-sections" can reduce
optimisations (especially if you have "-fcommon", which was the
default in older gcc).
I don't think this is a pure C programming question, but it's related.
I'm building a static library mylib.a with all the object files except main.o, and the final executable linking together main.o and mylib.a.
I want to remove from the final exe everything present in mylib.a that
is not used in main.o.
Suppose only mod1.o is present in mylib.a. foo1() and bar1() are defined
in mod1.c. main() is the only function in main.c and only foo1() is
called from main().
gcc -O2 -ffunction-sections -fdata-sections -c -o mod1.o mod1.c
ar rcs mylib.a mod1.o
gcc -O2 -ffunction-sections -fdata-sections -c -o main.o main.c
gcc -Wl,--gc-sections,--print-gc-sections -o main[.exe] main.o mylib.a objdump -d main[.exe] | grep bar1
MinGW in Windows build a main.exe that contains bar1(), while gcc in WSL doesn't.
Why?
On 29/08/2025 12:39, pozz wrote:
Il 29/08/2025 11:05, David Brown ha scritto:
On 28/08/2025 18:12, pozz wrote:
I don't think this is a pure C programming question, but it's related. >>>>
I'm building a static library mylib.a with all the object files
except main.o, and the final executable linking together main.o and
mylib.a.
My first question is "Why?"-a Why not simply link all the object files
together?
Because I want to start creating tests on my projects and one simple
approach is what I have described. All is in a static library (a
collection of object files), except main.o where is only main().
If I want to create test1.c (with its main), I have to only link
test1.o with library.
The only "benefit" you get from using a library in this situation is
that you might conceivably save a couple of lines in your makefile,
and
if you are using spinning rust drives and a PC from the 1990's, you
might save a second or two from the build.-a It is not worth the bother.
I want to remove from the final exe everything present in mylib.a
that is not used in main.o.
My second question is "Why?"-a When you are working on embedded
targets, saving space like this in the executable is often a very
good idea.-a On a PC, it is rarely worth the effort.
This question was born because I found another problem.
I have a library distributed in source codes. One function in one
source code needs to access a global array that *must* be defined
somewhere in the project.
Okay.
As I wrote, I'm creating some tests. Not all the tests use that
function, so I thought it would be safe to not have the definition of
the global array, but this isn't true in my project and building
system. The linker complains because it doesn't find the global array.
I expected the unused function, with its references, would have been
removed by the linker.
The "--gc-sections" gnu linker option works for elf files, but is "experimental" for coff/pe.-a Maybe it simply doesn't work as effectively for mingw, which will be generating Windows-style coff/pe binaries,
while it works for WSL which uses Linux-style elf binaries.
But while I appreciate that you expected linker garbage collection to
work here, you still haven't answered why you feel it is important.-a (If you are just trying to understand why it doesn't work, that's fine by me.)
Suppose only mod1.o is present in mylib.a. foo1() and bar1() are
defined in mod1.c. main() is the only function in main.c and only
foo1() is called from main().
gcc -O2 -ffunction-sections -fdata-sections -c -o mod1.o mod1.c
ar rcs mylib.a mod1.o
gcc -O2 -ffunction-sections -fdata-sections -c -o main.o main.c
gcc -Wl,--gc-sections,--print-gc-sections -o main[.exe] main.o mylib.a >>>> objdump -d main[.exe] | grep bar1
MinGW in Windows build a main.exe that contains bar1(), while gcc in
WSL doesn't.
Why?
Why are you using "-ffunction-sections" and "-fdata-sections" ?
Because each function is in its section and can be removed if unused
by the garbage collector of the linker (at least, so I understood).
They are potentially useful if you have a significant amount of extra
code and/or data that is in your source code and not wanted in the final binary, /and/ that it is important for the binary to be as small as reasonably possible.
As I understand it, you have an embedded program with lots of source
code, and you want to test different parts of it by compiling with
different small "main" functions on a PC.-a I am not sure if you said the main program was for an embedded system, or if I am assuming that
because you are one of the few people keeping comp.arch.embedded alive
by starting new threads there :-)
For the main program, function and data sections are probably not needed because you the source code that you build for the project is needed for
the program - if there was a lot that you didn't need, it wouldn't be in
the project build.
For the test programs, function and data sections are not needed because
the size of the test binaries on the PC is irrelevant.
Again - if your questions are from curiosity as to why things are not working as you expected, I fully appreciate that.
If your questions are
because you think there is a significant advantage in using static
libraries and section garbage collection in your build process, I
believe it is unlikely to be beneficial in reality - so it does not
matter if they don't work.
In the end, however, my guess is just that the limited coff/pe format
used by Windows binaries is the issue.
They can be helpful in some ways for omitting code and data that is
defined in the code, but not actually used in the executable.-a But
they can also make linking slower, and "-fdata-sections" can reduce
optimisations (especially if you have "-fcommon", which was the
default in older gcc).