This is the mail archive of the cygwin@cygwin.com 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]

Re: Can't link simple png test program.


Ross Smith wrote:
> 
> Using cygwin 1.3.2, when I compile pngtest.c:
> 
> #include "png.h"
> 
> int main() {
>   png_info_init(0);
>   return 0;
> }
> 
> with
> 
> % gcc -lpng -L/lib pngtest.c
> 
> I get:
> 
> /tmp/ccflselC.o(.text+0x11):pngtest.c: undefined reference to
> `png_info_init'
> collect2: ld returned 1 exit status
> 
> Even though /lib/libpng.a contains png_info_init.

Sigh.  Read /usr/doc/Cygwin/libpng*.README.  There are about five
misconceptions demonstrated in your test program.

#1.  #include <png.h>  NOT #include "png.h"
"png.h" implies that you're using a special png.h file in the same
directory as your pngtest.c file.  <png.h> says, "use the system png.h"

#2. link flags must come after the targets.  
gcc -L/lib pngtest.c -lpng

#3. <stylistic>  even though /lib and /usr/lib are *usually* mounted
such that they are identical, it's better to say '-L/usr/lib' instead of
'-L/lib' since that's how all cygwin packages are configured.

#4. <stylistic> even then, /usr/lib is in the default library search
path, so it's unnecessary to specify it.
gcc pngtest.c -lpng

#5. libpng depends on libz, so you must include -lz after -lpng
gcc pngtest.c -lpng -lz

#6. Default link method is shared, so the fact that "libpng.a" contains
png_info_init is immaterial. You're not linking against libpng.a, you're
linking against libpng.dll.a, the dll import lib.  To link statically,
you need:
gcc -static pngtest.c -lpng -lz

#7. But even *that* won't work, because the header file, png.h, is set
up to define functions and variables appropriate for dll linking.  So,
in addition to LINKING statically (-static) you also need to insure that
you are COMPILING with the appropriate definitions (for both zlib and
libpng)
gcc -static -DPNG_STATIC -DZLIB_STATIC pngtest.c -lpng -lz

#8. Finally, "png_info_init" is deprecated!  Therefore, it is
unavailable when linking dynamically (the fact that you can still link
to the symbol when linking statically, and that 'nm -a' show the symbol
in libpng.a, is a loophole -- but that doesn't change the fact that the
function is deprecated)  png.h sez:

/* Initialize the info structure (old interface - NOT DLL EXPORTED) */
extern void png_info_init PNGARG((png_infop info_ptr));

So, you CAN work around it as shown in #7, but you shouldn't.  If you're
just testing link success, do:
#include <png.h>
int main() {
  png_create_info_struct(0);
  return 0;
}

This code snippet is broken (that is, don't try to run the executable
because it'll coredump with a null pointer exception -- but so does your
example).

With MY code snippet, the following command works:
  gcc mypng.c -lpng -lz
and the resulting exe is dynamically linked. You can also do
  gcc -static -DPNG_STATIC -DZLIB_STATIC mypng.c -lpng -lz 
and the resulting exe is statically linked.

--Chuck

--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple


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