Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com Message-ID: <3B0EFD2E.37E494EA@ece.gatech.edu> Date: Fri, 25 May 2001 20:47:42 -0400 From: "Charles S. Wilson" X-Mailer: Mozilla 4.77 [en] (WinNT; U) X-Accept-Language: en MIME-Version: 1.0 To: Ross Smith CC: cygwin AT cygwin DOT com Subject: Re: Can't link simple png test program. References: Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit 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 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. says, "use the system png.h" #2. link flags must come after the targets. gcc -L/lib pngtest.c -lpng #3. 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. 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 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