ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
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.
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.
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.
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.
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?
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.
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?
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.
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.
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
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:
//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.
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.
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.
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.