Subject: Windows compilation [Was: Re: BEEP: Tomas Nilsson]
From: Martin Stjernholm <mast@lysator.liu.se>
Date: Sat, 1 Oct 2011 AD 11:48:14 -0400
郭雪松 wrote:
> Some month ago, I tried to setup a cross compiling environment, to
> build pike for windows. But failed.
>
> Can anyone provide a real runable HOWTO?
Unfortunately the windows build method is a complete embarrassment. It's
too bad that it still works well enough so that noone has bothered
fixing a sensible replacement (one that really works, that is).
You need a unix and a windows box sharing a file system (one virted in
the other is the usual setup). On windows you need Visual Studio 2008.
2005 may also work - I don't know anymore.
Then you check out the nt-tools branch from git. On the windows box you
install pike and make a bat script that runs the compilation server.
Mine looks like this:
set BUILD_ROOT=l:/mast-home/Pike/NT-build/vc9
set PIKE_BUILD_ARCH=%1
if "%PIKE_BUILD_ARCH%" == "" set PIKE_BUILD_ARCH=i386
if %PIKE_BUILD_ARCH% == i386 (
set MSVC_ARCH=x86
set SPRSHD_PORT=4711
)
if %PIKE_BUILD_ARCH% == x86_64 (
set MSVC_ARCH=amd64
set SPRSHD_PORT=4712
)
if %PIKE_BUILD_ARCH% == ia64 (
set MSVC_ARCH=ia64
set SPRSHD_PORT=4713
)
if "%MSVC_ARCH%" == "" (
echo Unknown PIKE_BUILD_ARCH "%PIKE_BUILD_ARCH%"
goto exit
)
set PIKE_BUILD_ROOT=%BUILD_ROOT%/%PIKE_BUILD_ARCH%
set CRT_MSM_PATH=c:/Program Files (x86)/Common Files/Merge Modules
set GNUWIN_ROOT=c:/gnuwin32
call "%GNUWIN_ROOT%/bin/set_gnuwin32.bat" -s gnuwin32 -l EN
set PKG_CONFIG_PATH=%GNUWIN_ROOT%/lib/pkgconfig
set INCLUDE=%GNUWIN_ROOT%/include;%GNUWIN_ROOT%/include/freetype2
set LIB=%GNUWIN_ROOT%/lib
set JAVA_ROOT=c:/Program Files (x86)/Java/jdk1.6.0_24
set INCLUDE=%JAVA_ROOT%/include;%JAVA_ROOT%/include/win32;%INCLUDE%
set LIB=%JAVA_ROOT%/lib;%LIB%
set PATH=%JAVA_ROOT%/jre/bin/server;%PATH%
call "c:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/vcvarsall.bat" %MSVC_ARCH%
rem Some packages come from both GnuWin32 and the GTK bundle. If there's
rem no other reason, we prefer the GTK versions since we'll have to include
rem them anyway.
set GTK_ROOT=%PIKE_BUILD_ROOT%/gtk+2.12.11
set PATH=%GTK_ROOT%/bin;%PATH%
set PKG_CONFIG_PATH=%GTK_ROOT%/lib/pkgconfig;%PKG_CONFIG_PATH%
set INCLUDE=%GTK_ROOT%/include;%INCLUDE%
set LIB=%GTK_ROOT%/lib;%LIB%
set KFW_ROOT=%PIKE_BUILD_ROOT%/kfw-3-2-2-final
set INCLUDE=%KFW_ROOT%/inc/krb5;%INCLUDE%
set LIB=%KFW_ROOT%/lib/i386;%LIB%
set PGSQL_ROOT=%PIKE_BUILD_ROOT%/pgsql
set INCLUDE=%PGSQL_ROOT%/include;%INCLUDE%
set LIB=%PGSQL_ROOT%/lib;%LIB%
set INCLUDE=%PIKE_BUILD_ROOT%/include;%INCLUDE%
set LIB=%PIKE_BUILD_ROOT%/lib;%LIB%
set PATH=%PIKE_BUILD_ROOT%/bin;%PATH%;C:/Program Files (x86)/Pike/bin;C:/Program Files (x86)/Windows Installer XML v2;C:\Program Files\Debugging Tools for Windows (x64);C:\Program Files (x86)\CMake 2.6\bin;C:/MinGW
echo PIKE_BUILD_ARCH=%PIKE_BUILD_ARCH%
echo PIKE_BUILD_ROOT=%PIKE_BUILD_ROOT%
echo CRT_MSM_PATH=%CRT_MSM_PATH%
echo .
echo INCLUDE=%INCLUDE%
echo .
echo LIB=%LIB%
echo .
echo PATH=%PATH%
echo .
echo PKG_CONFIG_PATH=%PKG_CONFIG_PATH%
echo .
echo SPRSHD_PORT=%SPRSHD_PORT%
echo .
:loop
"c:\Program Files (x86)\Pike\bin\pike" %BUILD_ROOT%\..\nt-tools\tools\sprshd %SPRSHD_PORT% 192.168.200.2 127.0.0.1 10.0.2.2
goto loop
The sprshd script at the end is the compilation server which you'll find
in the nt-tools branch. It listens to %SPRSHD_PORT% and allows
connections from the following ip's.
On the unix box you run nt-tools/init_nt to start up the
cross-compilation environment. It uses a file ~/.init_ntrc to set up the
path mappings. Here are the relevant parts of mine:
#!/bin/sh
#DEBUG=yes
test -z "$NTHOST" && NTHOST=127.0.0.1
CC=rntcl
unset MAKE_PARALLEL
NTMOUNT1=/home/mast
NTDRIVE1=l:/mast-home
NTMOUNT2=/export
NTDRIVE2=l:
NTMOUNT3=/net/lister.roxen.com/export
NTDRIVE3=l:
export NTHOST
The NTMOUNT/NTDRIVE stuff are the mappings between windows and unix
paths. After you run init_nt, you should be able to use configure and
make as usual in the pike tree, but all compilation takes place on
windows.
That's the easy part, really. The more time consuming bit (at least if
one is accustomed to the convenient linux package repositories) is to
set up all libraries and tools on windows so you get a working build
environment.
In particular it's important to keep track on how you link to crt's.
Preferably pike and all libs should use the same crt, but if you
download prebuilt libs you probably can't get that.
If everything works, then "make wix" is the top level command that'll
give you a complete installer msi.
Below are some notes I collected when I battled with it the last time.
It was about two years ago, so it's a little bit dated. Notably I only
got a 32 bit toolchain - we really ought to fix a full 64 bit
compilation environment.
Directories:
install The original install or source packages for the
libraries that are installed right now.
install/tools Packages for various build tools.
{vc8,vc9,...}
The first level of subdirectories reflects the build
environment, or more specifically which libc/CRT
things have been linked to since that often prohibit
mixing libs.
vc8 is Visual Studio 2005, vc9 is Visual Studio 2008.
Other future possibilities could include MinGW.
{vc8,vc9,...}/{i386,x86_64}
Second level is the Windows target architecture. Also
known as x86 and x64, respectively.
{vc8,vc9,...}/lib-build
Build trees for locally built libs. There are often
symlinks to built stuff in here, so be careful with
rm.
{vc8,vc9,...}/{i386,x86_64}/include
Part of the INCLUDE path.
{vc8,vc9,...}/{i386,x86_64}/lib
Part of the LIB path.
{vc8,vc9,...}/{i386,x86_64}/bin
Part of PATH. Should also contain any dlls that
libraries require, so that pike can run directly in
the build tree.
{vc8,vc9,...}/{i386,x86_64}/dll
This directory contains placeholders for the dlls that
need to be included in the install package.
install.pike searches for these in PATH. The contents
of the files here are not important; they can be zero
length. The MS CRT dlls shouldn't be here, though (see
CRT_MSM_PATH below instead).
{vc8,vc9,...}/{i386,x86_64}/install-tree
This directory contains other files that needs to be
added to the installation. The paths below this
directory will be mirrored below the pike installation
directory.
{vc8,vc9,...}/{i386,x86_64}/gtk+2*
Some bundles are kept in their own trees to avoid a
mess.
nt-tools From the Pike git.
Misc notes:
o Visual Studio, Microsoft SDK, WiX, Java JDK, and the full GnuWin32
suite are assumed to be installed locally.
o Lib packages are as far as possible installed as-is with either the
i386/x86_64 libs (if they contain only one architecture) or vc8/vc9
dirs (if they contain several architectures) as install root. Then
symlinks are used as necessary to make libs, dlls and include files
appear in the right places.
o Libs compiled for MinGW tend to not mix with "real" native libs such
as those produced by the GnuWin32 project (even though they ought
to).
o Note that it's easy to get several different runtime libs in
different parts, e.g. most prebuilt libs are linked statically to a
CRT while pike is linked dynamically to the dll CRT. Malloc'ed
blocks and fd's can't be mixed between the CRTs, so e.g. a block
allocated by malloc() in a lib can't be freed by free() in the pike
module.
The pike core and all modules use the same CRT. Everything else
must assume that the CRTs might be different.
o For VC8 and VC9, libs should be built for the dynamic nondebug CRT
as far as possible.
o VC8 and later has new complicated dependency tracking stuff which
affects the dll CRTs. This is only supported in the wix installer
which includes the msm files for the CRT in the package.
o The environment variable CRT_MSM_PATH points to the directory
containing the merge modules for the Microsoft CRTs to be bundled
in the wix installer. bin/install.pike needs it when it's used with
--release-crt or --debug-crt.
o cccl is heavily modified. It is symlinked from the bin dirs.
o Notes about compiling in MinGW:
o Using --out-implib to MinGW's ld.exe (at least version 2.17.50
20060824) produces an import library that doesn't work with VC9.
The Microsoft linker compains with "warning LNK4078: multiple
'.text' sections found with different attributes" and the app
crashes immediately when any function in the dll is called.
A workaround for this is to instead use --output-def to ld.exe
to create a .def file and then create the import library with
Microsoft's lib.exe:
lib /def:my_library.def
o Gmp (VC8):
o Changed to dynamic CRT.
o Define HAVE_STRNLEN in config-vc8.p0.
o Gmp (VC9):
o Using the dll version which in turn uses the dynamic CRT.
o Nettle:
o LICENSE PROBLEM: The two cryptos Blowfish and Serpent are
released under GPL, while the rest of Nettle is LGPL or more
free. The two problematic cryptos have been removed.
o Compiled in MSYS as follows:
CC=cccl CFLAGS="-MD -O2" ./configure --prefix=$PIKE_BUILD_ROOT
o libnettle.a has to be copied to nettle.lib for some post-targets
to work.
o There's some newline confusion in testsuite/sexp-conv-test that
causes it to fail if it isn't patched.
o PCRE:
o Compiled in MSYS as follows:
./configure --disable-cpp --enable-utf8 \
--enable-unicode-properties --prefix=$PIKE_BUILD_ROOT
o Using the dll version since the static one got CRT problems.
o Had to make the import lib (pcre.lib) manually due to the
--out-implib problem described above. Started from the "make
pcre.dll" target (which cuts out much of the libtool
gooblegook).
o MySQL 3.23.53:
o Changed to dynamic CRT.
o Define HAVE_STRNLEN in include/config-win.h
o MySQL 5.0.51: Using the Windows binary dist, dll variant.
o SQLite:
o The header comes from the "sqlite-amalgamation" package.
o The dll comes from the "sqlitedll" binary package for Windows.
o There's no import library in the binary package, so one was
create locally using:
lib /def:sqlite3.def
o GTK2:
o Pike must be configured --without-GTK to allow GTK2 to be
configured correctly, since the config cache names overlap
between GTK and GTK2.
o Java:
o A JRE (including jvm.dll) shouldn't get bundled by install.pike.
It's up to the user to install a JRE separately.
o GSS-API:
o DLLs are intentionally not bundled since the user is required to
install and configure Kerberos support separately anyway.
o See http://support.microsoft.com/kb/131313 for instructions on how
to create an import library directly from a dll.
o VC9 doesn't always install the 32-bit cl.exe. To get it installed,
choose to install VC# as well as VC++.
https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=295538
o Don't enable Just-in-time debugging in MSVS; the debug popup can
cause programs to hang in the build process. To disable, delete
these registry keys:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\DbgManagedDebugger
And on 64-bit systems also these:
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows NT\CurrentVersion\AeDebug\Debugger
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NETFramework\DbgManagedDebugger
See:
http://msdn.microsoft.com/en-us/library/k8kf6y2a.aspx
http://msdn.microsoft.com/en-us/library/5hs4b7a6.aspx
Note: It's possible that the method below will also disable the JIT
debugger popups.
o In Vista there's a popup anyway. To disable: Find the registry path
HKEY_CURRENT_USER\Software\Microsoft\Windows\Windows Error Reporting
and set/create the "Disabled" and "DontShowUI" DWORD keys with value 1.
See http://msdn.microsoft.com/en-us/library/bb513638.aspx.
o To enable UNC paths in cmd.exe: Under the registry path
HKEY_CURRENT_USER\Software\Microsoft\Command Processor
add the DisableUNCCheck REG_DWORD and set the value to 0x1 (Hex).
See http://support.microsoft.com/kb/156276
cmd.exe still behaves kinda funky when the current dir is a UNC
path though, but that's mainly a problem in interactive use. A
workaround is to use pushd/popd: http://support.microsoft.com/kb/317379
o Windows Vista often and for unknown reasons thinks that the network
changes and pops up the "Set Network Location" wizard when it
boots. To disable that, create this key:
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Network\NewNetworkWindowOff
The value doesn't matter. See
http://msdn.microsoft.com/en-us/library/cc733147.aspx.
o Autologon to a user that autostart sprshd might be convenient. To
enable that, go to:
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon
Create these keys:
AutoAdminLogon: string, value "1"
DefaultUserName: string
DefaultPassword: string
DefaultDomainName: string (if required)
o WinDbg is the debugger to use in the field:
http://www.microsoft.com/whdc/devtools/debugging/default.mspx
To get it to download the symbols for the windows libs, go to
File/Symbol File Paths..., enter:
SRV*c:\websymbols*http://msdl.microsoft.com/download/symbols
and check "reload".
Links:
o GnuWin32: http://gnuwin32.sourceforge.net/
o MinGW: http://www.mingw.org/
o MinGW32 packages repository: http://mingwrep.sourceforge.net/
o GTK for Windows: http://www.mpir.org/
o GMP port to VC: http://fp.gladman.plus.com/computing/gmp4win.htm
o YASM: http://www.tortall.net/projects/yasm/wiki
o Interesting article about the MS CRT installation mess:
http://www.codeproject.com/cpp/vcredists_x86.asp
o Script for running cl.exe like a cc: http://cccl.sourceforge.net/
o Simple tool for generating import libraries from dlls (untested):
http://www.geocities.com/SiliconValley/5806/implib32.htm
o Complex tool for generating import libraries from dlls (untested):
http://implib.sourceforge.net/
Return to results