(Free) Software Building and Packaging For Windows
If you haven’t already, build the packages that already exist. This will ensure you have everything needed and working; you can check the corresponding documentation.
There is a large number of existing Slackware build scripts which are split in two sets:
slackware
holds the packages scripts of the Slackware Linux distribution;slackbuilds.org
holds the scripts from the slackbuilds.org community repository.If you find an existing build script in either of these directory, you can re-use it directly.
Create a new directory for your package inside slackbuilds.org/win-builds
and copy an existing build script for that build system:
slackware/n/libgcrypt.SlackBuild
and slackware/n/libgcrypt/wb.ml
slackbuilds.org/libraries/openjpeg.SlackBuild
and slackbuilds.org/libraries/openjpeg/wb.ml
CMake-based build systems are much less friendly for cross-compilation and especially to cross-compilation to Windows and require a few kludges that can be difficult to avoid.
You will probably have to add package-specific bits. This is why having references in the form of native linux build scripts can help a lot.
(* The code below defines a new builder variable: libgcrypt. * It is the result of a call to the "add" function with 6 arguments: * - (name, variant): package name and variant which are defined automatically * according to the path of the 'wb.ml' file being used * - ~dir: the directory containing the package; also defined automatically * - ~dependencies: the list of dependencies, separated by ';' and enclosed * between '[' and ']'. * - ~version: the package version as a string * - ~build: the package build number, as an integer * - ~sources: the list of sources; * - each Tarball entry is made of the filename followed by the file's SHA1 * - each Patch entry only contains the filename * - Git entries are also possible (explained elsewhere) * The strings can contain ${PACKAGE} and ${VERSION} to not repeat values. *) let libgcrypt = add (name, variant) ~dir ~dependencies:[ libgpg_error ] (* set this *) ~version:"1.6.3" (* set this *) ~build:1 (* increment that after each new (public) build *) ~sources:[ (* set the extension and sha1sum for the current tarball *) Tarball ("${PACKAGE}-${VERSION}.tar.bz2", "9456e7b64db9df8360a1407a38c8c958da80bbf1"); ] in
Note the trailing in
: the OCaml construct is let … in
and the syntax requires that in
after each new variable creation in this context.
usr
with ${PREFIX}
(verbatim: don’t expand the variable) in the .SlackBuild file. This means /usr/
becomes /${PREFIX}/
.ARCH
, NUMJOBS
, SLKCFLAGS
and LIBDIRSUFFIX
; they look similar to# Automatically determine the architecture we're building on: if [ -z "$ARCH" ]; then ... NUMJOBS=${NUMJOBS:-" -j7 "} ... if [ "$ARCH" = "i486" ]; then SLKCFLAGS="-O2 -march=i486 -mtune=i686" LIBDIRSUFFIX="" ...
tar xvf $CWD/$PKGNAM-$VERSION.tar.bz2 || exit 1 # becomes yyextract "${CWD}" "${PKGNAM}-${VERSION}"
$(yyflags 'c')
, $(yyflags 'cxx')
, $(yyflags 'ld')
; look for $SLKCFLAGS
to locate places which need changes–host=${HOST_TRIPLET}
to the configure invocation. If this involves adding a newline in a configure call, don’t forget to escape that newline with \
. strip
invocation; it looks like:find $PKG | xargs file | grep -e "executable" -e "shared object" | grep ELF \ | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
mkdir -p $PKG/install cat $CWD/slack-desc > $PKG/install/slack-desc cd $PKG /sbin/makepkg -l y -c n $OUTPUT/$PRGNAM-$VERSION-$ARCH-$BUILD$TAG.${PKGTYPE:-tgz}
with
yymakepkg_split \ --pkg "${PKG}" \ --cwd "${CWD}" \ --version "${VERSION}" --build "${BUILD}" \ --packager "Adrien Nader" --packager-mail "adrien@notk.org" \ --host "${HOST_TRIPLET}" \ "${PKGNAM}" # ${PRGNAM} in some slackbuilds.org scripts instead; sometimes also no variable already exists
chmod -R u+w,go+r-w,a-s .
The source tarball needs to be in the same directory as your build script.
You can now build your package like any other package, i.e. with a command similar to:
make WINDOWS=your_package WINDOWS_EXTRAS=relative/path/to/your_package/wb.ml
The WINDOWS_EXTRAS
variable tells the system to read this wb.ml
file in addition to the ones it already knows about. You can have several files listed there, separated with ','. For other series, simply replace WINDOWS
with either NATIVE_TOOLCHAIN
or CROSS_TOOLCHAIN
.
This will build your package for windows for both 32b and 64b. The logs will be stored inside @@VERSION@@/logs/windows_??/your_package
.
Remember you can build for only one architecture . This will save CPU time and let you iterate faster. The syntax is:
make WINDOWS_64=your_package WINDOWS_EXTRAS=relative/path/to/your/wb.ml # note the additional "_64".
While developing you might want to have a shell. To do so, simply append :devshell
to your target:
make WINDOWS_64=your_package:devshell
It will give you a shell configured just like the shell used to run the SlackBuild except that it will try to use your own shell and not necessarily bash. You can then play the build script by hand to see what is going wrong.
Specifying the WINDOWS_EXTRA
variable each time is useful for testing but not for publishing. For that, the wb.ml
should be added to the list in win-builds/build/windows.ml
. Simply add a line similar to:
#use "slackware/n/libgcrypt/wb.ml"
Order matters and this line has to be below the ones for the dependencies listed in this wb.ml
file.
If you run make
from the win-builds
directory, the system will not build any package but will still run the builder after having checked the values that have been defined. It is a quick way to check the package descriptions are valid.