library implementation

Go To Last Post
57 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

in my static library output i have two function built. while compiling in an executable project both the functions are being put into hex file even though only one is being used. Is there a way around so that all functions will be implemented in library and still only one will be put into hex file .???

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There are compiler and linker options for that.

I think the compiler option is -ffunction-sections and the linker option
is -Wl,--gc-sections.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ChaunceyGardiner wrote:
There are compiler and linker options for that.

I think the compiler option is -ffunction-sections and the linker option
is -Wl,--gc-sections.

a little more detailed and elaborate please .. would you

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ChaunceyGardiner wrote:
There are compiler and linker options for that.

I think the compiler option is -ffunction-sections and the linker option
is -Wl,--gc-sections.

ok selected checked no improvement. it is still putting both the function.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I have no idea what a "static library" is.

A regular library is typically an archive.a of object1.o, object2.o, ...

If the linker is asked to link file.a it will only extract the relevant objects.

e.g. libc.a contains all the C library functions.

When you say

ld crts.o main.o libc.a

a traditional linker will include every function from crts.o and main.o but only the necessary functions from libc.a

Some clever linkers will remove unnecessary functions from main.o
The default avr-gcc linker will include unnecessary functions. (you must use special switches to change the behaviour)

Your C or Unix textbook should explain this.
Wikipedia is pretty good too.

Note that different toolchains may use different file extensions. And may be more clever too !

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

arkarup_gupta wrote:
ChaunceyGardiner wrote:
There are compiler and linker options for that.

I think the compiler option is -ffunction-sections and the linker option
is -Wl,--gc-sections.

ok selected checked no improvement. it is still putting both the function.


It would be easier to answer this if you stated what development tools you use.

In AS6, you can see your toolchain options by right-clicking on your project in the Solution Explorer and selecting Properties. Then click Toolchain.

In your compiler's settings, select Optimization. You should see the option there.

Same thing for the linker option.

I assume you have to compile your library with the mentioned compiler setting, and your program with the linker setting. Set both in both projects and you should be OK.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

arkarup_gupta wrote:
in my static library output i have two function built. while compiling in an executable project both the functions are being put into hex file even though only one is being used. Is there a way around so that all functions will be implemented in library and still only one will be put into hex file .???
Put the functions into separate source files.

The linker always pulls complete object files out of a library. So if you have both functions in one source file (and therefore in one object file after compilation), then you will have both in your binary .

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

david.prentice wrote:
I have no idea what a "static library" is.
A library where the linking happens at build time. As opposed to a "dynamic library" where the linking happens at run time.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sternst wrote:
Put the functions into separate source files.

The linker always pulls complete object files out of a library. So if you have both functions in one source file (and therefore in one object file after compilation), then you will have both in your binary .


I don't think that's true if you use modern tools. It used to be that way for PCs back in the 80s, but they got smarter. I'm pretty sure they did with the tools included in AS6, too.

You probably have to tell the tools to do it, though.

Sid

Life... is a state of mind

Last Edited: Sun. Feb 10, 2013 - 10:15 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Put the functions into separate source files.
This is the easiest approach for a small number of source files like in the present case.

If there are more functions, it might be more convenient to build the modules from one source file. See an example that shows how avr-gcc iterates over a library sources:

• Makefile
• Iterator

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ChaunceyGardiner wrote:
sternst wrote:
Put the functions into separate source files.

The linker always pulls complete object files out of a library. So if you have both functions in one source file (and therefore in one object file after compilation), then you will have both in your binary .


I don't think that's true if you use modern tools. It used to be that way for PCs back in the 80s, but they got smarter. I'm pretty sure they did with the tools included in AS6, too.

well i used AS5.1 and it did not. Probably separating out is a nice idea but then "using one library for all function" philosophy is not followed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

When a library is put together, each object file gets put into its own section.
When the linker 'pulls' a function from the library, it pulls that entire section.

If you create an entire library from a single source file, there will only be one section in the library. When linked against, the entire library winds up in your final product, though you only needed the one function.

That is why library source consists (usually) of just one function per file. Sometimes, it does make sense for closely related functions to be put together.

Separate your library functions out into separate source files... such as 'input.c' and 'output.c'

Compile the source into separate object code files...

avr-gcc -c -Os -mmcu=atmels_great_gizmo -o input.o input.c 
avr-gcc -c -Os -mmcu=atmels_great_gizmo -o output.o output.c

-c informs the compiler not to link at this time
-o specifies the resulting object code file name

Then archive the object files together...

avr-ar -rcs libio.a input.o output.o

Your next build will then link only the required functions.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

What exactly is it you guys think -ffunction-sections and -Wl,--gc-sections actually do ?

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

arkarup_gupta wrote:
i used AS5.1

You shouldn't. It doesn't work properly.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Probably separating out is a nice idea but then "using one library for all function" philosophy is not followed.
What are you talking about? You still have all functions in one library then.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ChaunceyGardiner wrote:
What exactly is it you guys think -ffunction-sections and -Wl,--gc-sections actually do ?
In this case it repairs a broken library setup. If you build the library the right way, then you don't need any additional options to keep unused functions away.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sternst wrote:
ChaunceyGardiner wrote:
What exactly is it you guys think -ffunction-sections and -Wl,--gc-sections actually do ?
In this case it repairs a broken library setup. If you build the library the right way, then you don't need any additional options to keep unused functions away.

Are you saying that creating one source file per function is the "right" way ?

I don't understand your thinking. In the 80s, on PCs, you had to do that if you wanted to only include referenced functions in your executable. In no way, shape, form or fashion was it desirable - it was just a consequence of rather lame tools.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sternst wrote:
Quote:
Probably separating out is a nice idea but then "using one library for all function" philosophy is not followed.
What are you talking about? You still have all functions in one library then.

actually I'm ,u can say, a newbie.. so did not understand properly ..mikericetga I think gave the exact method i needed though i must try the suggestion in as5.1 first and see how it puts the command (as mikericetga put) one by one ..

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There are, sometimes, very good reasons NOT to use --gc-sections.

The existence of the --no-gcc-sections option is confirmation of that fact.

When creating a library, it is not wise to make assumptions about compiler flags & linker options ( unless the library is for your own, personal use).

That is why libraries are still written using the one function, one file method, even though --gc-sections has been around for well over ten years.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mikericetga,

You're saying that there are good reasons to not use this option but you don't give any such reasons.

If the library is built with sensible compiler options, how could the library user possibly mess that up in a way that keeping each function in a separate file would fix ?

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ChaunceyGardiner wrote:
sternst wrote:
ChaunceyGardiner wrote:
What exactly is it you guys think -ffunction-sections and -Wl,--gc-sections actually do ?
In this case it repairs a broken library setup. If you build the library the right way, then you don't need any additional options to keep unused functions away.

Are you saying that creating one source file per function is the "right" way ?
It is the common way. But as Georg-Johann pointed out there are other ways.

ChaunceyGardiner wrote:
I don't understand your thinking. In the 80s, on PCs, you had to do that if you wanted to only include referenced functions in your executable. In no way, shape, form or fashion was it desirable - it was just a consequence of rather lame tools.
And generating a library with a totally unnecessary constraint is of course much more modern.

"If you want to you use this library in a useful way, then it is mandatory to use this option when linking your program. Oh I could have built the library so that you get the same result without that constraint, but that was too old fashioned for me." LOL

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ChaunceyGardiner wrote:
mikericetga,

You're saying that there are good reasons to not use this option but you don't give any such reasons.

If the library is built with sensible compiler options, how could the library user possibly mess that up in a way that keeping each function in a separate file would fix ?

i think he is trying to say that the compiler will mess up sometimes which would never come up if his methods are followed.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sternst wrote:
ChaunceyGardiner wrote:
sternst wrote:
ChaunceyGardiner wrote:
What exactly is it you guys think -ffunction-sections and -Wl,--gc-sections actually do ?
In this case it repairs a broken library setup. If you build the library the right way, then you don't need any additional options to keep unused functions away.

Are you saying that creating one source file per function is the "right" way ?
It is the common way. But as Georg-Johann pointed out there are other ways.

ChaunceyGardiner wrote:
I don't understand your thinking. In the 80s, on PCs, you had to do that if you wanted to only include referenced functions in your executable. In no way, shape, form or fashion was it desirable - it was just a consequence of rather lame tools.
And generating a library with a totally unnecessary constraint is of course much more modern.

"If you want to you use this library in a useful way, then it is mandatory to use this option when linking your program. Oh I could have built the library so that you get the same result without that constraint, but that was too old fashioned for me." LOL


I know that I may not fully understand how these options work, but I know how I think they should work. In my evil little yellow brain, it should make no difference whether you create the library from source files compiled with that option or separate source files without that option.

That may be a stupid idea to some people, but it makes perfect sense to me.

Anyway, keep on laughing. I'm getting used to it.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Chauncy, a search through these forums brings up some examples of when garbage collection went astray.

The issue is not building the library with sensible options... of course you should do so.

The issue is the assumption that you know what options will be used when linking against that library.

Put it this way... One function, one file... always works.
Relying on --gc-sections, not always.

Which is better?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ChaunceyGardiner wrote:
I know that I may not fully understand how these options work, but I know how I think they should work. In my evil little yellow brain, it should make no difference whether you create the library from source files compiled with that option or separate source files without that option.
The difference is that the USER of the library MUST use -Wl,--gc-sections.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If the tools are broken, all bets are off.

In that case, I will do what I usually do - try something, and then try something else. Whatever works, I'll keep.

And yes, if the tools are broken and I was to create a library for other people to use, I would do what I had to do to get it to work properly.

If outdated tools turn out to be broken, though, I don't give a hoot.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sternst wrote:
ChaunceyGardiner wrote:
I know that I may not fully understand how these options work, but I know how I think they should work. In my evil little yellow brain, it should make no difference whether you create the library from source files compiled with that option or separate source files without that option.
The difference is that the USER of the library MUST use -Wl,--gc-sections.

What are the possible good reasons not to activate that option, then ?

If there are no such good reasons, two questions show up immediately - 1) why should I care whether a user is unconscious or not ? And 2) why aren't those options on by default ?

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ChaunceyGardiner wrote:
What are the possible good reasons not to activate that option, then ?
What if the user explicitly wants to have stuff in the binary that is not directly referenced? E.g. search for "how to put bootloader together with application into one elf file" here on the forum.

But actually what does it matter whether there are good reasons or not (or: whether you or I can imagine good reasons)? It is simply stupid to generate unnecessary constraints.

Stefan Ernst

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ChaunceyGardiner wrote:
If the tools are broken, all bets are off.
If you are too lazy to read the manuals or to use the tools correctly, don't call the tools "broken".

It's fine if you refuse best practices, but don't recomment others to follow your bad practices.

avrfreaks does not support Opera. Profile inactive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's interesting that I just hit this same thing with LPCXpresso library code. CodeRed in their wisdom have switched from the old style library building we all know and love (separate source files for each function unless functions are inextricably linked such as malloc+free which both live in a single file) to relying on the fairly recently added -ffunction-sections and -gc-sections so they build the library with -ffunction-sections then rely on the user to link with -gc-sections to discard the non-used junk in the library.

I suppose now that these new options exist we should use them?

Only thing is that CodeRed made a mistake. The CRT for a Cortex program has a vector table with almost 50 weak links to a default while(1) handler also in the CRT. Then they went and put interrupt support for the peripherals in the same source file as all the other code for that peripheral. So, for example, the library had lpc800_gpio.c with about 20 functions, 10 synchronous for setting pins high/low and 10 to do with interrupt handling to satisfy the 7 IO interrupt Vectors. My code called GPIO_Init() and GPIO_set_pin() which were both about 4 lines of C and suddenly my program bloated by 700 bytes. Turned out that while I used gc-sections and 8 other synchronous functions were discarded I got both the two I called and almost all the interrupt stuff because they were strong links that over-rode the weak calls in the CRT. I've told CodeRed and they say they'll consider moving the handlers to separate .o in the .a in future.

So I guess the moral is "be careful how you use these new options"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Perhaps it would be a useful option to have the compiler
make more than one .o file out of the same .c file

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Personally, I can't see any problem with the traditional library build method. i.e. one source file per function.
After all, the punter does not witness the library build time. Linker algorithms are quicker.

Of course, it is useful if the linker either removes or warns about uncalled functions in the regular source files.

It is even more useful if all the non-default tool switches worked perfectly.

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ChaunceyGardiner wrote:
If the library is built with sensible compiler options, how could the library user possibly mess that up in a way that keeping each function in a separate file would fix ?
He could omit -gc-functions

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

sternst wrote:
ChaunceyGardiner wrote:
What are the possible good reasons not to activate that option, then ?
What if the user explicitly wants to have stuff in the binary that is not directly referenced? E.g. search for "how to put bootloader together with application into one elf file" here on the forum.

If the user wants to do something out of the ordinary, he should actively set options to achieve it. There is no need to push that functionality on everybody by default.

sternst wrote:
It is simply stupid to generate unnecessary constraints.

Yes it is, and that is what you are arguing for.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think this thread can be be safely said to have devolved from the original subject. The original poster now has a number of options to pursue, and I am fairly certain one of them will produce the outcome desired... probably hours before this post.

I think it is now reasonable to say that we have seen two 'schools of thought' in this thread.

The Traditional School says:

    Here is a library, built to standards. Enjoy.

The Garbage Collection School says:

    Here is a library which does the same thing. It's even built from the exact same source code.

    However, it was built with 'expectations' in mind. So you must utter certain magical incantations in order to use it.

    Oh, by the way, those incantations may break your own code. This isn't really our problem, it is because the maintainers of the GNU C Compiler are a bunch of dim wits.

    So write your code the way we tell you too.

    And enjoy.

Which library would you choose?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

SprinterSB wrote:
ChaunceyGardiner wrote:
If the tools are broken, all bets are off.
If you are too lazy to read the manuals or to use the tools correctly, don't call the tools "broken".

If something's broken, I call it broken. So far I didn't call the tools anything. If you are too lazy to learn the language or use it properly, don't use it.

SprinterSB wrote:
It's fine if you refuse best practices, but don't recomment others to follow your bad practices.

You are not the master of the universe. You are not in a position to tell me what to recommend or anything else either. You may have a different opinion than I do, but that doesn't make you right and it doesn't make me wrong.

Your idea of what is "best practices" and what is "bad practice" seems to be the opposite of what I think. I don't see that as a problem, as a matter of fact that frequently seems to be the case between you and me.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
ChaunceyGardiner wrote:
If the library is built with sensible compiler options, how could the library user possibly mess that up in a way that keeping each function in a separate file would fix ?
He could omit -gc-functions

I guess most people omit that all the time then, as it is not a part of the GUI in AS6.

I haven't done anything to that option, so how come I don't see the problem ?

I use the two options I mentioned earlier in this thread all the time, and they seem to work well for my applications. Why it shouldn't - and apparently even doesn't - work for libraries is beyond me.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

mikericetga wrote:
The Traditional School says:
    Here is a library, built to standards. Enjoy.

The Garbage Collection School says:

    Here is a library which does the same thing. It's even built from the exact same source code.

    However, it was built with 'expectations' in mind. So you must utter certain magical incantations in order to use it.

    Oh, by the way, those incantations may break your own code. This isn't really our problem, it is because the maintainers of the GNU C Compiler are a bunch of dim wits.

    So write your code the way we tell you too.

    And enjoy.

Which library would you choose?


It's obvious which one you would choose, as your descriptions are very biased.

I remember the time before the linkers commonly used on PCs got the option to do what we're talking about here. One scheme that worked was to fill your source files with #ifdefs and compile each file once for each function.

As much as I hated that scheme, it's still a whole heck of a lot better than having each function in a separate file.

What century is this anyway ?

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

"avr-gcc -funsigned-char -funsigned-bitfields -Os -fpack-struct -fshort-enums -g2 -Wall -c -std=gnu99 -MD -MP -MF "mylib2.d" -MT"mylib2.d" -mmcu=atmega32 -o"mylib2.o" ".././mylib2.c"

avr-gcc -funsigned-char -funsigned-bitfields -Os -fpack-struct -fshort-enums -g2 -Wall -c -std=gnu99 -MD -MP -MF "myLibrary.d" -MT"myLibrary.d" -mmcu=atmega32 -o"myLibrary.o" ".././myLibrary.c"

avr-gcc -r -o libmyLibrary.a mylib2.o myLibrary.o "

this is what avr studio did automatically when i put separate function in separate c file ; took both in the project and built it. I think this is what mikericetga suggested !!!!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes, the two suggestions I'm aware of are 1) put each function in a separate source file and 2) use options.

Either way should work for you.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

With modern source browsing editors I'd have thought that putting functions in separate files would be far less onerous than it might once have been. One thing it does do is make you think much deeper about the structure / layering of the code. As noted above when functions (like malloc and free) are inextricably linked you would still group them into a single file anyway so you might assume that no one is going to use your ADC_read() function without having called your ADC_init().

Going back to OPs original question I would ask whether there's really any point in building static libs for 8bit microcontrollers anyway? Sure it makes sense for processor agnostic functions like cos() and strcpy() (actually cos() will be dependent on whether the CPU has MUL or not) but huge amounts of MCU code are bound to CPU specific functionality (like is the UART UDR or UDR0) so most "library" code (Fleury, Stang, Thomas etc) end up being collections of .c files which are then recompiled once a specific target CPU has been chosen. Given the speed of modern PCs and the fact that Makefiles ensure unchanging files don't get recompiled every time it doesn't really matter that they are .c files. I suppose the only real appeal of .a/.o is when you don't want to expose the source?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
With modern source browsing editors I'd have thought that putting functions in separate files would be far less onerous than it might once have been.

They are not that modern yet. It is still more efficient to search in a single file than in 50. It is still easier to view different parts of one file simultaneously than it is to view several different files. It is still much more efficient to save one file than 50 when you have changed something central in what is essentially one unit of code - at least if you want to have control over what code actually gets saved.

You would think that modern tools could generate good code without imposing a file structure on the developer. And of course, modern tools can do that - modern tools have done that for well over two decades. But most of the loud voices here seem to advocate the alleged advantage of enforcing a certain file structure when the developer wants to activate key features that should be enabled by default for any source code.

If you know how to properly use more advanced languages than C and assembly, you are probably familiar with the concept of classes. Regardless of what programming language you use, classes are a natural organizing unit and the elements of a class belong together - not scattered in the file system or anywhere else.

Some languages, such as Java, even force you to keep your class in one file. Java is a very successful language.

clawson wrote:
Going back to OPs original question I would ask whether there's really any point in building static libs for 8bit microcontrollers anyway?

That is a very good point.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ChaunceyGardiner wrote:
You would think that modern tools could generate good code without imposing a file structure on the developer.
Are there C compilers that can generate more than one object file per source file?
Java will generate more than one class file per source file.
Rather a lot more.

Moderation in all things. -- ancient proverb

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

skeeve wrote:
ChaunceyGardiner wrote:
You would think that modern tools could generate good code without imposing a file structure on the developer.
Are there C compilers that can generate more than one object file per source file?

I don't know how it's done internally, but I know for a fact that for more than two decades it hasn't been necessary to have a one file per function scheme in order to exclude unused functions from your executable.

I *think* that works by making the linker see each function as a separate "module". Right or wrong - who cares how it is done ? It has been done for more than two decades and it has been working well.

skeeve wrote:
Java will generate more than one class file per source file.
Rather a lot more.

Yes, the developer is allowed to use nested classes and anonymous classes. That's a good thing, considering the rule imposed by only allowing one top-level class per source file.

(I guess "compilation unit" is more accurate than "source file" in this thread, but it doesn't matter to me what we call it.)

As it happens, Java creates one .class file per class, i.e. one "object" file per class even when there is more than one class in a source file. I think that's bad, but I don't care that much about what is put in the output directories as long as I can organize my sources according to my own preferences and still get good code out of it.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

I *think* that works by making the linker see each function as a separate "module". Right or wrong - who cares how it is done ? It has been done for more than two decades and it has been working well.

But what you are describing is exactly what -ffunction-sections does. Without it all the functions in file are placed into .text. When it is used a function foo() is placed in .text.foo and a function bar into .text.bar. When linked (using -gc-sections) the linker keeps track of which of the functions are actually accessed. If foo() is called then .text.foo is marked as used whereas if bar() isn't then .text.bar is not needed and it then discards the unused sections and only constructs the final .text from all the .text.* that have a reference >= 1.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Quote:

I *think* that works by making the linker see each function as a separate "module". Right or wrong - who cares how it is done ? It has been done for more than two decades and it has been working well.

But what you are describing is exactly what -ffunction-sections does. Without it all the functions in file are placed into .text. When it is used a function foo() is placed in .text.foo and a function bar into .text.bar. When linked (using -gc-sections) the linker keeps track of which of the functions are actually accessed. If foo() is called then .text.foo is marked as used whereas if bar() isn't then .text.bar is not needed and it then discards the unused sections and only constructs the final .text from all the .text.* that have a reference >= 1.

That is what I have been saying since the second message in this thread. Somebody got the idea that it didn't work, and apparently I am an idiot for thinking that it should work.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Oh it does work but only as long as the user of the library knows (and is willing) to link with -gc-sections. The traditional method has worked since Adam was a lad and always will with no thought on the part of the consumer.

I still have a hard time understanding the point of static libs for 8bit AVRs though. I suppose if someone came up with something like JPEG decode maybe or something equally CPU agnostic?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

clawson wrote:
Oh it does work but only as long as the user of the library knows (and is willing) to link with -gc-sections. The traditional method has worked since Adam was a lad and always will with no thought on the part of the consumer.

I still have a hard time understanding the point of static libs for 8bit AVRs though. I suppose if someone came up with something like JPEG decode maybe or something equally CPU agnostic?

let's summarise as
1.some one reported there had been problems in using -gc section ... so being a novice i would like to avoid.
2. i am making this library for an archive with many options open where similar functions will be placed different ways (for user to get feel of it). the choice will be provided through defining different values of macros.
3. as the whole archive is being built for my juniors to use who apparently even unaware of this world (truly in India stress is more upon memorising up theory and putting in exams' written answer GETTING HIGH MARKS RATHER THAN working some thing up). So telling them to include -gc section at a first go is bad idea, it will merely confuse them.
4. I intend to make the source codes invisible because that would create more attraction(vain fantasy ) to my juniors and they will be inclined to explore more :) .
so, all these combined i think the suggestion of mikericetga has been best for me .. ChaunceyGardiner! mate, i will explore your concept more and more in coming future :)

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

the choice will be provided through defining different values of macros.

But it cannot be a static library in that case? Or you mean you have a:

#if some_codition
  #define FOO() foo1()
#elif some_other_condition
  #define FOO() foo2()
#else
  #define FOO foo3()
#endif

and the archive contains all of foo1(), foo2() and foo3()?

Anyway if you want to avoid -gc-sections (personally I'm ambivalent I could see arguments either way) then you have no choice but to do it the old fashoined way as described in the user manual:

http://nongnu.org/avr-libc/user-...

See "How to design a library". Point 1 there has been discussed ad infinitum above. Point 2 is also worth bearing in mind. As I say NXP Cortex libraries made a mistake and do this wrong and it could be an argument against -gc-sections if you are not careful. So if you go the -gc-sections route then still split the ISR code into separate files anyway.

BTW what exactly is going into this "library". Is it high level software like JPEG decode, math functions, string functions, etc? Or is it something reliant on the specific hardware it runs on (timer, ADC, UART functions for example)? If so how do you handle the fact that the same UART_getchar() may be built to run on 50 different models of AVR? Do you do what the EEPROM functions in AVR-LibC do and actually build m16_uart_getchar(), t2313_uart_getchar(), x128a1_uart_getchar() then provide a generic #define uart_getchar() that takes the build target and maps to one of 200+ different copies of the function? If not you cannot build a static lib.

Last Edited: Tue. Feb 12, 2013 - 03:57 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The only reason this can be perceived as a problem is that apparently both the tools and the development environment (AS6) defaults to off for these options.

Why would a typical user want this feature to be off more frequently than on ?

Most people are not even aware of these options. Seeing how it creates smaller (=better) programs in many cases and never anything bigger, it should be on by default.

Those who want to add unused stuff to the executable presumably know what they are doing anyway. They are the ones who like to flood their file systems with one source file and one object file per function, and there would be nothing to stop them from doing that even if the defaults changed to something useful.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Suppose you put a module into a library that contains the following:

  • A definition for uart_getchar()
  • Definitions for a ring buffer and its producer and consumer offsets
  • The definition for a uart character-receive ISR
. If this boon-to-mankind linker option for excluding unreferenced functions is used when the module is extracted to satisfy an application's reference to uart_getchar(), how is it that the necessary ISR will be pulled in? And although the ring buffer and its consumer offsets will be included, what about the producer offset?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

How do they make it work on other platforms ?

You're saying that because every once in a blue moon somebody wants to do something that 99.9% of the users don't, we should default to generate much bigger executables than needed.

Clearly what you would have to do in your case would be to disable the option to discard unused functions. Yeah, it sucks that you have to select an option - but that's what everybody else have to do right now to activate a feature that should be there by default.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sid what about -whole-program then? Should As6 be using that and passing all the .c at once perhaps?

I guess the question is moot, LTO will soon arrive.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Any option that improves the generated executable for the vast majority of cases should be on by default.

The few that do "strange" things can still revert any such default settings.

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

ChaunceyGardiner wrote:
clawson wrote:
Quote:

I *think* that works by making the linker see each function as a separate "module". Right or wrong - who cares how it is done ? It has been done for more than two decades and it has been working well.

But what you are describing is exactly what -ffunction-sections does. Without it all the functions in file are placed into .text. When it is used a function foo() is placed in .text.foo and a function bar into .text.bar. When linked (using -gc-sections) the linker keeps track of which of the functions are actually accessed. If foo() is called then .text.foo is marked as used whereas if bar() isn't then .text.bar is not needed and it then discards the unused sections and only constructs the final .text from all the .text.* that have a reference >= 1.

That is what I have been saying since the second message in this thread. Somebody got the idea that it didn't work, and apparently I am an idiot for thinking that it should work.

If a user of your library does that, and then then try to include their bootloader in the same ELF file as their main program, then -gc-sections will cause their bootloader to disappear.

So, their first response will be to omit -gc-sections. But when they do that, your library would cause flash space utilization to shoot through the roof with unused library functions.

As a distributor of a library, I would want it to be as flexible as possible, so that, for example, it doesn't blow up in my users' face simply because they have existing restrictions which prevent them from using a specific set of linker directives.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

lfmorrison wrote:
If a user of your library does that, and then then try to include their bootloader in the same ELF file as their main program, then -gc-sections will cause their bootloader to disappear.

If that is true, the linker should have an option to force inclusion of specified sections whether they are used or not.

If you are forced to include a number of unused functions because you want a bootloader, the linker is seriously flawed.

The compiler has the ability to generate code with discardable functions. The linker has the ability to discard unused functions. But we can't rely on that to happen because every once in a blue moon somebody, somewhere wants a bootloader.

This doesn't make any sense whatsoever.

Why should it make any difference to the generated executable how many files were used to build the libraries used ?

Why should somebody that creates a library be forced to put each function in a separate file to achieve effects that are already available in the tools by means of options ?

Sid

Life... is a state of mind

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It does not make a difference, just build teh lib appropriately. For example, libgcc.a contains ~800 functions and is built from 4 source files (general stuff, float stuff, fixed-point stuff and AVR-specific assembler stuff).

Yet libgcc.a will work as intended and does not make implications on user code.

Besides that: A library with just 2 objects is rather uncommon. Typical libraries are much bigger. Builting a library like Qt in such a way that linking against it will first drags the whole several dozens of MB library and then gc-ing the 99.9% unneeded stuff is simply slowing down the process of linking.

And there might be other objections against -ffunction-sections like an ABI or requirement that does not allow cross-section inlining. (Notice with LTO you can inline and optimize against library code).

avrfreaks does not support Opera. Profile inactive.