68 megabytes for Hello World (and how to reduce that a bit)

When I first started playing around with .NET Core, I was perplexed when the default output was a .dll that you needed to run with the dotnet command line too.

To cut a long story short you can make .NET Core build as an exe by creating a publish profile via the GUI or with the following contents.

I guess building as a .dll by default makes sense when your primary target is Azure.

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
  <PropertyGroup>
    <PublishProtocol>FileSystem</PublishProtocol>
    <Configuration>Release</Configuration>
    <Platform>Any CPU</Platform>
    <TargetFramework>netcoreapp2.1</TargetFramework>
    <PublishDir>bin\</PublishDir>
    <RuntimeIdentifier>win-x64</RuntimeIdentifier>
    <SelfContained>true</SelfContained>
    <_IsPortable>false</_IsPortable>
  </PropertyGroup>
</Project>

It looks like truly self-contained apps will never happen: https://github.com/dotnet/corefx/issues/13329#issuecomment-322494078

Package trimming, or 21.65MB for Hello World

PM> install-package Microsoft.Packaging.Tools.Trimming
install-package : Unable to find package 'Microsoft.Packaging.Tools.Trimming'
At line:1 char:1
+ install-package Microsoft.Packaging.Tools.Trimming
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Install-Package], Exception
    + FullyQualifiedErrorId : NuGetCmdletUnhandledException,NuGet.PackageManagement.PowerShellCmdlets.InstallPackageCommand
 
Time Elapsed: 00:00:01.6966641

 

but… but… that’s what the official documentation says to do!

Turns out Adam from the past also had this issue. Thanks, Adam from the past! No idea why this has been removed from the docs.

Time Elapsed: 00:00:01.6966641
PM> install-package -pre Microsoft.Packaging.Tools.Trimming
  CACHE https://api.nuget.org/v3/registration3-gz-semver2/microsoft.packaging.tools.trimming/index.json
Restoring packages for c:\git\HelloWorldSingleFile\HelloWorldSingleFile\HelloWorldSingleFile.csproj...
  GET https://api.nuget.org/v3-flatcontainer/microsoft.packaging.tools.trimming/index.json
  OK https://api.nuget.org/v3-flatcontainer/microsoft.packaging.tools.trimming/index.json 890ms
  GET https://api.nuget.org/v3-flatcontainer/microsoft.packaging.tools.trimming/1.1.0-preview1-26619-01/microsoft.packaging.tools.trimming.1.1.0-preview1-26619-01.nupkg
  OK https://api.nuget.org/v3-flatcontainer/microsoft.packaging.tools.trimming/1.1.0-preview1-26619-01/microsoft.packaging.tools.trimming.1.1.0-preview1-26619-01.nupkg 819ms
Installing Microsoft.Packaging.Tools.Trimming 1.1.0-preview1-26619-01.
Installing NuGet package Microsoft.Packaging.Tools.Trimming 1.1.0-preview1-26619-01.

Also change your project file

<PropertyGroup>
  <TrimUnusedDependencies>true</TrimUnusedDependencies>
</PropertyGroup>

The next time you publish, you’ll see the following output

2>Trimmed 197 out of 214 files for a saving of 44.64 MB
2>Final app size is 21.65 MB

I understand why System.Text.Encoding.Extensions is shipped, but I don’t understand why System.Threading and Tasks are needed for Hello World.

.NET Core AOT / CoreRT or: you didn’t really need Reflection, did you? (Hello World in under 8 megabytes)

All snark aside, CoreRT is really, really impressive. Have a read of https://github.com/dotnet/corert/blob/master/Documentation/intro-to-corert.md or for more detail, http://mattwarren.org/2018/06/07/CoreRT-.NET-Runtime-for-AOT/

You’ll need Visual Studio 2017 with MSVC enabled, plus CMake, it seems, then clone https://github.com/dotnet/corert and run build.cmd

Some time later, you’ll be able to follow the instructions at https://github.com/dotnet/corert/blob/master/Documentation/how-to-build-and-run-ilcompiler-in-console-shell-prompt.md

PS c:\git\HelloWorldSingleFile> $env:IlcPath="c:\git\corert\bin\Windows_NT.x64.Debug"
PS c:\git\HelloWorldSingleFile> dotnet publish -r win-x64
...
 Generating native code
 HelloWorldSingleFile -> c:\git\HelloWorldSingleFile\HelloWorldSingleFile\bin\Debug\netcoreapp2.1\win-x64\publish\

If you don’t see the “Generating native code” line, you may need to delete your bin\ and obj\ folders. No, dotnet clean didn’t help here.

If you’ve got this far, you should have a ~7.6 MB exe that is independent of the .NET framework. Success!

The code for this article is at https://github.com/voltagex/HelloWorldSingleFile

TeamViewer “Commercial Use Detected”

ruined.png

(This post assumes you know about / use TeamViewer in a non-commercial setting)

So this seems to be going really “well” for TeamViewer, but it’s not a large enough section of the online community to cause a big backlash.

well-done.png

There’s a fair few people affected on the TeamViewer forums

teamviewerd

..and after I filtered out the TeamViewer Dominatrixes (Dominatrixii?), there’s a fair few people affected on Twitter, too. I first became aware of this issue when someone I followed was locked out, then about a week later I was booted too.

None of the people on the forums or Twitter are going to get helped, either: TeamViewer Support insists you fill out the form at https://www.teamviewer.com/en/support/commercial-use-suspected/ where you have to beg to be let back into the program you’ve been using to help Dad find out what features the latest OS X update removed from Finder this time. On top of that there seems to be quite a backlog, so there’ll be a delay before you’re attended to.

In all seriousness, I’ve probably been using TeamViewer without incident for about 5 years. This has made me look elsewhere, but the alternatives all suck! (Sorry NoMachine).

No other app seems to be:
* Cross platform
* Easily installed / run by people of all skill levels
* Bearable to use at > 300 ms latency
* Able to punch through NAT and firewalls, even falling back to posting JPGs over HTTP if needed (!)
* Able to find PCs on dynamic IPs, no matter where or how they’re connected (see previous point)

Yes, there’s RDP, but TeamViewer is faster. Yes there’s NoMachine NX but TeamViewer is better on Android and faster on Windows. Yes there’s LogMeIn but… no, just no.

WTF are you doing  TeamViewer – I would have probably paid if you’d offered something under $200 AUD as a once off – it’s saved me stepping through problems blind over the phone so many times. Why on earth would you risk all the goodwill you have?

Also, this raises some pretty big concerns – what’s the client scanning to decide whether use is “commercial”? What analysis is done? Who has access to that data?

Absolutely, TeamViewer should be paid when the application is being used in a commercial setting. There’s also no question this is the wrong way to go about collecting dues.

 

Abandon ship: I’ve moved to AnyDesk, and I suggest you do too. It doesn’t seem to handle connection dropouts as well as TeamViewer did, but it’s up and running without even installing and seems to be just as smooth if not smoother.

 

 

Small wins: building cdirip-mod

Recently, someone contacted me on Reddit about a file I’d provided years ago. Someone had asked for a tool to convert CDI files to ISO. I don’t really remember doing this, but I must have been fed up by sketchy filehoster links so I went and found the source code, built a Windows binary and re-hosted it.

Of course, two or three years later, the link I provided was broken. They wanted to know if I still had the file. I didn’t, but I thought it couldn’t have been to hard to recreate.

Problem 1: Link rot

Apparently I’d grabbed the link to the source plus some info on how it was built from Arch Linux’s AUR, but when I went back to find the pkgbuild, it was gone. Some Googling found another copy of the PKGBUILD. Great! cdirip-0.6.3-mod-v1.zip it is, then.

Problem 2: Build tools

Without spoiling the end of this article too much, the original-ish Makefile can be found at Makefile.win, which shows you it was originally built with Dev-C++ and Mingw32. Given that VS2017 is now free for open source, I could avoid installing more build tools if I could get Visual Studio to build the code for me.

Problem 3: POSIX

Okay, okay, POSIX isn’t the problem here, VS2017 just doesn’t support it.

When I imported the solution and tried to build, I got one error:

cdirip.obj : error LNK2019: unresolved external symbol strcasecmp referenced in function main

I’m not a C or C++ coder and this is where I’d normally give up trying to build something on Windows and reach for a VM, mainly because every other time I’ve seen LNK2019 there’s been 10 or more errors referencing different symbols I’ve never heard of. In this case, cdirip doesn’t rely on any external libraries so I threw that name into Google. 10 or so minutes of looking through incorrect and outdated information later I stumbled across a very angry person on the MSDN forums

One quick define in common.h later the program built and ran correctly. Thanks, angry forum poster!

At this point I sent the file to the Redditor who asked me for it and was pretty much done. However, it didn’t really satisfy me – I’ve never had a C program build that easily in VS2017 and certainly not one that had been abandoned years before.

You can probably stop reading here, or continue on to find out how I spent far, far too much time on this.

If you’re actually looking for a copy of cdirip-mod for Windows, it’s at
https://bintray.com/voltagex/cdirip-mod/windows-x64/view/files

Bonus Problem 2: cdirip vs cdirip-mod

In the time before source control was worth billions of dollars, people passed around zip and rar files of dubious origin. cdirip was not one of those projects: it’s still at SourceForge

cdirip-mod seems to be a different story. It seems to have been passed around the Dreamcast emulation scene for a while – updated by someone under the pseudonym ‘fackue’. I went back and created a fork on GitHub of cdirip, then set about adding the -mod patches back in.

Bonus Problem 3: It’s 2018 and I still have to care about line endings

This isn’t very interesting but I ended up having to generate a .patch file from a Git repo, run format-patch and then run the resulting file through dos2unix to stop Git thinking I’d modified every file in the repo

Bonus Problem 4: DevOps Automated build and deployment

I’m a big fan of AppVeyor for building software on Windows, mainly because they maintain the VMs for me and I don’t have to worry about having the right build tools installed for whatever I’m working on.

For such a simple Visual Studio project, the configuration is pretty easy, defining Visual Studio 2017 plus the solution name will get you a green build.

I wanted to go a bit further than that so you’ll see some extra stuff around build artifacts. You could publish the artifacts to AppVeyor itself but they’ll be deleted in 6 months on a free account. This brings me to Bonus Problem 5.

Bonus Problem 5: distributing software on Windows sucks

(UWP/Drawbridge is one solution to this, NuGet and Chocolatey is another)

I’m not making any money off this little sidequest and I’ve already spent far too much time on it. If I were to throw the exe up on an S3 bucket it probably wouldn’t cost me much but I don’t like having my credit card attached to things unnecessarily.

Enter BinTray, who offer free hosting of binaries for open source projects. Sweet! I’ve now set up a project for cdirip-mod and added a windows-x64 package.

There are a couple of gotchas here:

  1. The API key I need to publish to BinTray is buried in the profile page, rather than on the same page where I create a project. It’s also account-wide rather than per-project which would make me a little nervous if I was working on big projects (compromise one key, compromise a whole lot of software)

  2. The AppVeyor documentation for BinTray is a bit wonky. It doesn’t seem like you can use organisation accounts, only user accounts and it says ‘AWS key’ where they probably mean API key. I’ve sent a quick-fix pull request to AppVeyor.

Trouble with ext4 filesystems and u-boot

If you’re having trouble using the ext4 support in u-boot to load or list files, your filesystem probably has a feature bit turned on that u-boot’s ext4 implementation doesn’t support. To fix this, run:

 

root@devbox:/home/voltagex# e2fsck -f /dev/sdb1
e2fsck 1.43.5 (04-Aug-2017)
Pass 1: Checking inodes, blocks, and sizes
Pass 2: Checking directory structure
Pass 3: Checking directory connectivity
Pass 4: Checking reference counts
Pass 5: Checking group summary information
/dev/sdb1: 34440/478608 files (0.5% non-contiguous), 253717/1913344 blocks
root@devbox:/home/voltagex# tune2fs -O ^64bit,^metadata_csum /dev/sdb1
tune2fs 1.43.5 (04-Aug-2017)
Disabling checksums could take some time.
Proceed anyway (or wait 5 seconds) ? (y,N) y
Please run `resize2fs -s /dev/sdb1' to disable 64-bit mode.
root@devbox:/home/voltagex# resize2fs -s /dev/sdb1
resize2fs 1.43.5 (04-Aug-2017)
Converting the filesystem to 32-bit.
The filesystem on /dev/sdb1 is now 1913344 (4k) blocks long.

Failing to build VirtualBox on Windows

In 2017, it’s still way too hard to build software on Windows. I wanted to see how difficult it’d be to make a few changes to VirtualBox, for which I’d have to rebuild it from source. The version of VirtualBox you download as a binary from virtualbox.org isn’t the same one you get if you try to build from source, and I think this is where the problems start.

The first challenge is getting the source. I gave up after an hour of waiting for the source to download from http://www.virtualbox.org/svn/vbox/trunk. As I was going to be working from Git repo, I used BitBucket’s Subversion import to create a repo at https://bitbucket.org/voltagex/virtualbox-mirror.

The first thing you’ll notice about the VirtualBox build system is that the configure script for Windows is in VBScript, which is an unusual choice but it technically means you could get up and running on most Windows installs without too much effort. Unfortunately, this is where the easy part ends. I very quickly worked out that I wanted to use AppVeyor, mainly because their VM images are very well configured. I did try building on my own Server 2016 VM, but I couldn’t get the right version of the Windows SDK / DDK installed, or at least not in the paths that the VirtualBox build system expected them.

This leads me to the next reason why building VirtualBox on Windows absolutely sucks. It requires both an old version of MinGW and the Visual Studio 2010 compiler. Visual Studio 2010 was released on 12 April 2010, while MinGW 4.9.3 was released sometime in 2015, I think. SourceForge’s file browser is very hard to navigate.

I suspect choosing a 64 bit toolchain was my first mistake here, but we’ll get to that later.

I created an appveyor branch to work from, mainly so I could easily diff changes that I made to configure.vbs. When I started working on this, each build took about 20 minutes on AppVeyor, depending on where the build broke. You can see all the builds at https://ci.appveyor.com/project/voltagex/virtualbox-mirror/history, along with my terrible commit messages. Future Adam – please write better commit / build messages so that writing these blog posts will be easier. If anyone has any suggestions for technical note-taking, I’m all ears – but I think OneNote will be hard to beat.

AppVeyor’s build history shows 63-odd builds. I know I did a few more on AWS and various virtual machines, but I gave those up quickly – I think most of the issues were around not being able to find WinDDK even though it was installed.

Apparently it took me 4 builds even to get a sensible error message out of the configure script

Checking for MinGW32 GCC v3.3.x + Binutils + Runtime + W32API...
warning: Can't locate a suitable MinGW32 installation, ignoring since we're targeting AMD64 and won't need it.
Checking for MinGW-w64 GCC (unprefixed)...
error: Can't locate a suitable MinGW-w64 installation. Try specify the path with the --with-MinGW-w64= argument. If still no luck, consult the configure.log and the build requirements.

The hint there is that the error complains about a suitable MinGW installation. At that point it’s actually found some of the required files, but buried in the configure.log is the real reason it’s failing

trying: strPathMinGWw64=C:\tools\mingw64
Testing 'C:\tools\mingw64': lib64/libgcc_s.a not found
trying: strPathMinGWw64=C:\tools\mingw64
Testing 'C:\tools\mingw64': lib64/libgcc_s.a not found

I can’t remember whether at this point I realised that the version of MinGW I had installed was too new, but it definitely wasn’t the only problem. Skipping ahead a few builds shows I was copying files into the lib64 directory with xcopy, betting that the build system was looking in an old or obsolete path.

I don’t know why the configure script hides most of the useful information in configure.log – for example MinGW-w64 version '5.3.0' is not supported (or configure.vbs failed to parse it correctly).

Anyway, after dropping the MinGW version back I was able to progress past this point. I still needed to copy files from lib to lib64.

For the next little while it was as simple as adding dependencies in and rebuilding. The builds only took 5 or so minutes to fail so it wasn’t too bad, although it was very frustrating to wait and then find out I’d messed up a 7z command line, like in https://ci.appveyor.com/project/voltagex/virtualbox-mirror/build/1.0.15.

Things get interesting when your software depends on OpenSSL on Windows. I’ve never actually built it from source myself and I’m afraid of the amount of whisky I’ll need when I eventually try. Security implications be damned, by 15 builds in I’d ‘cheated’ and downloaded some pre-built libraries from https://www.npcglib.org/~stathis/blog/precompiled-openssl/ and included them in the build. Unfortunately this involved renaming the dlls to the ‘old’ OpenSSL names – apparently sometime in 2016 the OpenSSL project changed the names, breaking decades  of assumptions.

curl is another story. libcurl – despite being one of the most commonly used libraries anywhere (it’s probably in your phone, your car and maybe even your lightbulb), there were no precompiled binaries for Windows that I could find.

A slight diversion to work out how to build curl, then I guess. This means (in theory) linking to OpenSSL again, too. Luckily someone else had done it for me and I could lean on https://github.com/blackrosezy/build-libcurl-windows. This has some pretty neat batch scripting in it and soon I had https://github.com/baxterworks-build/build-libcurl-appveyor for myself. I should have really learned how to use GitHub Releases or BinTray but I think at this point this silly project had consumed enough of my evening and I threw a zip up on my NeoCities site and carried on.

20 builds later, I’d passed the trials of configure.vbs, and in theory I was ready to build VirtualBox.

Execute env.bat once before you start to build VBox:
env.bat
kmk

This in itself proved a challenge because I couldn’t work out how to set the path to kmk so that AppVeyor’s build system would find it. I believe that AppVeyor is running everything in a single PowerShell instance by default and every command runs in a ‘child’ process so I couldn’t work out how to get the variables where they needed to be.

Sidenote: kmk is part of kBuild, which is not Kbuild, the Linux Kernel build system. Have a look at https://trac.netlabs.org/kbuild/wiki/kBuild and then just fucking use cmake like everyone else. Anyone building on Windows will thank you for it.

A couple (9) more failed builds later I’d hacked the batch files enough to start actually building VirtualBox! Is almost 3 days to set up a build system some kind of record? I’m sure even a new Microsoft employee could kick off a Windows build faster than this. Come on.

I didn’t expect it to work first time but I definitely didn’t expect this error:

build.bat
Config.kmk:2773: C:/projects/virtualbox-mirror/out/win.amd64/release/DynamicConfig.kmk: No such file or directory
Config.kmk:3503: *** You need to enable code signing for a hardened windows build to work.. Stop.
Command exited with code 2
I think on Linux there’s a `–disable-hardening` option for configure, but this didn’t exist for the Windows build – there’s another good reason to use a single build system for all builds. Looking at this commit you’d think it’s as easy as flipping a switch, but apparently not. I could not disable the code signing or hardening options no matter what I tried. The real solution, of course, is to disable the error message itself.
Onwards and… upwards? The next error to sort out was a missing python.exe, which turned out to be pretty boring – someone had coded it to only ever look in /bin/, which won’t help you much on Windows. With that fixed, it should be smooth sailing, right? Yeah, nah.
35 builds in, I got completely stuck. For some reason openssl.h wasn’t being found, even though it wasn’t a problem before. Luckily, AppVeyor let you RDP into a build machine during the build itself to inspect the state of the machine. This is pretty amazing – and I’m still on a free account!

By adding iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1')) into AppVeyor you’ll get an IP and credentials printed out in the build log. On a free account, I think the build logs are public so be careful with this.

From memory I was trying to use SysInternals Procmon (which every dev should learn to use) to work out where kBuild was expecting to find openssl.h. This turned out to be much too slow and created huge trace log files – 600mb+. I’m very glad I’m no longer on DSL based broadband. I think I tried a few different filters before giving up and looking for a way to run procmon non-interactively. Luckily that’s already been thought of, if you run
procmon /Quiet /Minimized /BackingFile virtualbox-build.pml you can start procmon automagically. I did have to ask for help for this one as it seemed to ‘block’ the build. AppVeyor support is awesome and came through with a fix, even opening a pull request on my repo (tl;dr start commands in PowerShell jobs and they won’t interrupt anything – similar to a bash subshell).

After fiddling with paths and learning about all the different hooks AppVeyor has (I needed to be able to retreive files from the build but the artifacts section normally isn’t run on a ‘failed’ build), I managed to get 628mb of 7zipped PML files off the build host. If you ever need to debug to this level, I highly recommend doing something like this. This was build number 44, clocking in at over 56 minutes, which is a bit of a problem as AppVeyor’s free plan has a 60 minute limit. Over the next little while I tried different paths for OpenSSL and talked to one of the VirtualBox developers on IRC.

This developer told me that internally (for the ‘commercial’ build of VirtualBox) they use a different build process which unfortunately couldn’t be shared due to licencing concerns. Sigh. At least a few of the things in the build system made a bit more sense (it looks like an internal checkout of the source contains most of the build tools).

It seems like the include path just got too long and the build system doesn’t see all of it, or something along those lines – the fix was to move openssl.h to virtualbox\include. After an evening and a half (?) I was off and moving again.

You should definitely include any references you’ve used in troubleshooting in code comments and commit messages. I don’t think I would have got much further without https://forums.virtualbox.org/viewtopic.php?f=10&t=61510, which described the exact issue I was having at this point and a solution – copying a file with a specific name. I’m not sure whether I caused more issues here by mixing 32 and 64 bit libraries, but the build continued.

By build number 60, with a commit message of ‘Sigh’, I’d definitely hit the 60 minute limit of the free AppVeyor plan. Suprisingly, AppVeyor staff increased my time limit to 90 minutes when I asked. Thanks, Ilya!

At this point I was tracking down the cause of [00:16:37] kmk_builtin_redirect: _spawnvpe(/bin/nm.exe) failed: No such file or directory, which I probably should have recognised from the Python failure earlier – but which nm.exe did it want? Visual Studio? MinGW? 32 or 64 bit? It took multiple gigs of ProcMon logs to work this out, and I’m still not sure I chose the right one.

It was at build 62 I find myself completely defeated – VirtualBox appears to build some SSL certificates into a binary for some unknown reason and whatever was generating byte arrays generated bad code.

[00:19:41] TrustAnchorsAndCerts.cpp
[00:19:42] C:\projects\virtualbox-mirror\out\win.amd64\release\obj\SUPR3\TrustAnchorsAndCerts.cpp(496) : error C2070: 'const unsigned char []': illegal sizeof operand
[00:19:42] C:\projects\virtualbox-mirror\out\win.amd64\release\obj\SUPR3\TrustAnchorsAndCerts.cpp(540) : error C2070: 'const unsigned char []': illegal sizeof operand
[00:19:42] kmk: *** [C:/projects/virtualbox-mirror/out/win.amd64/release/obj/SUPR3/gen/TrustAnchorsAndCerts.obj] Error 2 (0x2)

I don’t know enough about C++ to fix this, and I don’t know enough about VirtualBox to fix whatever’s generating this. Maybe another day, with another bottle of Monkey Shoulder.

I only wanted to play with a modified VirtualBox Web Service, why is it this hard?

Failing to build an nginx addon

For a project I’m working on I needed to be able to rewrite the content of a page as it’s sent back to me from a remote server (via proxy_pass in nginx).

I’ve been using Alpine Linux more as part of very small Docker containers, so I started looking into how nginx is built there. After stumbling around a bit, I found that Alpine uses a ports-like system called aports. I copied the nginx port into a new folder and began working on a Dockerfile.

abuild, the Alpine package build tool seems to be designed to build the whole tree, and the wiki talks about an abuild build command that apparently does everything except build the package. Sigh. I eventually cobbled enough together from mailing list posts and guesses to figure out that the command I wanted was abuild -r -fF -c -P /packages

This is where it all went a bit wrong. The module I needed was https://github.com/yaoweibin/ngx_http_substitutions_filter_module, which I added into the APKBUILD script and faked up a sha256sum. abuild doesn’t seem to check this at all, but won’t let the build continue if it’s not listed.
No matter what I did, I got the following failure:

mv: can't rename '/nginx/pkg/nginx/usr/lib/nginx/modules/ngx_http_subs_filter_module.so': No such file or directory
>>> ERROR: nginx-mod-http_subs_filter*: _module failed
>>> ERROR: nginx*: prepare_subpackages failed
>>> ERROR: nginx: all failed

Now, earlier in the build log I could see the module being built, so I couldn’t understand why this was going wrong.

After more stumbling around I found that this was an “old style” module – that couldn’t be built as a dynamic module like the rest of the ones in the script. I wonder why nginx’s build system doesn’t make more noise about this?

A quick patch from https://github.com/yaoweibin/ngx_http_substitutions_filter_module/pull/19 and I had it building as a dynamic module… except that it didn’t. There was still no .so file created, only an intermediate .o somewhere in the tree.

The really strange part of this is that if you try the same thing on a Debian or Ubuntu system, the module will build fine. At this point I’d wasted a lot of time trying to build on Alpine, so I switched my baseimage over to use debian:stretch-slim, installed nginx-full, which already has the module I need and continued with my project.

It’s not all bad though, I created a couple of good things while trying to get this to work. One is a debug version of abuild, which was as simple as changing #!/usr/bin/ash -e to #!/usr/bin/ash -xe. It’s up on docker as voltagex/alpine-builder-debug if you really need it.  This is helpful if you’re trying to build packages for Alpine and things aren’t working as you expect. Be warned though, this produces a lot of output.

Update: awilfox has a much better patch for abuild that is available at http://foxkit.us/linux/0002-abuild-Add-verbose-option-v-to-show-everything.patch – this adds the traditional -v option to turn on verbose output. It does the same thing as my hack, but is cleaner.

Building nginx from source, very quickly

Just a quick note more for myself than anyone else. I needed to test a particular module for nginx but I didn’t have the build pre-reqs set up properly.

I’m slowly getting used to using Docker where I’d normally spin up additional VMs, so these are the commands:

docker run -it debian:latest /bin/bash
# apt update && apt install -y git build-essential
# cd /usr/src && git clone --depth=1 https://github.com/nginx/nginx
# git clone --depth=1 https://github.com/yaoweibin/ngx_http_substitutions_filter_module
# This is the bit most of the tutorials miss! The configure script is not where you'd normally expect
# cd nginx
# ./auto/configure --without-http_rewrite_module --without-http_gzip_module --add-module=../ngx_http_substitutions_filter_module
# make -j

Note the –without lines make this build pretty useless – don’t use it for anything important!

Another oddity is that the output binaries are in ./obj