This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: how to compile the .so to allow extern functions


andy wang wrote:

> I want to compile a .so which contains extern function that may be

Shared libraries have the extension .DLL on windows.  You can make one
that is named .so, but it will be utterly confusing, because it is still
a DLL just with a nonstandard extension.  And the tools are all
configured to search for libraries named .dll by default not .so, so
standard makefiles that expect to be able to just specify "-lfoo" to
link against a library 'foo' will not work.  You will only make your
life harder by insisting on naming a .dll as .so.

> defined on the main program.
> The following file can be compiled on linux without any problem but
> how to compile it on cygwin?
> 
> $ cat bug1.c
> //this will be .so and will call an extern func1() in the main proc
> int func1();
> int myfunc()
> {
>   printf("in myfunc.so");
>   func1();
> }
> 
> $ gcc -o bug1.so -shared bug1.c
> /cygdrive/c/DOCUME~1/Flyiky/LOCALS~1/Temp/ccBB7v0l.o:
> bug1.c:(.text+0x13): undefined reference to `_func1'
> collect2: ld returned 1 exit status

As much as we would like to change it, Win32 is fundamentally different
from ELF in terms of how linking works.  You need to read up on how the
Win32 linker works, in particular dllimport and dllexport.  There is a
whole Win32 chapter in the ld manual (which is online at the binutils
site) that is packed with info, and it's also explained in the Cygwin
users guide I'm pretty sure.

The particular question of having a DLL that imports a function exported
from the main .exe comes up from time to time.  It is possible, but not
necessarily pretty.  If it is only a one-way dependency then it's rather
simple to mark the symbol as dllexport in the .exe, create an import
library for the .exe (yes the .exe) during linking, and then link the
.dll against that import library.

If the dependency is two-way though, i.e. the .dll imports a function
from the .exe and the .exe imports a function from the .dll, then you
have a circular dependency and neither module can be built first since
they both require a import lib (or direct-DLL linking) of the other at
link-time.  You have to break this circular dependency by making an
import lib by hand with a .def file, rather than automatically creating
it as a side effect of linking.

Both of these are considered bad form though, because it hard codes the
name of the .exe in the .dll which means the .dll is useless as a
general purpose library.  The preferred solution is to factor out the
common code into its own .dll and import from it in both the .exe and
the other .dll.

A final option that breaks the link-time requirement to have no
undefined symbols is to do dynamic linking with GetProcAddress and
LoadModule (or in the specific case of Cygwin, dlopen/dlsym.)  But this
gets ugly if you have lots of symbols or in the case of mangled C++
symbols.

Also, consider using libtool.  Every platform has its own unique and
different implementation of how shared libraries work, each with its own
quirks.  Libtool was thus created to provide a portable interface to
creating libraries that works across this entire spectrum, without
having to know all the details of how each linker works.

Brian

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]