Subject: Re: bug#9960: Compiling Emacs trunk with MSVC

From: Fabrice Popineau <[email-masked]>
Date: Fri, 11 Nov 2011 20:28:21 +0100

>
> Yes, though if the changes are significant, they will probably not
> make it into Emacs 24.1.  Plus, I think you will need to sign legal
> papers to contribute more than what you already have.  (I can
> currently find on file your assignment only to Gnus.)
>
>
Ok, I'll do it if needed. Albeit it is almost only a matter of configuring
the right defines.

>  > I have added two other files : a 64bits manifest for emacs.exe and a
> > w32compat.h header file that is needed to compile the above mentioned
> > libraries. In my case, this w32compat.h is included while compiling
> image.c
> > for example.
>
> Is this for a 64-bit build, or is this needed for a 32-bit build as
> well?  If for a 32-bit built, then what exactly are the problems with
> image.c that requires w32compat.h?
>
>
The problem is that image.c includes png.h (for example) and png.h
may compile out of the box ... or not. In my case, I always try to compile
all the libraries with the same set of defines and options. So I included
this
file for completeness.

I have both the  7.1 MS SDK and VS2010 installed on my machine.
Using this w32compat.h plus the emacs/nt/inc and emacs/lib,
I was able to compile all the libraries
(32bits and 64 bits versions). And emacs too of course.

> > +#ifndef _MSC_VER
> >        extern char **environ;
> > +#endif
>
> Which MSVC header has the necessary declaration, and what is that
> declaration?
>

#include <stdlib.h>
is enough.

Extract :

#if !defined(_M_CEE_PURE)
#ifdef  _POSIX_
extern char ** environ;             /* pointer to environment table */
#else
_CRTIMP extern char ** _environ;    /* pointer to environment table */
_CRTIMP extern wchar_t ** _wenviron;    /* pointer to wide environment
table */
#endif  /* _POSIX_ */
#else

_CRTIMP char*** __cdecl __p__environ(void);
_CRTIMP wchar_t*** __cdecl __p__wenviron(void);
_CRT_INSECURE_DEPRECATE_GLOBALS(_get_pgmptr) _CRTIMP char** __cdecl
__p__pgmptr(void);
_CRT_INSECURE_DEPRECATE_GLOBALS(_get_wpgmptr) _CRTIMP wchar_t** __cdecl
__p__wpgmptr(void);

#define _environ   (*__p__environ())
#define _wenviron  (*__p__wenviron())
#define _pgmptr    (*__p__pgmptr())
#define _wpgmptr   (*__p__wpgmptr())

#endif /* !defined(_M_CEE_PURE) */

> > --- lib/strftime.c    2011-03-31 04:24:03 +0000
> > +++ lib/strftime.c    2011-11-10 17:39:37 +0000
> > @@ -36,9 +36,14 @@
> >  #include <ctype.h>
> >  #include <time.h>
> >
> > +#ifdef _MSC_VER
> > +#define tzname _tzname
> > +#else
> >  #if HAVE_TZNAME && !HAVE_DECL_TZNAME
> >  extern char *tzname[];
>
> Can we instead modify the #define on src/s/ms-w32.h so as to include
> versions of MSVC above 1400?  Or does that not work for some reason?

Ok, I removed the restriction on MSVC version below 1400 and that is
compiling.

> > --- lisp/bindings.el  2011-10-08 16:37:46 +0000

> +++ lisp/bindings.el  2011-11-10 17:49:35 +0000
> > @@ -824,13 +824,13 @@
> >  ;; Define control-digits.
> >  (let ((i ?0))
> >    (while (<= i ?9)
> > -    (define-key global-map (read (format "[?\\C-%c]" i))
> 'digit-argument)
> > +;    (define-key global-map (read (format "[?\\C-%c]" i))
> 'digit-argument)
> >      (setq i (1+ i))))
> >  (define-key global-map [?\C--] 'negative-argument)
> >  ;; Define control-meta-digits.
> >  (let ((i ?0))
> >    (while (<= i ?9)
> > -    (define-key esc-map (read (format "[?\\C-%c]" i)) 'digit-argument)
> > +;    (define-key esc-map (read (format "[?\\C-%c]" i)) 'digit-argument)
> >      (setq i (1+ i))))
> >  (define-key global-map [?\C-\M--] 'negative-argument)
>
> Why is this part needed?
>

I would like to know. I get an error when bootstrapping at these lines :
invalid read syntax.
If someone has a suggestion on how to investigate it, I'd like to hear it:

Loading bindings (source)...
Invalid read syntax: "?"
NMAKE : fatal error U1077:
'C:\Source\XEmTeX\mirror\emacs\src/obj-spd/i386/temacs.exe' : return code
'0xffffffff'
Stop.
NMAKE : fatal error U1077: '"c:\Program Files (x86)\Microsoft Visual Studio
10.0\VC\Bin\nmake.exe"' : return code '0x2'
Stop.

It is failing only while bootstrapping, not during  the regular build.

> === modified file 'src/makefile.w32-in'
> > --- src/makefile.w32-in       2011-11-05 22:55:08 +0000
> > +++ src/makefile.w32-in       2011-11-10 02:16:49 +0000
> > @@ -177,7 +177,7 @@
> >  $(TEMACS):      $(TLIB0) $(TLIB1) $(TLIB2) $(TLASTLIB) $(TOBJ) $(TRES) \
> >                 ../nt/$(BLD)/addsection.exe $(GNULIB)
> >       $(LINK) $(LINK_OUT)$(TEMACS_TMP) $(FULL_LINK_FLAGS) $(TOBJ)
> $(TRES) $(LIBS)
> > -     "$(THISDIR)/../nt/$(BLD)/addsection" "$(TEMACS_TMP)" "$(TEMACS)"
> EMHEAP 21
> > +     "$(THISDIR)/../nt/$(BLD)/addsection" "$(TEMACS_TMP)" "$(TEMACS)"
> EMHEAP 42
>
> Is such a large heap really needed for a 32-bit MSVC build?  Or is it
> for the 64-bit build?

I tried to double it for the 64 bits build in the hope it will let me go a
bit further.
Maybe that size is not needed even in this case. So forget it for the
moment.

Also, it seems that it is possible to declare segments using #pragma
and that they can even be resized using the editbin tool (available with
the sdk). That may make addsection useless, and wrt to a 64bits build,
I would be more confident in using the sdk tools if possible.

I'll try to remove the use of addsection if possible. Well, if someone has
a good reason
for which it is not possible, let me know.

> -#if (defined(_MSC_VER) && defined(emacs)) || defined(USE_CRT_DLL)
> > +#if (defined(_MSC_VER) && defined(emacs))
> >  #define malloc e_malloc
> >  #define free   e_free
> >  #define realloc e_realloc
>
> What was the problem that required this change?

Linking all other programs except emacs.
For the other programs, you surely don't want to define malloc to be
e_malloc  ?

Being able to link against libc or msvcrt is confusing.
Wouldn't it be better if only MSVCRT was supported ?
Does the build work with the static libc ?

Best regards,

Fabrice