Skip to content

NimScript (config.nims) for building a static binary using Nim + musl + pcre + libressl/openssl

License

Notifications You must be signed in to change notification settings

kaushalmodi/hello_musl

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

95 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Nim + musl + pcre + libressl/openssl

https://travis-ci.org/kaushalmodi/hello_musl.svg?branch=master

This repo contains a generic ~config.nims~ that adds a Nim “sub-command” or task named musl. You can simply add that file to your Nim project, and run nim musl foo.nim with optional -d:pcre and/or -d:libressl / -d:openssl switches (assuming that the below prerequisites are met).

Prerequisites

  • OS: One of Linux x86 (32/64), ARM (32/64), MIPS (32/64), PowerPC (32/64), S390X, SuperH, Microblaze, OpenRISC (ref)
  • Nim: https://nim-lang.org/ (built from *devel* branch as of <2018-09-13 Thu>)
  • musl library: https://www.musl-libc.org/download.html
  • curl and GNU tar are needed on the system for the -d:pcre / -d:libressl / -d:openssl switches to work.

Optional

These optional command-line utilities for binary size optimization will be run automatically one by one, if present.

Generating static binary

For this example hello_musl project

  1. git clone https://github.com/kaushalmodi/hello_musl
  2. cd hello_musl
  3. Run nim musl [-d:pcre] [-d:libressl|-d:openssl] <FILE>.nim

Static links with just musl lib

nim musl src/hello_musl.nim

That will generate hello_musl binary in src/ directory.

  • file ./src/hello_musl will print:
    src/hello_musl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
        
  • ./src/hello_musl will print:
    Hello, World!
        

Static linking with musl + pcre libs

nim musl -d:pcre src/hello_musl_pcre.nim

That will generate hello_musl_pcre binary in src/ directory.

  • file ./src/hello_musl_pcre will print:
    src/hello_musl_pcre: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
        
  • ./src/hello_musl_pcre will print:
    Hello, World!
    Bye, World!
        

Static linking with musl + libressl libs

nim musl -d:libressl src/hello_musl_ssl.nim

That will generate hello_musl_ssl binary in src/ directory.

  • file ./src/hello_musl_ssl will print:
    src/hello_musl_ssl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
        
  • ./src/hello_musl_ssl will print:
    {"name":"Kaushal Modi","type":"card","url":"https://scripter.co/"}
    {
      "name": "Kaushal Modi",
      "type": "card",
      "url": "https://scripter.co/"
    }
    "Kaushal Modi"
        
Note
Binary built using -d:libressl on RHEL 6.8 is known to crash with just a “Killed” message. But the same, when built on Travis, run fine on RHEL 6.8 (mystery). So a RHEL 6.8 user may look at the slightly less secure option of building using with -d:openssl switch instead.

Static linking with musl + openssl libs

nim musl -d:openssl src/hello_musl_ssl.nim

That will generate hello_musl_ssl binary in src/ directory, and the outputs would be same as those you see for the -d:libressl switch.

Note about compiling with statically linked OpenSSL (-d:openssl)

When building with -d:openssl, a statically linked version of OpenSSL library is first built with the -DOPENSSL_NO_SECURE_MEMORY Configure option, because of an issue with it getting built using MUSL.

This security laxing switch is not added if LibreSSL is used instead (~-d:libressl~)

For your Nim project

  • Copy the ~config.nims~ to your Nim project.
  • While being the same directory as config.nims, do:
    nim musl <path/to/your/nim/file>             # without static pcre lib linking
    nim musl -d:pcre <path/to/your/nim/file>     # *with* static pcre lib linking
    nim musl -d:libressl <path/to/your/nim/file> # *with* static libressl lib linking
    nim musl -d:openssl <path/to/your/nim/file>  # *with* static openssl lib linking (less secure)
        

References

Todo-List

  • [ ] Figure out how to have nimble install install the binary generated by nim musl.
  • [X] Don’t hard-code the muslGcc const in config.nims
  • [X] Not require hello_musl.nimble
    • Currently that is needed just to add the -d:musl and -d:release switches, and then to auto-run strip -s.
    • So to remove dependency on this file, I need to figure out how to get the current foo.nim file name from within the config.nims.
    • Eventual goal is to reuse the same config.nims for all projects. So I cannot hardcode the pkgName as I do in hello_musl.nimble.