= Building NSS on Windows =

== Preamble ==

NSS stands for [http://www.mozilla.org/projects/security/pki/nss/ Network Security Services]. NSS is required to use SSL in Pidgin. NSS depends on NSPR and a [https://wiki.mozilla.org/NSS_Shared_DB shared database] (SQLite since [http://www.mozilla.org/projects/security/pki/nss/nss-3.12/nss-3.12-release-notes.html NSS 3.12]), but you don't have to worry about these, there's and NSS with NSPR package which is compact thus it contains all sources required to build NSS.

'''Note''': at the moment you can't build NSS completely using GCC. It fails at the final stage when linking additional tools. However, you can build all the important libraries successfully. It will hopefully be improved in the future. You can build NSS completely with [http://www.microsoft.com/downloads/details.aspx?FamilyId=F3FBB04E-92C2-4701-B4BA-92E26E408569&displaylang=en#filelist Microsoft Visual C++ 2008 Express Edition SP1]. This isn't covered in this tutorial but it's basically the same. However, if you build NSS with Visual C++, you must instruct your users to install the [http://www.microsoft.com/downloads/details.aspx?familyid=A5C84275-3B97-4AB7-A40D-3802B2AF5FC2&displaylang=en Microsoft Visual C++ 2008 SP1 Redistributable Package] or include it in the installer of your application (if permitted).  Note that you cannot use NSS with Pidgin if it is built with Visual C++, as the mingw GCC and Visual C++'s compiler link against different, incompatible C libraries.

== Prerequisites ==

 1. '''Get NSS:'''  Download [ftp://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/NSS_3_12_5_RTM/src/nss-3.12.5-with-nspr-4.8.2.tar.gz NSS with NSPR 3.12.5]. Extract it to `c:\devel\pidgin-devel\win32-dev`.
 1. '''Get MozillaBuild:'''  Download [http://ftp.mozilla.org/pub/mozilla.org/mozilla/libraries/win32/MozillaBuildSetup-1.4.exe MozillaBuild 1.4] and install it to `c:\devel\mozilla-build`.
 1. '''Get MinGW''':  This assumes that you have MinGW working as described in the [wiki:BuildingWinPidgin#Themanualway Pidgin Building Instructions] (in short, you need [https://sourceforge.net/projects/mingw/files/Automated%20MinGW%20Installer/ MinGW] installed with at least gcc).

== Choose build flavour ==

The 3 most important options are:
 * target OS
 * optimization
 * debug RTL

You can toggle them with environmental variables. Here's the matrix:
   {{{
#!comment
|| ||BUILD_OPT=0||BUILD_OPT=0||BUILD_OPT=1||BUILD_OPT=1||
|| ||USE_DEBUG_RTL=0||USE_DEBUG_RTL=1||USE_DEBUG_RTL=0||USE_DEBUG_RTL=1||
||OS_TARGET=WIN95||WIN954.0_DBG.OBJ||WIN954.0_DBG.OBJD||WIN954.0_OPT.OBJ||N/A||
||OS_TARGET=WINNT||WINNT6.1_DBG.OBJ||WINNT6.1_DBG.OBJD||WINNT6.1_OPT.OBJ||N/A||
   }}}
   {{{
#!rst

=================  =================  =================  =================  =================
        .                      BUILD_OPT=0                           BUILD_OPT=1
-----------------  ------------------------------------  ------------------------------------
        .          USE_DEBUG_RTL=0    USE_DEBUG_RTL=1    USE_DEBUG_RTL=0    USE_DEBUG_RTL=1
=================  =================  =================  =================  =================
OS_TARGET=WIN95    WIN954.0_DBG.OBJ   WIN954.0_DBG.OBJD  WIN954.0_OPT.OBJ   N/A
OS_TARGET=WINNT    WINNT6.1_DBG.OBJ   WINNT6.1_DBG.OBJD  WINNT6.1_OPT.OBJ   N/A
=================  =================  =================  =================  =================

   }}}

The version after WINNT is the version of your current OS (you can check it with the `winver` command). WINNT6.1 assumes you're building on Windows 7.

The default values are 0 for numerical variables and current OS for OS_TARGET. So on Windows 7 with no values set you'll end up building WINNT6.1_DBG.OBJ.

Pick the desired configuration (in other words, cell), and set the environmental variables with `set`. Example:
   {{{
set BUILD_OPT=1
set OS_TARGET=WIN95
   }}}

'''WARNING''': it seems the builder considers any variable as 1 if it's set. So if you enter
   {{{
set BUILD_OPT=0
   }}}
you'll get an optimized build although you wanted a debug one. The answer lies in `mozilla\security\coreconf\WIN32.mk`. They check variables with ifdefs, which is just plain wrong (or they should mention it this way in the documentation).

'''Solution''': set a variable only if you want the related build. Here's the table for seeing what you actually have to enter and what you'll get:
   || || ||USE_DEBUG_RTL=1||BUILD_OPT=1||
   ||OS_TARGET=WIN95||WIN954.0_DBG.OBJ||WIN954.0_DBG.OBJD||WIN954.0_OPT.OBJ||
   ||OS_TARGET=WINNT||WINNT6.1_DBG.OBJ||WINNT6.1_DBG.OBJD||WINNT6.1_OPT.OBJ||
OS_TARGET is an exception and isn't affected by this error because it's not numerical, so the script checks for its value instead of its existence. As a sidenote, BUILD_OPT seems to have a higher priority than USE_DEBUG_RTL, so if you enter
   {{{
set BUILD_OPT=1
set USE_DEBUG_RTL=1
   }}}
you'll get an optimized build without linking with the debug RTL. In case you want, for example, a debug build after an optimized, you can unset the variable by setting it without a value, such as:

   {{{
set BUILD_OPT=
   }}}

More info about the build variables can be found on the [https://developer.mozilla.org/en/NSS_reference/Building_and_installing_NSS/Build_instructions Build instructions] page of the Mozilla Developer Central.

== Patch NSS ==

There's an error which prevents NSS from building with GCC. Apply the following patch to `c:\devel\pidgin-devel\win32-dev\nss-3.12.5-with-nspr-4.8.2\mozilla\security\nss\lib\freebl\config.mk`:

{{{
#!diff
--- config.mk.orig	2009-04-12 00:18:42 +0200
+++ config.mk	2010-02-28 20:19:08 +0100
@@ -85,10 +85,14 @@
 RESNAME = freebl.rc

 ifndef WINCE
+ifndef NS_USE_GCC
 OS_LIBS += shell32.lib
 endif
+endif

 ifdef NS_USE_GCC
+OS_LIBS += -lshell32
+DEFINES += -D_WIN32_IE=0x0400
 EXTRA_SHARED_LIBS += \
        -L$(DIST)/lib \
        -L$(NSSUTIL_LIB_DIR) \
}}}

This error is already [https://bugzilla.mozilla.org/show_bug.cgi?id=549266 reported] and will hopefully be fixed in upstream soon.

== Build NSS ==

The easiest way to do this with consistent results is to make a build script (the following is what the binary included with Pidgin is built with):
{{{
#!sh
#!/bin/bash

#The path that we've extracted the nss source tarball into
NSS_SRC_DIR=/c/devel/pidgin-devel/win32-dev

#Set our Build Arguments:
#Optimized Build
export BUILD_OPT=1
#Target Windows NT Family
export OS_TARGET=WINNT
#Use GCC (as opposed to VC)
export NS_USE_GCC=1

#Set up the build path with MinGW and Moztools
PATH=/c/devel/pidgin-devel/win32-dev/mingw/bin
PATH=/c/devel/mozilla-build/moztools/bin:$PATH
PATH=/c/devel/mozilla-build/msys/bin:$PATH
export PATH

pushd $NSS_SRC_DIR/nss-3.12.5-with-nspr-4.8.2/mozilla/security/nss
make nss_build_all
popd

}}}

Save this script as `build.sh`. Launch a command prompt and run:

{{{
c:\devel\mozilla-build\msys\bin\sh build.sh
}}}

The build will likely not complete successfully (it will bail out building `.../cmd/bltest`).  If it gets that far, it has built the various libraries successfully.

The resulting binaries will be placed in `c:\devel\pidgin-devel\win32-dev\nss-3.12.5-with-nspr-4.8.2\mozilla\dist`. The contents of `private` and `public` are the same across all flavours so they can be distributed separately.

== Build x64 NSS ==

Currently it's not possible to build NSS x64 with GCC. You can make an x64 build of NSS only with Visual C++ yet. Since x64 tools aren't available in Visual C++ Express, you have to install the Windows SDK instead, which is a superset of Visual C++ Express in means of command line tools.

 1. Download [http://www.microsoft.com/downloads/details.aspx?FamilyID=c17ba869-9671-4330-a63e-1fd44e0e2505&displaylang=en Microsoft Windows SDK for Windows 7 and .NET Framework 3.5 SP1]. Install (at least) the following components:
  * Windows Headers and Libraries
  * Visual C++ Compilers
  * Win32 Development Tools
 1. Start `Microsoft Windows SDK v7.0/CMD Shell` from the Start Menu. Don't be bothered by the message about target, it won't affect this build. If it really annoys you, you can tweak it with `setenv` (query flags with `setenv /?`).
 1. Find a way to include `moztools\bin` and `msys\bin` in PATH.
 1. Set build flavour as before, and additionally add the following:
   {{{
set USE_64=1
   }}}
 1. Start compiling:
   {{{
make nss_build_all
   }}}
 1. Instruct your users to download and install the [http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=ba9257ca-337f-4b40-8c14-157cfdffee4e Microsoft Visual C++ 2008 SP1 x64 Redistributable Package] or include it in the installer of your application (if permitted).

Note that it's not possible to use a 64-bit version of NSS with Pidgin on Windows. Normally you wouldn't need to do this. This section is here only as reference for the future. Pidgin is a 32-bit application, thus cannot interact with 64-bit libraries.