conditionally linking to mingw32 library

classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

conditionally linking to mingw32 library

Mark Brand
I'm not very experienced with the GNU build tools, but I've managed to
get a couple simple autoconf/automake configurations to work. My goal
now is to build for Linux or Mingw32 starting with the same configure.ac
and Makefile.am files. My generate/configure/make steps are:

    autoheader
    touch NEWS README AUTHORS ChangeLog
    touch stamp-h
    aclocal
    autoconf
    automake -a
    ./configure
    make

For Mingw32, the configure step looks like this:

    ./configure --with-msw --target=i586-mingw32msvc
--host=i586-mingw32msvc --build=i386-linux

The good news is that this works well. However, for a program that uses
the sockets interface, the Mingw32 version needs to link to the winsock
library ws2_32. If I add to Makefile.am the line:

    myprogram_LDADD = -lws2_32

then the Ming32 version can build, but the Linux version gets a link
error. So, obviously it would be nice to make this LDADD line conditional.

To reach this lofty goal, I've been trying to apply the example in

        http://lists.gnu.org/archive/html/automake/2002-11/msg00116.html

to my situation, but I'm getting stuck. I have:

<configure.ac>
 if test x$target_os == xmingw32; then
    WINSOCK=-lws2_32
 fi
 AC_SUBST(WINSOCK)
</configure.ac>

<Makefile.am>
 myprogram_LDADD := @LTLIBINTL@ @WINSOCK@
</Makefile.am>

My generated Makefile contains:

    WINSOCK = @WINSOCK@

When I build (for either target) I get this error:

    g++  -g -O2   -o myprogram  main.o  @WINSOCK@
    g++: @WINSOCK@: No such file or directory
    make[2]: *** [myprogram Error 1


Can someone explain what's going on and set me straight? Is there a
better standard approach to this?

On a related matter, do I need to do something else to assign a value to
target_os, of does the configure script take care of this?

By the way, this is all happening on Debian Sarge with:

m4 1.4.2-1
autoconf 2.59a-3
automake 1.9.5-1
mingw32 3.4.2.20040
mingw32-binutils 2.15.94-200
mingw32-runtime 3.7-1


Regards,

Mark


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: conditionally linking to mingw32 library

Ralf Wildenhues
Hi Mark,

* Mark Brand wrote on Wed, Jun 01, 2005 at 02:41:58PM CEST:
>
> to my situation, but I'm getting stuck. I have:
>
> <configure.ac>
>  if test x$target_os == xmingw32; then

Don't use the test operator `==' , it's unportable and completely
superfluous, as `=' does string comparison just fine.

>     WINSOCK=-lws2_32
>  fi
>  AC_SUBST(WINSOCK)
> </configure.ac>
>
> <Makefile.am>
>  myprogram_LDADD := @LTLIBINTL@ @WINSOCK@

Use
  myprogram_LDADD = $(LTLIBINTL) $(WINSOCK)

as `:=' assignment is not portable, and, as you already learned,
automake will set the WINSOCK make variable for you in the generated
Makefile.in.  (The recommendation to use the make variables over the
substituted values is rather one of style.)

> </Makefile.am>
>
> My generated Makefile contains:
>
>     WINSOCK = @WINSOCK@
>
> When I build (for either target) I get this error:
>
>     g++  -g -O2   -o myprogram  main.o  @WINSOCK@
>     g++: @WINSOCK@: No such file or directory
>     make[2]: *** [myprogram Error 1
>

Let me guess: You did rerun automake but forgot rerunning either
autoconf or configure (in that order)?

Regards,
Ralf


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: conditionally linking to mingw32 library

Mark Brand

>>to my situation, but I'm getting stuck. I have:
>>
>><configure.ac>
>> if test x$target_os == xmingw32; then
>>    
>
>Don't use the test operator `==' , it's unportable and completely
>superfluous, as `=' does string comparison just fine.
>
>  
>>    WINSOCK=-lws2_32
>> fi
>> AC_SUBST(WINSOCK)
>></configure.ac>
>>
>><Makefile.am>
>> myprogram_LDADD := @LTLIBINTL@ @WINSOCK@
>>    
>
>Use
>  myprogram_LDADD = $(LTLIBINTL) $(WINSOCK)
>
>as `:=' assignment is not portable, and, as you already learned,
>automake will set the WINSOCK make variable for you in the generated
>Makefile.in.  (The recommendation to use the make variables over the
>substituted values is rather one of style.)
>
>  

Would you please elaborate on the difference between "make variables"
and "substituted values" here?  I'm still very new to this.

>></Makefile.am>
>>
>>My generated Makefile contains:
>>
>>    WINSOCK = @WINSOCK@
>>
>>When I build (for either target) I get this error:
>>
>>    g++  -g -O2   -o myprogram  main.o  @WINSOCK@
>>    g++: @WINSOCK@: No such file or directory
>>    make[2]: *** [myprogram Error 1
>>
>>
>>    
I've made the changes you suggest. Now I have in configure.ac:

    if test x$target_os = xmingw32; then
        WINSOCK=-lws2_32
    fi
    AC_SUBST([WINSOCK])


and in Makefile.am:

    myprogram_LDADD = $(LTLIBINTL) $(WINSOCK)


The generated Makefile still contains:

    WINSOCK = @WINSOCK@
    myprogram_LDADD = $(LTLIBINTL) $(WINSOCK)


(I have to admit I don't really know what the @ signs mean in
Makefile.)  Anyway, I still see this when I run make:

    g++  -g -O2   -o myprogram  main.o @WINSOCK@
    g++: @WINSOCK@: No such file or directory
    make[2]: *** [myprogram] Error 1


>Let me guess: You did rerun automake but forgot rerunning either
>autoconf or configure (in that order)?
>  

No, actually I've been running all of the following each time:

    autoheader
    touch NEWS README AUTHORS ChangeLog
    touch stamp-h
    aclocal
    autoconf
    automake -a
    /.configure
    make



Mark


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: conditionally linking to mingw32 library

Stepan Kasal
In reply to this post by Mark Brand
Hello,

On Wed, Jun 01, 2005 at 02:41:58PM +0200, Mark Brand wrote:
>     touch stamp-h

why do you need this?  It looks wrong.

>     ./configure --with-msw --target=i586-mingw32msvc
> --host=i586-mingw32msvc --build=i386-linux

Are you cross compiling?
--build=i386-linux says you are building on GNU/Linux, and the resulting
executable files will be copied to --host=i586-mingw32msvc .

Is that really what you intend?  Why you cannot build the package on
the OS where it will run?  If you built the package on your mingw32msvc
system, then the following should be enough:
        ./configure --with-msw

(Only in case the system cannot be autodetected, use:
        ./configure --with-msw --build=i586-mingw32msvc
and report the problem to [hidden email].)

--target is only used for tools which generated machine code, eg. compilers
or linkers.  If your program is not a compiler, you don't need --target.
Please don't use it.

>  if test x$target_os == xmingw32; then

But then, of course, you have to use $host_os here.

>     myprogram_LDADD = -lws2_32

The best solution is to use
        AM_CONDITIONAL([MINGW32], [test "x$host_os" = xmingw32])
in configure.ac

See http://sourceware.org/automake/automake.html#Conditionals

and in Makefile.am:
        if MINGW32
                myprogram_LDADD = -lws2_32
        endif

>  myprogram_LDADD := @LTLIBINTL@ @WINSOCK@

You should use $(LTLIBINTL) $(WINSOCK) here.  You can use this syntax,
because the make variable WINSOCK is defined in the Makefile.in:

>     WINSOCK = @WINSOCK@

> My generated Makefile contains:
>     WINSOCK = @WINSOCK@

It's wrong.  This line is in Makefile.in, but when you run ./configure
then it replaces @WINSOCK@ with a value.
AC_SUBST([WINSOCK]) required this.

Have you regenerated ./configure by autoconf?
Have you re-run ./configure?

Then you shouldn't see any @WINSOCK@ in the generated Makefiles.

Normally, make does all the necessary refresh.  Perhaps you used ``touch''
again.  Beware, ``touch'' is a very dangerous program.  ;-)

HTH,
        Stepan


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: conditionally linking to mingw32 library

Tomás-27
In reply to this post by Mark Brand
On Wed, Jun 01, 2005 at 04:44:39PM +0200, Mark Brand wrote:

[I'm too dumb to answer that, but...]

> Would you please elaborate on the difference between "make variables"
> and "substituted values" here?  I'm still very new to this.

This one I can answer: the "make variables" are those $FOO thingies.
They get substituted by make when interpreting the make file. The
"substituted values" are those @FOO@ thingies. They live in Makefile.in
(actually in other foo.in files as well) and get textually substituted
(the AC_OUTPUT macro controls which files to transform), making e.g.
a Makefile out of a Makefile.in

> >></Makefile.am>
> >>
> >>My generated Makefile contains:
> >>
> >>    WINSOCK = @WINSOCK@

Something must have gone wrong then. This shouldn't be seen in Makefile,
only in Makefile.in (the template from which Makefile is generated).

Regards
-- tomás

attachment0 (196 bytes) Download Attachment
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: conditionally linking to mingw32 library

Alexandre Duret-Lutz
In reply to this post by Mark Brand
>>> "Mark" == Mark Brand <[hidden email]> writes:

[...]

 Mark> <configure.ac>
 Mark> if test x$target_os == xmingw32; then
 Mark> WINSOCK=-lws2_32
 Mark> fi
 Mark> AC_SUBST(WINSOCK)
 Mark> </configure.ac>

Eww.  That would be $host, not $target, and anyway testing the
host type should always be your last resort.  Why not test for
the presence of the ws2_32 library and use it if it's there ?

Here is a possible check assuming adding -lws2_32 to LIBS is OK
(but it's easy to define WINSOCK as above if you prefer).


AC_SEARCH_LIBS([gethostbyname], [nsl socket], [], [
dnl Can't search ws2_32 for gethostbyname using AC_SEARCH_LIBS, because
dnl it requires #include <winsocks2.h> to work.
my_old_LIBS=$LIBS
LIBS="-lws2_32 $LIBS"
ws2_res=yes
AC_MSG_CHECKING([for gethostbyname in ws2_32])
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <winsock2.h>]],
                                [[gethostbyname ("");]])],
               [], [LIBS=$my_ac_save_LIBS ws2_res=no])
AC_MSG_RESULT([$ws2_res])
])
--
Alexandre Duret-Lutz



Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: conditionally linking to mingw32 library

Stepan Kasal
Hi,

On Wed, Jun 01, 2005 at 09:43:22PM +0200, Alexandre Duret-Lutz wrote:
> Why not test for
> the presence of the ws2_32 library and use it if it's there ?
...
> AC_SEARCH_LIBS([gethostbyname], [nsl socket], [], [
> dnl Can't search ws2_32 for gethostbyname using AC_SEARCH_LIBS, because
> dnl it requires #include <winsocks2.h> to work.
...

perhaps it's obvious, but let me get it straight:

This solution is much better and cleaner than the one I posted.

(Future versions of mingw might contain libnsl or libsocket, for example.
Or perhaps another window platform could also require winsocks2.)

Thank you, Alexandre, for sharing your bright inside with us!

Stepan Kasal


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: conditionally linking to mingw32 library

Mark Brand-2
In reply to this post by Alexandre Duret-Lutz

>>>>"Mark" == Mark Brand <[hidden email]> writes:
>>>>        
>
>[...]
>
> Mark> <configure.ac>
> Mark> if test x$target_os == xmingw32; then
> Mark> WINSOCK=-lws2_32
> Mark> fi
> Mark> AC_SUBST(WINSOCK)
> Mark> </configure.ac>
>
>Eww.  That would be $host, not $target, and anyway testing the
>host type should always be your last resort.  Why not test for
>the presence of the ws2_32 library and use it if it's there ?
>
>Here is a possible check assuming adding -lws2_32 to LIBS is OK
>(but it's easy to define WINSOCK as above if you prefer).
>
>
>AC_SEARCH_LIBS([gethostbyname], [nsl socket], [], [
>dnl Can't search ws2_32 for gethostbyname using AC_SEARCH_LIBS, because
>dnl it requires #include <winsocks2.h> to work.
>my_old_LIBS=$LIBS
>LIBS="-lws2_32 $LIBS"
>ws2_res=yes
>AC_MSG_CHECKING([for gethostbyname in ws2_32])
>AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <winsock2.h>]],
>                                [[gethostbyname ("");]])],
>               [], [LIBS=$my_ac_save_LIBS ws2_res=no])
>AC_MSG_RESULT([$ws2_res])
>])
>  

I agree that this is a more elegant solution. Thanks.

"my_old_LIBS" and "my_ac_save_LIBS" were meant to be the same variable,
right?

Thanks. Even though "./configure --with-msw --target=i586-mingw32msvc
--host=i586-mingw32msvc --build=i386-linux" reports that  that it finds
gethostbyname in ws2_32, the generated Makefile has a line:

    LIBS =

I must be missing something obvious.


Mark


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: conditionally linking to mingw32 library

Mark Brand
In reply to this post by Alexandre Duret-Lutz
Alexandre Duret-Lutz wrote:

>>>>"Mark" == Mark Brand <[hidden email]> writes:
>>>>        
>
>[...]
>
> Mark> <configure.ac>
> Mark> if test x$target_os == xmingw32; then
> Mark> WINSOCK=-lws2_32
> Mark> fi
> Mark> AC_SUBST(WINSOCK)
> Mark> </configure.ac>
>
>Eww.  That would be $host, not $target, and anyway testing the
>host type should always be your last resort.  Why not test for
>the presence of the ws2_32 library and use it if it's there ?
>
>Here is a possible check assuming adding -lws2_32 to LIBS is OK
>(but it's easy to define WINSOCK as above if you prefer).
>
>
>AC_SEARCH_LIBS([gethostbyname], [nsl socket], [], [
>dnl Can't search ws2_32 for gethostbyname using AC_SEARCH_LIBS, because
>dnl it requires #include <winsocks2.h> to work.
>my_old_LIBS=$LIBS
>LIBS="-lws2_32 $LIBS"
>ws2_res=yes
>AC_MSG_CHECKING([for gethostbyname in ws2_32])
>AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <winsock2.h>]],
>                                [[gethostbyname ("");]])],
>               [], [LIBS=$my_ac_save_LIBS ws2_res=no])
>AC_MSG_RESULT([$ws2_res])
>])
>  

I found my obvious and fundamental mistake.  In configure.ac, my
AC_OUTPUT line came before the AC_SEARCH_LIBS. Studying the generated
configure script made this clear.  Thanks very much for your help.

Mark


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: conditionally linking to mingw32 library

Alexandre Duret-Lutz-2
In reply to this post by Mark Brand-2
>>> "Mark" == Mark Brand <[hidden email]> writes:

[...]

 Mark> "my_old_LIBS" and "my_ac_save_LIBS" were meant to be the same variable,
 Mark> right?

Yep.  Bits of this code were stolen from Curl's configure.ac.

 Mark> Thanks. Even though "./configure --with-msw --target=i586-mingw32msvc
 Mark> --host=i586-mingw32msvc --build=i386-linux"

./configure --with-msw --host=i586-mingw32msvc

 Mark> reports that that it finds gethostbyname in ws2_32, the
 Mark> generated Makefile has a line:

 Mark> LIBS =

 Mark> I must be missing something obvious.

Maybe.  It works fine for me.  Could you post a complete test
case with instructions to reproduce your problem?
--
Alexandre Duret-Lutz



Loading...