\documentclass[english]{beamer}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage{babel}
\usepackage{hyperref}
\usepackage{relsize}
\usepackage{listings}
\usepackage{fancyvrb}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% User specified LaTeX commands.
\definecolor{debianred}{rgb}{.780,.000,.211} % 199,0,54
\definecolor{debianblue}{rgb}{0,.208,.780} % 0,53,199
\definecolor{debianlightbackgroundblue}{rgb}{.941,.941,.957} % 240,240,244
\definecolor{debianbackgroundblue}{rgb}{.776,.784,.878} % 198,200,224

\usecolortheme[named=debianbackgroundblue]{structure}
%\setbeamercolor{normal text}{fg=debianred}
\setbeamercolor{titlelike}{fg=debianblue}
\setbeamercolor{sidebar}{fg=debianred,bg=debianbackgroundblue}

\setbeamercolor{palette sidebar primary}{fg=debianred}
\setbeamercolor{palette sidebar secondary}{fg=debianred}
\setbeamercolor{palette sidebar tertiary}{fg=debianred}
\setbeamercolor{palette sidebar quaternary}{fg=debianred}

\setbeamercolor{section in toc}{fg=debianred}
\setbeamercolor{subsection in toc}{parent=debianred}

\setbeamercolor{item}{fg=debianred}

\setbeamercolor{block title}{fg=debianblue}

\usetheme{Boadilla}

\AtBeginSection[]
{
  \begin{frame}<beamer>
    \frametitle{Outline}
    \tableofcontents[currentsection]
  \end{frame}
}

\title{Cross-porting to Windows with Debian}
\author{Stephen Kitt \href{mailto:skitt@debian.org}{\texttt{<skitt@debian.org>}}}
\date[Paris Mini-DebConf 2014]{February 19, 2014}

\logo{\includegraphics[viewport=274 335 360 440,width=1cm]{openlogo-nd.pdf}} 

\begin{document}

\begin{frame}
  \titlepage
\end{frame}

\begin{frame}
  \begin{center}
    {\Huge ``Kill me now''}

--- a reaction at DebConf 13
  \end{center}
\end{frame}

\section{What?}

\begin{frame}{What?}
\begin{center}
Using Debian
\pause
to build software for Windows
\pause
involves cross-building
\pause
and porting
\end{center}
\end{frame}

\section{Use cases}

\begin{frame}{Use case 1: Debian}
  Debian itself includes a number of packages targeting Windows:
  \begin{itemize}
  \item \texttt{win32-loader} helps users install Debian from Windows
    \begin{itemize}
    \item \texttt{cpio-win32}
    \item \texttt{gpgv-win32}
    \item \texttt{gzip-win32}
    \end{itemize}
  \item \texttt{autorun4linuxcd} starts Debian Live from Windows
  \item \texttt{libreoffice} includes a Windows DLL for its SDK
  \item \texttt{netbeans} includes a Windows platform launcher
  \end{itemize}
There are more candidates (Python for one).
\end{frame}

\begin{frame}{Use case 2: Wine}
  Wine, the Windows ABI implementation, needs two packages built for
  Windows:
  \begin{itemize}
  \item \texttt{wine-gecko}, xulrunner for Windows used to provide IE
    functionality
  \item \texttt{wine-mono}, Mono for Windows used to provide .Net
  \end{itemize}
\end{frame}

\begin{frame}{Use case 3: our users}
  Various projects use (or support using) Debian to build Windows versions:
  \begin{itemize}
  \item Ekiga
  \item Gpg4win
  \item VLC
  \item QEMU
  \item \ldots
  \end{itemize}
\end{frame}

\section{How to}

\begin{frame}[fragile]{Building Windows software}
Install \texttt{mingw-w64}, and cross-compile.

``Host'' is \texttt{i686-w64-mingw32} for 32-bit Windows,
  \texttt{x86\_64-w64-mingw32} for 64-bit.

\begin{itemize}
\item Manually:
\begin{Verbatim}[formatcom=\color{debianred}]
${HOST}-gcc -g -O2 myprogram.c -o myprogram.exe
${HOST}-strip myprogram.exe
\end{Verbatim}
\item With autoconf:
\begin{Verbatim}[formatcom=\color{debianred}]
./configure --host=${HOST}
\end{Verbatim}
\item With cmake: use a toolchain file; see
  \url{http://www.cmake.org/Wiki/CMake_Cross_Compiling}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Building Windows software for Debian}
The usual approach is to build an architecture-independent package
containing the generated Windows files.

\begin{enumerate}
\item Build-depend (indep) on \texttt{mingw-w64} or the specific
  compiler you need
\begin{itemize}
\item \texttt{g++-mingw-w64} will provide 32- and 64-bit C++ compilers
\item \texttt{g++-mingw-w64-i686} will provide a 32-bit C++ compiler
\item \texttt{g++-mingw-w64-x86-64} will provide a 64-bit C++ compiler
\end{itemize}
\pause
\item In the \texttt{build-indep} target, configure and build with the
  appropriate options (\textbf{not} \texttt{-Wl,-z,relro})
\begin{Verbatim}[formatcom=\color{debianred}]
dh_auto_configure -Bbuild/windows -- --host=${HOST}
dh_auto_build -Bbuild/windows
\end{Verbatim}
\pause
\item Install as appropriate; current convention is to ship
  executables in \texttt{/usr/share/win32} or
  \texttt{/usr/share/win64}, DLLs and link libraries in
  \texttt{/usr/\$\{HOST\}/lib}.
\end{enumerate}
\end{frame}

\section{Current situation}

\begin{frame}{Current situation}{Compilers}
  ``Traditional'' cross-compilers with two toolchains:
  \begin{itemize}
  \item MinGW32, tuple \texttt{i586-mingw32msvc}
    \begin{itemize}
    \item \texttt{mingw32} package
    \item GCC 4.2.1 (C, C++)
    \end{itemize}
  \item MinGW-w64, tuples \texttt{i686-w64-mingw32} and
    \texttt{x86\_64-w64-mingw32}
    \begin{itemize}
    \item \texttt{mingw-w64} package
    \item GCC 4.8.2 (C, C++, Fortran, Objective-C, Objective-C++)
    \item GNAT 4.8.2
    \item GDB 7.6
    \item OCaml 4
    \end{itemize}
    (mainly using various \texttt{\ldots{}-source} packages)
  \end{itemize}
\end{frame}

\begin{frame}{Current situation}{Libraries}
  \begin{itemize}
  \item \texttt{mingw-w64-dev}, the Windows runtime headers and link
    libraries
    \begin{itemize}
    \item includes Pthreads
    \end{itemize}
  \item Libraries provided by gcc
  \end{itemize}
  \pause
\begin{center}
  ... and that's it!
\end{center}
\end{frame}

\begin{frame}[fragile]{There's the rub}
Building anything involving libraries is painful:

\begin{block}{Building Ekiga}
\begin{Verbatim}[fontsize=\relsize{-4}]
--- Getting libregex...
mkdir -p /tmp/user/1000/ekiga/src/regex
cd /tmp/user/1000/ekiga/src/regex; \
	for i in regex.c regexec.c regex.h regex_internal.c regex_internal.h regcomp.c alloca_.h alloca.c \
                 localcharset.c localcharset.h; do \
	  wget -nv -T 60 -N http://git.savannah.gnu.org/cgit/gnulib.git/plain/lib/$i?id=203e34 -O $i; \
	done
[...]
--- Getting libboost ...
wget -nv -T 60 -N -P src http://downloads.sourceforge.net/project/boost/boost/1.52.0/boost_1_52_0.tar.gz
[...]
--- Getting EXPAT ...
wget -nv -T 60 -N -P src https://downloads.sourceforge.net/project/expat/expat/2.1.0/expat-2.1.0.tar.gz
[...]
--- Getting OpenLDAP ...
wget -nv -T 60 -N -P /tmp/user/1000/ekiga/src \
  http://www.openldap.org/software/download/OpenLDAP/openldap-release/openldap-2.4.31.tgz
[...]
\end{Verbatim}
\end{block}
\end{frame}

\section{The Fedora/OpenSUSE/Arch Linux approach}

\begin{frame}{Let's fix this!}{The Fedora/OpenSUSE/Arch Linux
    approach}
Repackage anything useful in MinGW-w64-specific packages
\pause
\begin{itemize}
\item Fedora has 170 specific packages
\item OpenSUSE has 277 specific packages
\end{itemize}
\pause

Specific means all-new source packages, with no direct link to the
``main'' source package.
\pause

Great for users though!
\end{frame}

\section{The Debian approach}

\begin{frame}[fragile]{Let's fix this!}{The Debian approach}
Source-package build-dependencies
\pause
\begin{block}{mingw-w64-zlib debian/control}
\begin{Verbatim}
Source: mingw-w64-zlib
Section: libs
[...]
Build-Depends: zlib [source]

Package: zlib1g-mingw-w64
Architecture: all
\end{Verbatim}
\end{block}
\end{frame}

\begin{frame}
\begin{center}
{\Huge No thanks!}
\pause

(Although source build-dependencies would be nice anyway\ldots{})
\end{center}
\end{frame}

\begin{frame}{Let's fix this!}{The Debian approach}
Two new partial architectures
\begin{itemize}
\item \texttt{mingw64-amd64}
\item \texttt{mingw64-i386}
\end{itemize}
(see \#606825 for details).
\pause

\texttt{dpkg-buildpackage} and \texttt{sbuild} handle the
cross-building, and \texttt{dpkg-buildflags} handles the
architecture-specific flags.
\end{frame}

\begin{frame}[fragile]{New architectures}{\texttt{ostable} and
    \texttt{triplettable}}
\begin{block}{\texttt{ostable}}
\begin{Verbatim}[fontsize=\relsize{-2}]
 uclibceabi-uclinux     uclinux-uclibceabi      uclinux[^-]*-uclibceabi
 uclibc-uclinux         uclinux-uclibc          uclinux[^-]*(-uclibc.*)?
 tos-mint               mint                    mint[^-]*
+mingw64-windows        w64-mingw32             w64-mingw32[^-]*
\end{Verbatim}
\end{block}
\begin{block}{\texttt{triplettable}}
\begin{Verbatim}[fontsize=\relsize{-2}]
 uclibceabi-uclinux-arm uclinux-armel
 uclibc-uclinux-<cpu>   uclinux-<cpu>
 tos-mint-m68k          mint-m68k
+mingw64-windows-<cpu>  mingw64-<cpu>
\end{Verbatim}
\end{block}
\end{frame}

\begin{frame}[fragile]{New architectures}{\texttt{dpkg-architecture}}
\begin{block}{\texttt{scripts/Dpkg/Vendor/Debian.pm}}
\begin{Verbatim}[fontsize=\relsize{-4}]
@@ -122,15 +122,17 @@ sub add_hardening_flags {
        #  (#574716).
        $use_feature{pie} = 0;
     }
-    if ($cpu =~ /^(ia64|alpha|mips|mipsel|hppa|arm64)$/ or $arch eq 'arm') {
+    if ($cpu =~ /^(ia64|alpha|mips|mipsel|hppa|arm64)$/ or $arch eq 'arm' or $os eq 'windows') {
        # Stack protector disabled on ia64, alpha, arm64, mips, mipsel, hppa.
        #   "warning: -fstack-protector not supported for this target"
        # Stack protector disabled on arm (ok on armel).
        #   compiler supports it incorrectly (leads to SEGV)
+       # Stack protector disabled on Windows (requires glibc).
        $use_feature{stackprotector} = 0;
     }
-    if ($cpu =~ /^(ia64|hppa|avr32)$/) {
+    if ($cpu =~ /^(ia64|hppa|avr32)$/ or $os eq 'windows') {
        # relro not implemented on ia64, hppa, avr32.
+       # relro not implemented on Windows.
        $use_feature{relro} = 0;
     }
 
\end{Verbatim}
\end{block}
\end{frame}

\begin{frame}{New architectures}{Advantages}
This gives us
\begin{itemize}
\item Real binary packages for real binaries
\pause
\item Cross-architecture dependencies
\pause
\item No more Windows-specific sub-packages
\pause
\item Cross-building support:
\begin{itemize}
\item \texttt{binutils-source} and \texttt{gcc-...-source} targets
\item \texttt{cross-build-essential}
\end{itemize}
\pause
\item and \ldots{}
\end{itemize}
\end{frame}

\begin{frame}{New architectures}
\begin{center}
{\Huge Multi-Arch}
\end{center}
\end{frame}

\begin{frame}{Multi-Arch}{A blessing and a curse}
\begin{itemize}
\item A way of installing and running binaries for multiple
  architectures on a single system
\pause
\item The ``native'' architecture is just a special case
\pause
\item Many libraries are co-installable
\pause
\begin{itemize}
\item Development packages not so much (yet!)
\end{itemize}
\pause
\item It's Debian-and-derivative-specific
\pause
\begin{itemize}
\item The toolchains and autoconf support it
\pause
\item cmake and others aren't quite there yet
\pause
\item Are upstreams interested in patches?
\pause
\item It involves hacks in various packages
\end{itemize}
\end{itemize}
\end{frame}

\begin{frame}[fragile]{Multi-Arch}{Hacking around Python}
\begin{block}{\texttt{pyconfig.h}}
\begin{Verbatim}[fontsize=\relsize{-2}]
#if defined(__linux__)
# if defined(__x86_64__) && defined(__LP64__)
#  include <x86_64-linux-gnu/python2.7/pyconfig.h>
# elif defined(__x86_64__) && defined(__ILP32__)
#  include <x86_64-linux-gnux32/python2.7/pyconfig.h>
# elif defined(__i386__)
#  include <i386-linux-gnu/python2.7/pyconfig.h>
# elif defined(__aarch64__) && defined(__AARCH64EL__)
#  include <aarch64-linux-gnu/python2.7/pyconfig.h>
# elif defined(__alpha__)
#  include <alpha-linux-gnu/python2.7/pyconfig.h>
# elif defined(__ARM_EABI__) && defined(__ARM_PCS_VFP)
#  include <arm-linux-gnueabihf/python2.7/pyconfig.h>
# elif defined(__ARM_EABI__) && !defined(__ARM_PCS_VFP)
#  include <arm-linux-gnueabi/python2.7/pyconfig.h>
[...]
\end{Verbatim}
\end{block}
\end{frame}

\begin{frame}{Other annoyances}
\begin{itemize}
\item Usual cross-building issues
\pause
\item Windows is not POSIX
\begin{itemize}
\item How do we define the contents of \texttt{/usr/include}?
\end{itemize}
\pause
\item Windows-specific build systems in some packages (\emph{e.g.}
  \texttt{zlib})
\pause
\item Binaries and libraries need special handling:
\begin{itemize}
\item executables end in \texttt{.exe}
\item runtime libraries end in \texttt{.dll}
\item there are no development libraries for dynamic linking
\item by default some end up in the wrong place
\end{itemize}
Where should this be handled? \texttt{debhelper}?
\pause
\item Some binary packages don't make sense (\texttt{udeb}s)
\pause
\begin{itemize}
\item Build profiles to the rescue!
\end{itemize}
\end{itemize}
\end{frame}

\begin{frame}{Next steps}
\begin{enumerate}
\item Get MinGW-w64 in upstream \texttt{config.guess} and
  \texttt{config.sub}
\pause
\item Add the new architectures to \texttt{dpkg}
\pause
\item Provide ported packages somewhere
\begin{itemize}
\item (but remember the Windows packages in Debian)
\end{itemize}
\pause
\item Figure out what to do about \texttt{/usr/include}
\pause
\item Get patches merged
\pause
\item Support partial architectures (also useful for \texttt{x32}
  \ldots{})
\pause
\item Improve cross-architecture binary dependency support
\pause
\item Finish build profile support
\pause
\item Add support for cross-architecture build-dependencies?
\end{enumerate}
\end{frame}

\begin{frame}{That's all folks!}
  \begin{center}
    {\Huge Thanks!}
    \vfill
    \url{https://wiki.debian.org/Mingw-W64}
    
    \url{http://mingw-w64.sf.net}
  \end{center}
  \vfill
  \vfill
  \vfill
      {\tiny
        Slides available at \url{http://www.sk2.org/talks/}
        
        \copyright{}~2014 Stephen Kitt ---
        \href{http://creativecommons.org/licenses/by-sa/4.0/}{CC BY-SA 4.0
          --- Creative Commons Attribution-ShareAlike 4.0 International}}
\end{frame}

\end{document}
