[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: CygWin woes
From: |
Charles Wilson |
Subject: |
Re: CygWin woes |
Date: |
Thu, 24 Apr 2003 23:50:11 -0400 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4a) Gecko/20030401 |
Earnie Boyd wrote:
Disagree 100%. The whole point of my work and that of others over the
last 2.5 years concerning auto-import in gcc, binutils, automake,
autoconf, and libtool was precisely so that -- on cygwin at least, if
not on mingw -- we can discard those damn declspec() atrocities.
PLEASE don't encourage cygwin users to go back to the dark ages...
If you want to be portable between all the different vendors of win32
build tools; then, you will do as I suggest. What I suggest is the MS
officially documented method. So, I will suggest it as much as possible
although I will now clarify upfront as to why.
But *cygwin* is already sandboxed. You really can't link against a
cygwin binary using any buildtool other than a cygwin gcc/ld (or
cross-tools for cygwin), *unless* you are prepared for much pain and
extreme effort. Thus, my request to NOT recomment this practice for
*cygwin* ports -- as it is a lot of effort for virtually no benefit.
It's a different story for MSVC or mingw, of course.
Concrete example: Suppose we have a cross-platform project "foobaz".
Foobaz, right now, builds a shared library and an application on just
about any unix platform. Solaris .so's, Linux .so's, HPUX .sl's, AIX
.dylibs or whatever, you get the picture.
Now, Jane wants to build it on pure Windows, and chooses to use
mingw/MSYS as her development platform. Now, libtool&friends on MSYS
*do* support auto-import; Jane could simply re-auto-tool with the latest
versions (and maybe throw in a -no-undefined flag in the Makefile.am's)
and it would "Just Work(tm)." No declspec required.
BUT, that is not The Microsoft Way -- and while her executable will run
on any Windows box, she cannot develop against the shared library (.dll)
using MSVC or Borland or whatever -- as you pointed out. Jane's locked
into the MSYS/mingw world for future development thanks to the fancy
auto-import (and maybe even runtime-pseudo-reloc) tricks. This is, in
general, a bad thing for pure windows ports.
So, I fully understand that PURE windows ports (and perhaps most mingw
ports, if you consider them to be distinct) would benefit from explicit
declspec() nastiness.
Cygwin apps and libraries are an entirely different beast. We're
ALREADY locked in to the cygwin/gcc world for future development. You
can NEVER(*) use MSVC to link against cygwin-built DLLs anyway...
(*) never say never. Technically it is possible, but quite difficult to
do correctly.
Now, I know how ugly the declspec #define tree can get. I've attached
the current ncurses_dll.h header file to show how ugly these things are.
And most of the packages that I maintain for cygwin, I originally
"dll-ized" and ported this way, before auto-import was available. You
know what I discovered?
Very very few of the "real" maintainers had any interest in accepting
such uglifying patches -- even when I pointed out that these cygwin
(declspec) patches would assist any eventual pure windows port. Bruno
Haible (iconv?, gettext), for instance, was quite firm.
I'd prefer to now treat cygwin much more unix like, and save the
declspec() for
#if defined(WIN32) && !(defined(__CYGWIN__) || defined(__MINGW__))
that way MSVC gets the declspec nastiness, and cygwin and mingw are
spared. OR possibly
#if defined(WIN32) && !defined(__CYGWIN__)
thus lumping mingw in with MSVC if you prefer. See the second
attachment (do a diff to make things clear...). Mainly, it's selfish
laziness: I find it's much easier to get cygwin-ifying patches accepted
into the official "upstream" sources if they are not intrusive -- and
you don't get much more intrusive than redeclaring every single function
and extern var in a library! I'll let the pure windows people fight
*that* battle.
However, what I really really dislike about the declspec() stuff is that
it mucks up XEmacs's function search menu -- it parses any given file
into 27 functions named "NCURSES_EXPORT()" -- and my
"ncurses_dll_better.h" doesn't fix that.
--Chuck
/* $Id: ncurses_dll.h,v 1.2 2001/12/09 01:36:34 tom Exp $ */
#ifndef NCURSES_DLL_H_incl
#define NCURSES_DLL_H_incl 1
/* no longer needed on cygwin or mingw, thanks to auto-import */
/* but this structure may be useful at some point for an MSVC build */
/* so, for now unconditionally define the important flags */
/* "the right way" for proper static and dll+auto-import behavior */
#undef NCURSES_DLL
#define NCURSES_STATIC
#if defined(__CYGWIN__)
# if defined(NCURSES_DLL)
# if defined(NCURSES_STATIC)
# undef NCURSES_STATIC
# endif
# endif
# undef NCURSES_IMPEXP
# undef NCURSES_API
# undef NCURSES_EXPORT
# undef NCURSES_EXPORT_VAR
# if defined(NCURSES_DLL)
/* building a DLL */
# define NCURSES_IMPEXP __declspec(dllexport)
# elif defined(NCURSES_STATIC)
/* building or linking to a static library */
# define NCURSES_IMPEXP /* nothing */
# else
/* linking to the DLL */
# define NCURSES_IMPEXP __declspec(dllimport)
# endif
# define NCURSES_API __cdecl
# define NCURSES_EXPORT(type) NCURSES_IMPEXP type NCURSES_API
# define NCURSES_EXPORT_VAR(type) NCURSES_IMPEXP type
#endif
/* Take care of non-cygwin platforms */
#if !defined(NCURSES_IMPEXP)
# define NCURSES_IMPEXP /* nothing */
#endif
#if !defined(NCURSES_API)
# define NCURSES_API /* nothing */
#endif
#if !defined(NCURSES_EXPORT)
# define NCURSES_EXPORT(type) NCURSES_IMPEXP type NCURSES_API
#endif
#if !defined(NCURSES_EXPORT_VAR)
# define NCURSES_EXPORT_VAR(type) NCURSES_IMPEXP type
#endif
#endif /* NCURSES_DLL_H_incl */
/* $Id: ncurses_dll.h,v 1.2 2001/12/09 01:36:34 tom Exp $ */
#ifndef NCURSES_DLL_H_incl
#define NCURSES_DLL_H_incl 1
/* For MSVC - by default, we assume that the unit being
compiled is intended to be linked against the DLL.
For other behaviors (building the DLL itself, or
building/linking-to the static library) you must
#define the appropriate macro.
*/
#if defined(WIN32) && !(defined(__CYGWIN__) || defined(__MINGW__))
# if defined(NCURSES_DLL)
# if defined(NCURSES_STATIC)
# undef NCURSES_STATIC
# endif
# endif
# undef NCURSES_IMPEXP
# undef NCURSES_API
# undef NCURSES_EXPORT
# undef NCURSES_EXPORT_VAR
# if defined(NCURSES_DLL)
/* building a DLL */
# define NCURSES_IMPEXP __declspec(dllexport)
# elif defined(NCURSES_STATIC)
/* building or linking to a static library */
# define NCURSES_IMPEXP /* nothing */
# else
/* linking to the DLL */
# define NCURSES_IMPEXP __declspec(dllimport)
# endif
# define NCURSES_API __cdecl
# define NCURSES_EXPORT(type) NCURSES_IMPEXP type NCURSES_API
# define NCURSES_EXPORT_VAR(type) NCURSES_IMPEXP type
#endif
/* Take care of non-MSVC platforms */
#if !defined(NCURSES_IMPEXP)
# define NCURSES_IMPEXP /* nothing */
#endif
#if !defined(NCURSES_API)
# define NCURSES_API /* nothing */
#endif
#if !defined(NCURSES_EXPORT)
# define NCURSES_EXPORT(type) NCURSES_IMPEXP type NCURSES_API
#endif
#if !defined(NCURSES_EXPORT_VAR)
# define NCURSES_EXPORT_VAR(type) NCURSES_IMPEXP type
#endif
#endif /* NCURSES_DLL_H_incl */