0.4.1 (2021-10-20)

We’re happy to announce the release of Scala Native v0.4.1!


  • Backward compatible with previous 0.4.x releases,

  • Windows support

  • Immix and Commix GC supports WeakReferences

  • FileChannels improvements and support for MappedByteBuffers

  • Updated JUnit runtime

  • Faster builds in release modes

  • New mechanism - linktime resolved values and conditional branching

  • Improvements to Java stdlib implementation

  • Multiple bugfixes

Commits since last release 158
Merged PRs 158
Closed issues 113
Contributors 15

Most impacting changes

Windows support

This release of Scala Native brings native support for compilation and running Scala Native applications on Windows. For instructions how to setup your environment check out our documentation

Linktime resolved expressions

To make Windows support possible we introduced a new way of interacting with native code, especially with OS native functions that might not be existing on different platforms. Our solution to this problem is the introduction of linktime resolved expressions - special values using @scala.scalanative.unsafe.resolvedAtLinktime annotation. Each of such a value provides a stub in NIR (Native Intermediate Representation), which would be replaced when performing linking, based on values defined in scala.scalanative.build.NativeConfig. Currently, the list of linktime resolved expressions is limited and users cannot create new ones, but it might change in the future.

// Example of linktime resolved expressions definition
package scala.scalanative.meta
import scala.scalanative.unsafe._

object LinktimeInfo {
  def isWindows: Boolean = resolved

In case of usage of if condition containg linktime resolved value, at the time of performing linking of NIR files, whole condition expression would be replaced with constant boolean value equal to true or false. At this point we can dead-code eliminate never taken branch. This feature is crucial for cross compilation on different platforms - if we eliminate branch containing call to OS specific function it would be never used, and though we would not need its definition when building.

In the snippet below you can see an example of linktime conditional branching. Depending on Native Config settings only one of the if condition branch would be taken, the second one would be always discarded.

import scala.scalanative.meta.LinktimeInfo.isWindows
import scala.scalanative.unsafe._

def isDirectory(path: CString): Boolean = {
  if (isWindows) {
    GetFileAttributesA(path) & FILE_ATTRIBUTE_DIRECTORY != 0 
  } else {
    val buf = alloc[stat.stat]()
    stat.stat(path, buf)
    stat.S_ISDIR(buf._13) != 0

Weak References support

The next new feature is partial support for Weak References, however usage of this feature is only possible when using Immix or Commix GC - they have beed adopted to handle proper marking of WeakReference objects. Other Garbage Collector implementations, like external Boehm GC do not contain mechanisms allowing to perform WeakReference semantics. To check at runtime if your current GC supports weak references you can use the dedicated linktime resolved value LinktimeInfo.isWeakReferenceSupported


Big thanks to everybody who contributed to this release or reported an issue!

$ git shortlog -sn --no-merges v0.4.0..v0.4.1
    56	Wojciech Mazur
    40	LeeTibbert
    19	Jan Chyb
    18	Eric K Richardson
     6	Nacho Cordón
     4	Kirill A. Korinsky
     4	Sébastien Doeraene
     2	João Costa
     2	Lorenzo Gabriele
     2	Teodor Dimov
     1	Alex Dupre
     1	Bjorn Regnell
     1	Denys Shabalin
     1	Ergys Dona
     1	philwalk

Merged PRs

v0.4.1 (2021-10-20)

Full Changelog

Merged pull requests:

Scala compiler plugin

  • Fix: #2187 Match with guards does not compile #2188 (WojciechMazur)

  • Fix #2305 compile error on macro using Scala 2.11.12 #2336 (jchyb)

  • Fix: #2144, Lambda function generation should check if boxing is needed. #2147 (WojciechMazur)

Scala Native build

Sbt plugin

  • Fix sbt plugin incompatibilities on Windows #2189 (WojciechMazur)

  • Fix #2321: Fix Clang discovery on Windows #2334 (ekrich)

  • if Windows, append .exe to binaryName in discover(), to support mingw64 and cygwin compilers #2349 (philwalk)

  • Fix resolving binary version in ScalaNativeCrossVersion for snapshots #2207 (WojciechMazur)

  • Fix 2378; Allow to read from stdin when using run command #2384 (WojciechMazur)

  • Skip linking on subsequent nativeLink calls in SN sbt plugin #2389 (jchyb)

  • Fix #2146: Publish sbt-scala-native to Sonatype instead of Bintray. #2386 (sjrd)

  • Sbt nativeLink command should fail in case of clang failure #2394 (WojciechMazur)

Garbage Collector

Java Standard Library

  • Fix #1590: Correct j.i.DataInputStream EOF handling & skipBytes #2104 (LeeTibbert)

  • Fix #2137: Two defects in j.n.PlainSocketImpl#read #2140 (LeeTibbert)

  • Simplify match case in j.n.PlainSocketImpl #2149 (LeeTibbert)

  • Fix #2138: j.i.DataInputStream#rebuffer handles short reads correctly. #2142 (LeeTibbert)

  • Fix #2143: j.i.DataOutputStream now does bulk writes where possible. #2152 (LeeTibbert)

  • Fix #2164: Return -1 at first EOF at Base64.DecodingInputStream #2165 (catap)

  • Port DataInputStream readUTF code & all of DataInputStreamTest #2153 (LeeTibbert)

  • Fix #2163: Do not use regexp in j.u.Formatter #2169 (WojciechMazur)

  • Fix #2178: j.l.{Double,Float}#isFinite now handles NaN as specified. #2180 (LeeTibbert)

  • Correct j.i.DataInputStream static readUTF implementation. #2172 (LeeTibbert)

  • Reduce indirection for the implementation of getClass #2139 (densh)

  • Fix #2063: Modify j.u.Date#toString to be Java 8 compliant. #2110 (LeeTibbert)

  • Update j.u.Formatter to the latest version from Scala.js. #2196 (sjrd)

  • Implement j.nio.file.PosixException object #2198 (LeeTibbert)

  • Make it explicit that Unix FileAttributeView is provided by Posix calls. #2227 (LeeTibbert)

  • Update & supersede PR #1609: Implement java.nio UserPrincipal infrastructure. #2244 (LeeTibbert)

  • Homogenises numeric exception messages #2270 (ncordon)

  • Fix #I2283 - j.nio.file.Files.copy() now sets lastModified time correctly #2284 (LeeTibbert)

  • Use Unicode 13 for Character toUpperCase and toLowerCase #2103 (ekrich)

  • Fix #2313: Defect in j.n.InetAddress#createIPStringFromByteArray #2348 (jchyb)

  • A few improvements inside FS related API #2081 (catap)

  • Correct BufferedInputStream mark() and close() behaviour #2354 (WojciechMazur)

  • Implement java.io for Windows #2355 (WojciechMazur)

  • Implement java.nio on Windows #2358 (WojciechMazur)

  • Implement java.lang.ProcessBuilder for Windows #2360 (WojciechMazur)

  • Implement java.net for Windows #2364 (WojciechMazur)

  • Allow to use java.util.zip in Windows #2361 (WojciechMazur)

  • Port CVarArgList implementation for Windows #2376 (WojciechMazur)

  • Fix: #2135, segmentation-faults when working with file channels #2141 (WojciechMazur)

  • Add WeakReference functionality and finalization-like operation via WeakReferenceRegistry #2368 (jchyb)

  • Fix bug with File.getCanonicalFile leading to infinite recursion loop on Windows #2374 (WojciechMazur)

  • Remove memory leak when reading user locale country and language data on Windows #2383 (WojciechMazur)

  • Reimplement Thread.sleep to be OS-specific and multithreading safe #2373 (WojciechMazur)

  • Fix #2396: URI normalize doesn’t seem to work #2397 (jchyb)

  • Update RE2 regex implementation #2402 (jchyb)

  • Fix java.nio.file.Files inconsistencies between JVM and Native #2408 (jchyb)

  • Match regex implementation of re2j version 1.3 #2407 (jchyb)

  • Fix sn.regex parsing of OR expressions with a common prefix and \Q\E quoted expressions #2410 (jchyb)

  • Add missing FileChannel functionality in javalib #2393 (jchyb)

Native library

  • Fix 1664: Correct two memory access flaws in POSIX time #2160 (LeeTibbert)

  • Fix #1665: posixlib localtime() now ensures tzset() has been called. #2269 (LeeTibbert)

  • Support for POSIX signal #1362 (ekrich)

  • posix.time strptime improvements & TimeTest macOS correction #2203 (LeeTibbert)

  • Fix #1646: Implement posixlib sys/resource.scala #2193 (LeeTibbert)

  • Makes dirent.c more readable and returns -1 only on empty dir #2221 (ncordon)

  • Fix #2251: size of scalanative_sockaddr_in == struct sockaddr #2252 (LeeTibbert)

  • Fix #1921, #2250: Evolve hacktoberfest Posix socket sendto() & recvfrom() #2258 (LeeTibbert)

  • Improve POSIX pthread code quality #2307 (ekrich)

  • Implement shutdown using atexit instead of c++ #1906 (lolgab)


  • Make corresponding Scala Native version evident in documentation. #2116 (LeeTibbert)

  • Remove two instances of a hard-coded Scala Native version in documentation. #2121 (LeeTibbert)

  • Generate latest documentation copyright year #2115 (LeeTibbert)

  • Add missing commix reference in the documentation #2136 (JD557)

  • add docs on profiling including how to make flamegraphs #2226 (bjornregnell)

  • Fix #2267: Correct a broken link in docs/user/profiling.rst. #2268 (LeeTibbert)

  • Explain how to create universal binary on macOS #2405 (catap)