(Free) Software Building and Packaging For Windows
This is an old revision of the document!
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.
Packaging is usually an experience with many issues and dirty work-arounds. Some of these are quite common and easy to spot for someone who has already seen similar issues so don’t hesitate to hit one of the support channels and ask questions.
The questions will help build documentation. For issues that have already been solved elsewhere in the project the answers will be easy; the difficult part is in making the list of possible issues. Again, don’t hesitate to ask.
There is a fairly large number of Slackware build scripts which are split in two:
slackware
directory;slackbuilds.org
directory.If such a build script exist, read Section 4, “Port an existing build script”. Otherwise, read Section 5, “Or, start from a similar package”.
Even though this relies on build scripts for Slackware, this is in no way tied to Slackware: these build scripts have been chosen for their quality, simplicity and portability.
For slackbuilds.org
all the files are already there. For slackware64-current
, you need to copy them first. For example, libgcrypt
is inside slackware64-current/n
so you’d run a command similar to this one:
cd slackware64-current/n lftp -c 'connect http://mirrors.slackware.com/slackware/slackware64-current/source/n; mirror libgcrypt'
${PACKAGE}.yypkg.script
file to the package directory; if you have nothing specific to set for the packaging (by far the usual case), you only have to cp
another one; any will do except gcc’s; don’t forget to name it after the package however. For instance:cp ../../l/libjpeg.yypkg.script newpackage.yypkg.script
packager_email
and packager_name
in the ${PACKAGE}.yypkg.script
file.usr
with ${PREFIX}
(verbatim: don’t expand the variable). This means /usr/
becomes /${PREFIX}/
.if [ "$ARCH" = "i486" ]; then SLKCFLAGS="-O2 -march=i486 -mtune=i686" LIBDIRSUFFIX="" elif [ "$ARCH" = "i686" ]; then
$SLKCFLAGS
with -O2
* Add –host=${HOST_TRIPLET}
to the configure invocation. If this involves adding a newline in a configure call, don’t forget to escape it with \
right before it. find $PKG | xargs file | grep -e "executable" -e "shared object" | grep ELF \ | cut -f 1 -d : | xargs strip --strip-unneeded 2> /dev/null || true
Replace grep ELF
with grep ${HOST_EXE_FORMAT}
and xargs strip
with xargs ${HOST_STRIP}
.
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
cat ${CWD}/${PKGNAM}.yypkg.script | sed \ -e "s/%{PKG}/${PKGNAM}/" \ -e "s/%{HST}/${HOST_TRIPLET}/" \ -e "s/%{TGT}//" \ -e "s/%{VER}/${VERSION}/" \ -e "s/%{BUILD}/${BUILD}/" \ -e "s/%{DESCR}/${DESCR:-"No description"}/" \ | yypkg --makepkg -o ${YYOUTPUT} --script - --directory "${PKG}/${PREFIX}"
Some packages don’t set the PKGNAM
variable but instead hardcode the package name throughout the script; in that case, use the package name instead of ${PKGNAM}
.
chmod -R u+w,go+r-w,a-s .
Create a new directory for your package inside mingw/
and copy an existing build script that is similar:
slackware64-current/n/libgcrypt.SlackBuild
and slackware64-current/n/libgcrypt.yypkg.script
slackbuilds.org/libraries/openjpeg.SlackBuild
and slackbuilds.org/libraries/openjpeg.yypkg.script
CMake-based build systems are much less friendly for cross-compilation and especially to Windows compared to autotools ones and openjpeg.SlackBuild
has more kludges but they can’t be easily avoided for cmake-based systems.
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.
You will have to download the sources in the same directory as your build script.
Also note that the extension of the sources can matter: slackbuilds unfortunately tend to assume one such as in the following snippet (assumes .bz2
) and you’ll need to ensure the build script matches the tarball extension.
rm -rf $PKGNAM-$VERSION tar xvf $CWD/$PKGNAM-$VERSION.tar.bz2 || exit 1 cd $PKGNAM-$VERSION
Before building you need to let the builer know about your package. In the win-builds git
repository, edit build/windows.ml
“. You need to add an entry after all the package dependencies. The list is written in OCaml but you only need to understand the basic syntax.
For instance, libgcrypt
depends on libgpg-error
and needs to be added below it so that it can reference it.
(* The code below defines a new variable: libgcrypt * it is the result of a call to the "add" function with 6 arguments: * - ("libgcrypt", None): the package name is "libgcrypt" and there no * so-called "variant" for it * - ~dir: the directory containing the package; the full path will be * "slackware64-current/n/libgcrypt" * - ~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 which are not tracked in git (i.e. large * binaries); each entry is made of the filename followed by the SHA1 of the * file; the filename can contain ${PACKAGE} and ${VERSION} to not repeat * the values given as ~version and in the first argument to the "add" * function. *) let libgcrypt = add ("libgcrypt", None) ~dir:"slackware64-current/n" ~dependencies:[ libgpg_error ] ~version:"1.6.1" ~build:1 ~sources:[ "${PACKAGE}-${VERSION}.tar.bz2", "d9b63ac3b17a6972fc11150d136925b702f02"; ] in
Note the trailing in
: the OCaml construct is let … in
and the syntax requires that in
after each new variable creation.
You can now build your package like any other package, i.e. with a command similar to:
make -C win-builds WINDOWS=your_package
This will build your package for windows for both 32b and 64b. The logs will be stored inside @@VERSION@@/logs/windows_??/your_package
.
You will most likely have to build, check the logs and change your build script several times.
Remember you can build for only one architecture at once. This will save CPU time and allow iterating faster. The syntax is:
make -C win-builds WINDOWS_64=your_package
While developing you might want to have a shell. To do so, simply append :devshell
to your target:
make -C win-builds 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.