From Fedora Project Wiki

Revision as of 14:39, 10 September 2008 by Rjones (talk | contribs)

Packaging Guidelines for MinGW Windows cross-compiler

Please note this is a draft. "Rationale" sections are for discussion and will be deleted from the final document.

Naming

Packages should be named by prefixing the upstream package name with mingw-

Rationale Debian name their packages mingw32-*. However I can't see a reason for including '32' in the name, particularly since (a) the upstream package is just called mingw and (b) we may want to build 64 bit binaries.

Base packages

The base packages provide a root filesystem, base libraries, binutils (basic programs like 'strip', 'ld' etc), the compiler (gcc) and the Win32 API. Packages may need to depend on one or more of these. In particular, almost any conceivable package should depend on mingw-runtime.

mingw-filesystem Core filesystem directory layout, and RPM macros for spec files. Equivalent to 'filesystem' RPM
mingw-runtime Base libraries for core MinGW runtime & development environment. Equivalent to 'glibc' RPM
mingw-binutils Cross-compiled binutils (utilities like 'strip', 'as', 'ld') which understand Windows executables and DLLs. Equivalent to 'binutils' RPM
mingw-w32api Win32 API. A free (public domain) reimplementation of the header files required to link to the Win32 API. No direct equivalent in base Fedora - 'glibc' is closest
mingw-gcc GNU compiler collection. Compilers for C and C++ which cross-compile to a Windows target. Equivalent to 'gcc' RPM

Rationale I've used the same names as the upstream packages, and also the same names as Debian (minus the unnecessary '32' which Debian has in the name).

Filesystem layout

[root]
  |
  +- etc
  |   |
  |   +- rpm
  |       |
  |       +- macros.mingw
  |
  +- usr
      |
      +- bin   - Links to cross compiler toolchain
      |   |
      |   +- i686-pc-mingw-cpp
      |   +- i686-pc-mingw-gcc
      |   +- i686-pc-mingw-g++
      |   +- ... etc..
      |
      +- lib
      |   |
      |   +- rpm
      |       |
      |       +- mingw-defs   - custom helper scripts for auto-requires, binary stripping, etc
      |       +- mingw-find-provides.sh - extra DLL names
      |       +- mingw-find-requires.sh - discover required DLL names
      |
      +- i686-pc-mingw  - root of mingw toolchain and binaryes - see next diagram


[mingw-root]
  |
  +- bin  - Cross compiler toolchain  
  |   |
  |   +- cpp
  |   +- gcc
  |   +- g++
  |   +- ... etc ...
  |
  +- lib  - Cross compiler toolchain support libraries / files
  |
  +- sys-root  - root for cross compiled binaries
      |
      +- mingw
          |
          +- bin     - cross-compiled binaries & runtime DLL parts
          +- doc     - documentation
          +- include - include files for cross compiled libs
          +- lib     - cross-compiled static libraries & linktime DLL parts
          |   |
          |   +- pkgconfig  - pkg-config definitions for libraries
          |
          +- share
              |
              +- man

Standard mingw RPM macros

The mingw-filesystem package provides a number of convenience macros for the cross compiled sysroot directories, and toolchain. It is mandatory to use these macros in all mingw packages submitted to Fedora.

Toolchain macros

The following macros are for the %build and %install section of the spec

_mingw_ar i686-pc-mingw32-ar cross compiler 'ar' binary
_mingw_cc i686-pc-mingw32-gcc cross compiler 'gcc' binary
_mingw_cflags -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions --param=ssp-buffer-size=4 -I%{_mingw_includedir} Rationale: we need to remove the -m64 flag from standar RPM_OPTS_FLAGS
_mingw_configure CC="%{_mingw_cc}" CFLAGS="%{_mingw_cflags}" ./configure --build=%_build --host=%{_mingw_host} --target=%{_mingw_target} --prefix=%{_mingw_prefix} standard invocation for autotools 'configure' scripts
_mingw_cpp i686-pc-mingw32-gcc -E cross compiler 'cpp' binary
_mingw_host i686-pc-mingw32 Host platform for build
_mingw_objdump i686-pc-mingw32-objdump cross compiler 'objdump' binary
_mingw_ranlib i686-pc-mingw32-ranlib cross compiler 'ranlib' binary
_mingw_strip i686-pc-mingw32-strip cross compiler 'strip' binary
_mingw_target i686-pc-mingw32 Target platform for build

Filesystem location macros

The following macros are for use in %build, %install and %files sections of the RPM spec


_mingw_bindir %{_mingw_prefix}/bin
_mingw_datadir %{_mingw_prefix}/share
_mingw_docdir %{_mingw_prefix}/share/doc
_mingw_includedir %{_mingw_prefix}/include
_mingw_libdir %{_mingw_prefix}/lib
_mingw_libexecdir %{_mingw_prefix}/libexec
_mingw_mandir %{_mingw_prefix}/share/man
_mingw_prefix %{_mingw_sysroot}/mingw
_mingw_sbindir %{_mingw_prefix}/sbin
_mingw_sysconfdir %{_mingw_prefix}/etc
_mingw_sysroot %{_prefix}/i686-pc-mingw32/sys-root

Naming of the cross-compilers and binutils

The cross-compilers and binutils are Fedora binaries and are therefore placed in %{_bindir} (ie. /usr/bin) according to the FHS and Fedora guidelines.

The cross-compilers and binutils which generate i686 binaries for Windows are named:

%{_bindir}/i686-pc-mingw32-gcc
%{_bindir}/i686-pc-mingw32-g++
%{_bindir}/i686-pc-mingw32-ld
%{_bindir}/i686-pc-mingw32-as
%{_bindir}/i686-pc-mingw32-strip
etc.

The same binaries are present in %{_prefix}/i686-pc-mingw32/bin without any prefix in the name, ie:

%{_prefix}/i686-pc-mingw32/bin/gcc
%{_prefix}/i686-pc-mingw32/bin/g++
%{_prefix}/i686-pc-mingw32/bin/ld
%{_prefix}/i686-pc-mingw32/bin/as
%{_prefix}/i686-pc-mingw32/bin/strip
etc.

Note that we don't support generating x86-64 binaries (or any other architecture) at the moment, but if we do those will have a different prefix.

Rationale This is the name which autoconf configure scripts expect when they are invoked in cross-compiling mode. The /usr/i686-pc-mingw32/bin directory is required by GCC, otherwise it invokes the wrong assembler and linker.

Naming of the root filesystem

The root filesystem contains Windows executables and DLLs and any other Windows-only files. It is necessary both because we need to store Windows libraries in order to link further libraries which depend on them, and also because MinGW requires a root filesystem location. The location (for i686 target) is provided by the macro:

%{_mingw_sysroot}   %{_prefix}/i686-pc-mingw/sys-root

Rationale This is what the existing Fedora packages do, and very similar to what Debian is doing (they use a different and inconsistent name, but it is still a directory located directly under /usr), and is what MinGW expects.

Packaging DLLs

The Fedora MinGW SIG packages a range of common Linux libraries as Windows DLLs so that further libraries/programs can be compiled against them.

These libraries should be packaged in the directory provided by the macro:

%{_mingw_libdir}    %{_mingw_sysroot}/lib

Rationale Specified by MinGW. Putting them in %{_libdir} is not desirable because they are not intended for use on the host system. They are cross-compiled binaries only executable on the Windows platform, or under an environment like Wine.

Packaging EXEs

Any Windows binaries should be packaged in the directory given by the macro:

%{_mingw_bindir}    %{_mingw_sysroot}/bin

Rationale Specified by MinGW. Not applicable for /usr/bin as these are cross-compiled binaries only intended for execution under Windows, or an environment like Wine.

Packaging header files and other auxiliary files

Any auxiliary Windows files should be placed in the standard subdirectories of the root filesystem, for example:

%{_mingw_includedir} %{_mingw_sysroot}/include
%{_mingw_datadir}    %{_mingw_sysroot}/share
etc.

Dependencies

If a package contains binaries which depend on a DLL provided by another package, these dependencies should be expressed in the form:

mingw(foo.dll)

where foo.dll is the name of the DLL. The name must be converted to lowercase because Windows binaries contain case insensitive dependencies.

All packages should depend on mingw-filesystem.

Correct dependency generation is done automatically. Packagers should include this line in all library packages:

%include /usr/lib/rpm/mingw-defs

All specfiles should BuildRequire at least:

BuildRequires:  mingw-filesystem >= minimum-version

and any other BuildRequires at they need.

Build architecture

All packages should have:

BuildArch: noarch

unless they contain Fedora native executables.

Rationale Windows executables always target 32 bit x86 at present, and so (in theory) should be identical whatever Fedora architecture was used to build or host them.

DLLs

All libraries must be built as DLLs.

Because of the peculiarity of Windows, DLLs are stored in the %{_mingw_bindir} directory, along with a control file in the %{_mingw_libdir} directory. For example, for a library called foo there would be:

%{_mingw_bindir}/foo.dll
%{_mingw_bindir}/foo.def
%{_mingw_libdir}/foo.dll.a
%{_mingw_libdir}/foo.la

All files are required in those locations in order to link successfully.

The %files section must list DLLs separately. Packages must NOT use %{_mingw_bindir}/*

Rationale Libtool is very fragile and will give up on building a DLL very easily. Therefore we force the name of the DLL to be listed explicitly in the %files section in order to catch this during RPM builds.

Stripping

Libraries and executables should be stripped. This is carried out automatically if the mingw-defs file is included in the spec.