ruby--ruby/win32
Alan Wu e6f4a39a4d MJIT MSVC: Use /Z7 to avoid PDB write race
With MSVC, MJIT uses the /Fd option on an installed PDB file when
compiling. Combined with the /Zi option, this causes the PDB file to be
modified every time MJIT compiles. Concurrent modifications to the same
PDB file is known to cause problems. MSVC even has an option, /FS to
deal with it. When running MJIT tests in parallel, sometimes this leads
to corrupting the PDB file, breaking subsequent compilations. On CI,
we get messages like these:

    rb_mjit_header-3.1.0.pdb is not the pdb file that was used when this precompiled header was created, recreate the precompiled header.

To avoid this race, use the /Z7 option when building precompiled header,
which asks the compiler to put debug info into the .obj file,
eliminating the need for pointing the compiler to the PDB file for the
precompiled header.

The /Fd option is changed to use a unique path based on the name of the
dll output. Because of the /debug linker flag, we generate a PDB file
at runtime even though we use /Z7.

There are a couple things missing from this change:
 - Because MJIT uses the interpreter's CFLAGS build option and that
   contains /Zi, putting /Z7 at the end leads to a build warning
 - With /Z7 no PDB file is built anymore, so the code for installing
   the PDB file can be removed

There might also be other problems with this change I haven't noticed
while developing this change using Github Actions. I don't have a
Windows dev environment with Visual Studio so I can't finish this
change easily. Please feel free to complete this change if it makes
sense.

Note:
 - On master, you can see the PDB file changing with llvm-pdbutil or a
   simple checksum. There is an age field in the file that is bumped
 - I'm not sure if users can specify compile flags on MSVC. If they
   couldn't, maybe it's easier to change MJIT's compile options to
   use /Z7 when building the precompile header.
 - MJIT could pass different options at runtime to generate fewer
   files. Right now it inherits the /DEBUG linker flag which causes
   a PDB file to be generated at runtime even though /Z7 is used.

Relevant MSVC docs:
 - [/Zi,/Z7](https://docs.microsoft.com/en-us/cpp/build/reference/z7-zi-zi-debug-information-format?view=msvc-160)
 - [/DEBUG](https://docs.microsoft.com/en-us/cpp/build/reference/debug-generate-debug-info?view=msvc-160)
 - [/FS](https://docs.microsoft.com/en-us/cpp/build/reference/fs-force-synchronous-pdb-writes?view=msvc-160)
2021-11-24 23:45:57 +09:00
..
.document
Makefile.sub
README.win32
configure.bat
dir.h
enc-setup.mak
file.c
file.h
ifchange.bat
makedirs.bat
mkexports.rb
resource.rb
rm.bat
rmdirs.bat
rtname.cmd
ruby.manifest
setup.mak
win32.c
winmain.c

README.win32

# -*- rdoc -*-

= How to build ruby using Visual C++

== Requirement

1.  Windows 7 or later.

2.  Visual C++ 12.0 (2013) or later.

    [Note] if you want to build x64 version, use native compiler for
           x64.

3.  Please set environment variable +INCLUDE+, +LIB+, +PATH+
    to run required commands properly from the command line.

    [Note] building ruby requires following commands.
    * nmake
    * cl
    * ml
    * lib
    * dumpbin

4.  If you want to build from GIT source, following commands are required.
    * bison
    * patch
    * sed
    * ruby 2.0 or later

5.  Enable Command Extension of your command line.  It's the default behavior
    of +cmd.exe+.  If you want to enable it explicitly, run +cmd.exe+ with
    <tt>/E:ON</tt> option.

== How to compile and install

1.  Execute <tt>win32\configure.bat</tt> on your build directory.
    You can specify the target platform as an argument.
    For example, run `<tt>configure --target=i686-mswin32</tt>'
    You can also specify the install directory.
    For example, run `<tt>configure --prefix=<install_directory></tt>'
    Default of the install directory is <tt>/usr</tt> .
    The default _PLATFORM_ is `+i386-mswin32_+_MSRTVERSION_' on 32-bit
    platforms, or `+x64-mswin64_+_MSRTVERSION_' on x64 platforms.
    _MSRTVERSION_ is the 2- or 3-digits version of the Microsoft
    Runtime Library.

2.  Change _RUBY_INSTALL_NAME_ and _RUBY_SO_NAME_ in +Makefile+
    if you want to change the name of the executable files.
    And add _RUBYW_INSTALL_NAME_ to change the name of the
    executable without console window if also you want.

3.  Run `<tt>nmake up</tt>' if you are building from GIT source.

4.  Run `<tt>nmake</tt>'

5.  Run `<tt>nmake check</tt>'

6.  Run `<tt>nmake install</tt>'

== Icons

Any icon files(*.ico) in the build directory, directories specified with
_icondirs_ make variable and +win32+ directory under the ruby
source directory will be included in DLL or executable files, according
to their base names.
    $(RUBY_INSTALL_NAME).ico or ruby.ico   --> $(RUBY_INSTALL_NAME).exe
    $(RUBYW_INSTALL_NAME).ico or rubyw.ico --> $(RUBYW_INSTALL_NAME).exe
    the others                             --> $(RUBY_SO_NAME).dll

Although no icons are distributed with the ruby source, you can use
anything you like. You will be able to find many images by search engines.
For example, followings are made from {Ruby logo
kit}[https://cache.ruby-lang.org/pub/misc/logo/ruby-logo-kit.zip]:

* Small {favicon}[https://www.ruby-lang.org/favicon.ico] in the official
  site

* http://ruby.morphball.net/vit-ruby-ico_en.html or
  {icon itself}[http://ruby.morphball.net/icon/vit-ruby.ico]

== Build examples

* Build on the ruby source directory.

  ex.)
    ruby source directory:  C:\ruby
    build directory:        C:\ruby
    install directory:      C:\usr\local

    C:
    cd \ruby
    win32\configure --prefix=/usr/local
    nmake
    nmake check
    nmake install

* Build on the relative directory from the ruby source directory.

  ex.)
    ruby source directory:  C:\ruby
    build directory:        C:\ruby\mswin32
    install directory:      C:\usr\local

    C:
    cd \ruby
    mkdir mswin32
    cd mswin32
    ..\win32\configure --prefix=/usr/local
    nmake
    nmake check
    nmake install

* Build on the different drive.

  ex.)
    ruby source directory:  C:\src\ruby
    build directory:        D:\build\ruby
    install directory:      C:\usr\local

    D:
    cd D:\build\ruby
    C:\src\ruby\win32\configure --prefix=/usr/local
    nmake
    nmake check
    nmake install DESTDIR=C:

* Build x64 version (requires native x64 VC++ compiler)

  ex.)
    ruby source directory:  C:\ruby
    build directory:        C:\ruby
    install directory:      C:\usr\local

    C:
    cd \ruby
    win32\configure --prefix=/usr/local --target=x64-mswin64
    nmake
    nmake check
    nmake install

== Bugs

You can *NOT* use a path name that contains any white space characters as
the ruby source directory, this restriction comes from the behavior of
<code>!INCLUDE</code> directives of +NMAKE+.

You can build ruby in any directory including the source directory,
except +win32+ directory in the source directory.
This is restriction originating in the path search method of +NMAKE+.