Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/kaushalmodi/hello_musl

NimScript (config.nims) for building a static binary using Nim + musl + pcre + libressl/openssl
https://github.com/kaushalmodi/hello_musl

binary libressl musl nim nimscript openssl pcre ssl static

Last synced: 10 days ago
JSON representation

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

Awesome Lists containing this project

README

        

#+title: Nim + musl + pcre + libressl/openssl
#+author: Kaushal Modi

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

This repo contains a generic [[https://github.com/kaushalmodi/hello_musl/blob/master/config.nims][~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 ([[https://www.musl-libc.org/intro.html][ref]])
- Nim: [[https://nim-lang.org/]] (built from [[https://github.com/nim-lang/Nim/tree/devel][*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.
- ~strip~ (from ~binutils~): [[https://sourceware.org/binutils/docs/binutils/strip.html]]
- ~upx~: [[https://github.com/upx/upx]]
* 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] .nim~
** Static links with just ~musl~ lib
#+begin_example
nim musl src/hello_musl.nim
#+end_example

That will generate ~hello_musl~ binary in ~src/~ directory.
- ~file ./src/hello_musl~ will print:
#+begin_example
src/hello_musl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
#+end_example
- ~./src/hello_musl~ will print:
#+begin_example
Hello, World!
#+end_example
** Static linking with ~musl~ + ~pcre~ libs
#+begin_example
nim musl -d:pcre src/hello_musl_pcre.nim
#+end_example

That will generate ~hello_musl_pcre~ binary in ~src/~ directory.
- ~file ./src/hello_musl_pcre~ will print:
#+begin_example
src/hello_musl_pcre: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
#+end_example
- ~./src/hello_musl_pcre~ will print:
#+begin_example
Hello, World!
Bye, World!
#+end_example
** Static linking with ~musl~ + ~libressl~ libs
#+begin_example
nim musl -d:libressl src/hello_musl_ssl.nim
#+end_example

That will generate ~hello_musl_ssl~ binary in ~src/~ directory.
- ~file ./src/hello_musl_ssl~ will print:
#+begin_example
src/hello_musl_ssl: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), statically linked, stripped
#+end_example
- ~./src/hello_musl_ssl~ will print:
#+begin_example
{"name":"Kaushal Modi","type":"card","url":"https://scripter.co/"}
{
"name": "Kaushal Modi",
"type": "card",
"url": "https://scripter.co/"
}
"Kaushal Modi"
#+end_example

- 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
#+begin_example
nim musl -d:openssl src/hello_musl_ssl.nim
#+end_example

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 [[https://github.com/openssl/openssl/issues/7207#issuecomment-420814524][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 [[https://github.com/kaushalmodi/hello_musl/blob/master/config.nims][~config.nims~]] to your Nim project.
- While being the same directory as ~config.nims~, do:
#+begin_example
nim musl # without static pcre lib linking
nim musl -d:pcre # *with* static pcre lib linking
nim musl -d:libressl # *with* static libressl lib linking
nim musl -d:openssl # *with* static openssl lib linking (less secure)
#+end_example
* References
- [[https://github.com/nim-lang/Nim/wiki/Using-nimscript-for-configuration]]
- [[https://nim-lang.org/docs/nims.html]]
- [[https://nim-lang.org/docs/nimscript.html]]
- [[https://hookrace.net/blog/nim-binary-size/#using-the-c-standard-library]]
- [[https://www.reddit.com/r/programming/comments/2wk7q6/static_linking_with_nim/corwtl7/]]
* TODO 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~.