LinuxQuestions.org
LinuxAnswers - the LQ Linux tutorial section.
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices

Reply
 
Search this Thread
Old 08-10-2006, 09:56 AM   #1
jineshkj
Member
 
Registered: Apr 2006
Distribution: Fedora
Posts: 33

Rep: Reputation: 15
Hiding global symbols in a shared/static library


hi friends,

i would like to know how to remove symbols from shared or static library. for example, i have two files f1.c and f2.c to be compiled to make a static library. both these files use a common global function called func(). But, this function must not be used by anyone who links the library with their application. ie, i want to remove func() from the global symbol table while compiling the library either as static or shared library.

will 'ld -x' help us while compiling shared libraries? what can I do for static libraries? i couldn't find anything specific in ar, nm or ranlib manpages.

can someone help me please?

thanks,

jinesh.
 
Old 08-10-2006, 12:22 PM   #2
sundialsvcs
Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 5,378

Rep: Reputation: 1108Reputation: 1108Reputation: 1108Reputation: 1108Reputation: 1108Reputation: 1108Reputation: 1108Reputation: 1108Reputation: 1108
Have a look at info libtool.

Declare "func()" to be static so that the compiler will not generate an external symbol dictionary entry for it.
 
Old 08-10-2006, 11:47 PM   #3
jineshkj
Member
 
Registered: Apr 2006
Distribution: Fedora
Posts: 33

Original Poster
Rep: Reputation: 15
but if i declare func() to be static, it can be accessed only from the file it is written. remember that here i have two files f1.c and f2.c both of which should use this function.
 
Old 08-11-2006, 07:03 AM   #4
sundialsvcs
Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 5,378

Rep: Reputation: 1108Reputation: 1108Reputation: 1108Reputation: 1108Reputation: 1108Reputation: 1108Reputation: 1108Reputation: 1108Reputation: 1108
The document How to Write Shared Libraries is the best I've ever found anywhere: http://people.redhat.com/drepper/dsohowto.pdf

45 (count 'em) pages covering way more than you ever thought you needed to know about how all this magic works in various Unix implementations. Symbol visibility and exporting is among the many topics covered.

Apple Computer also published a good piece although it's even longer:
http://developer.apple.com/documenta...cLibraries.pdf

Since "they" use basically the same techniques that "we" use, the document applies to "us, too."

Last edited by sundialsvcs; 08-11-2006 at 07:07 AM.
 
Old 08-11-2006, 09:23 AM   #5
xhi
Senior Member
 
Registered: Mar 2005
Location: USA::Pennsylvania
Distribution: Slackware
Posts: 1,065

Rep: Reputation: 45
what i would do in this case is to make two header files, one libsomelib.h and libsomelib_local.h.

all the files in somelib can include both files, done like this

#include <libsomelib.h>
#include "libsomelib_local.h"

keep all of the private library functions in _local.h.

now to make this work, you have to get a little creative with the makefile. you will need to copy the libsomelib.h to another directory, say director include/ somewhere in the build tree. this is also done for all your other libs. so now you have an include dir somewhere that has libsomelib.h, libsomeotherlib.h, libalib.h, etc etc.. and then when compiling just pass the path of that dir include/ to gcc like so

-I/path/to/include

now all of the libs only have access to the public api of each other, and each lib will have access to both the public and private api that it owns.

as for making functions private with the linker, i dont know if its possible i have never seen it done or attempted. but this works just as well, actuall better as it is far more flexible and easier to change.

Last edited by xhi; 08-11-2006 at 09:24 AM.
 
Old 08-25-2006, 06:30 AM   #6
jineshkj
Member
 
Registered: Apr 2006
Distribution: Fedora
Posts: 33

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by xhi

#include <libsomelib.h>
#include "libsomelib_local.h"

keep all of the private library functions in _local.h.
Thanks for the reply. But, don't you think that instead of keeping two header files, we may have a #ifdef section to differentiate the local functions. For example, out header will be like:

--- somelib.h ------


#ifdef SOMELIB_LOCAL_INCLUDE

All the locally used functions.

#endif

All the public functions.


--- somelib.h ends here -----


And when compiling the library, we may use:

gcc -DSOMELIB_LOCAL_INCLUDE ...

In that way, it becomes easy to move functions between the sections, maybe in a far future we may wish to make a function public or private... right?
 
Old 08-25-2006, 08:29 AM   #7
xhi
Senior Member
 
Registered: Mar 2005
Location: USA::Pennsylvania
Distribution: Slackware
Posts: 1,065

Rep: Reputation: 45
sure that sounds like it would work as well.

imo the way i mentioned is more clear cut, you have a public file and a private file. when you are looking for a function you dont have to see where in the file it is. looking for a #ifdef amongst hundered of lines over time would be error prone i would think. but as far as being functional, sure your way should work fine.

the project im currently working on is about 15,000 C source files large, and it is using a make system like i mentioned and it works flawlessly. the time spent is in the beginning writing your makefile.in template, then after that it is cake.

> In that way, it becomes easy to move functions between the sections,

i dont understand, you are just moving functions from one line in one file to another line in another file. i would not use that as a reason for using #ifdef, because either was is trivial.

>maybe in a far future we may wish to make a function public or private... right?

(i may not be understanding this statement correctly)
do you mean a function should be both private and public? in what i mentioned they are, a lib can include both the .h and the _local.h so both public and private functions are available to the lib.

-good luck
 
Old 08-25-2006, 09:59 AM   #8
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
I don't see how the question makes sense. If you have something in a library, and that something needs to be referenced by another module, how will the linker resolve that reference, without there being a public name for it in the library? If the symbol is not to be referenced, why put it in a library? What am I missing?

--- rod
 
Old 08-25-2006, 10:09 AM   #9
xhi
Senior Member
 
Registered: Mar 2005
Location: USA::Pennsylvania
Distribution: Slackware
Posts: 1,065

Rep: Reputation: 45
> If you have something in a library, and that something needs to be referenced by another module, how will the linker resolve that reference

i think you misread part of the original question

> this function must not be used by anyone who links the library with their application.

the function(s) is available to different modules in the lib itself, but not to any other lib
 
Old 08-25-2006, 11:29 AM   #10
theNbomr
LQ 5k Club
 
Registered: Aug 2005
Distribution: OpenSuse, Fedora, Redhat, Debian
Posts: 5,395
Blog Entries: 2

Rep: Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903Reputation: 903
If you need the global symbol for your application only, and don't want it exported to other users of your library, just link the function as a separate object module, 'func.o', and don't put it in the library.
--- rod.
 
Old 08-25-2006, 12:24 PM   #11
xhi
Senior Member
 
Registered: Mar 2005
Location: USA::Pennsylvania
Distribution: Slackware
Posts: 1,065

Rep: Reputation: 45
theNbomr, sure you could do that. it sounds to me like with your solution it seems like you are simply moving to having public and private .c files instead of (my solution) public and private .h files. right? which sounds to be less flexible. sure you save a few k on your libs, but i dont see it being worth it.

in my application the reason it is done the way i mentioned is because the public and private functions may be mixed amongst the source files. for example one source file may have 10 public and 3 private functions and another be similar, they are potentially all mixed. this is because they are possibly using some sort of statically declared function or variable in that file. if we want to change one of those to be public or private, instead of copying and pasting the function definition to another file (which is another error prone story in itself) we simply modify the declaration, remove from on .h and move to the other .h ..

imo its a simple solution for a large and quickly changing project.
 
Old 08-26-2006, 03:30 PM   #12
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Look at info:gcc and look up "Function Attributes". This will tell you the different classifications of visibility of functions (you might be looking for "__attribute__ ((visibility ("internal")))".) Also, you can link with the '--retain-symbols-file=file' option with 'ld' to restrict the symbols placed in the table (visible when using 'nm'.)
ta0kira

Last edited by ta0kira; 08-26-2006 at 03:33 PM.
 
Old 08-27-2006, 09:42 PM   #13
ta0kira
Senior Member
 
Registered: Sep 2004
Distribution: FreeBSD 9.1, Kubuntu 12.10
Posts: 3,078

Rep: Reputation: Disabled
Quote:
Originally Posted by xhi
we simply modify the declaration, remove from on .h and move to the other .h ..
There are many ways to prevent the user from including a function in their own headers, but that doesn't prevent them from declaring an extern and then linking to it. Take this example:
Code:
//test.c

__attribute__ ((visibility ("internal")))
void DontUseMe()
{

}
Code:
//main.c

extern void DontUseMe();

int main()
{
DontUseMe();
}
Code:
> gcc test.c -c -fPIC
> gcc main.c -c
> ld test.o -shared -o libtest.so
> gcc main.o libtest.so
main.o(.text+0x11): In function `main':
: undefined reference to `DontUseMe'
collect2: ld returned 1 exit status
The linker error is a result of internal; if you remove it, you don't get the error. This only affects the final linked object; it can still be used across object files before the final link is made.
ta0kira

PS This is a "link time" vs. a "compile time" issue.

Last edited by ta0kira; 08-27-2006 at 09:43 PM.
 
Old 08-27-2006, 09:53 PM   #14
xhi
Senior Member
 
Registered: Mar 2005
Location: USA::Pennsylvania
Distribution: Slackware
Posts: 1,065

Rep: Reputation: 45
ta0kira,

i have never saw the attribute trick. i will definately be checking that out.. thanks.

and you are right, with my method if someone wanted to cheat they could cheat. it is used as more of a guide than a tight restriction i guess. the uses my method has found are only for control within a single app, controlling what one lib can know about another lib. and the libs that use this are never made available to other apps eithe, it seems like your method would be significantly more flexible, especially if one were to make libraries available to other projects.


good stuff..
 
Old 08-28-2006, 04:50 AM   #15
jineshkj
Member
 
Registered: Apr 2006
Distribution: Fedora
Posts: 33

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by ta0kira
Look at info:gcc and look up "Function Attributes". This will tell you the different classifications of visibility of functions (you might be looking for "__attribute__ ((visibility ("internal")))".) Also, you can link with the '--retain-symbols-file=file' option with 'ld' to restrict the symbols placed in the table (visible when using 'nm'.)
ta0kira
I liked the ld option that you've mentioned since it seem to be more straight forward. Combining this with the header file scheme mentioned by xhi, i think my problem is solved. I'm sure that just manipulating the header files won't prevent a tricky user from using those unintended-public functions declared in the xxx-local.h.

I personally don't like to use gcc attributes since no other compiler provides similar functionalities, whereas linker options would be easily portable across various linkers.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
shared to static library ofada Programming 2 07-08-2009 11:54 AM
LINUX - linking archive (static library) with shared (dynamic) library gurkama Programming 5 03-04-2007 11:11 PM
Hiding Symbols in Static Libraries JCipriani Programming 2 03-03-2006 05:15 PM
Making static symbols private/local in shared libraries skoona Programming 1 02-18-2005 03:14 PM
howto compile bin with my library using all-static and shared linked standart library stpg Programming 4 06-29-2004 04:20 AM


All times are GMT -5. The time now is 09:40 PM.

Main Menu
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
identi.ca: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration