Skip to content

Commit

Permalink
bugfix: Fix compilation on FreeBSD. (#3625)
Browse files Browse the repository at this point in the history
* Fix compilation on FreeBSD.
* Explicitly error out on unsupported platforms.
* Make the MAP_NORESERVE change specific for FreeBSD.
* Fix the sed expression to run on FreeBSD, too.
* Make the TestMain to run on all java versions on FreeBSD.
* Update the documentation for FreeBSD.
* Restore the ability to skip leading whitespaces in a more portable way.
* Add a note about failing tests.

(cherry picked from commit 963666d)
  • Loading branch information
alexdupre authored and WojciechMazur committed Jan 19, 2024
1 parent 3472648 commit 313e876
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 54 deletions.
17 changes: 13 additions & 4 deletions docs/user/setup.rst
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,24 @@ installation of Arch Linux.
$ sudo dnf groupinstall "Development Tools"
$ sudo dnf install gc-devel zlib-devel # both optional
**FreeBSD 12.2 and later**
**FreeBSD 12.4 and later**

*Note 1:* Only AMD64 and ARM64 architectures are supported.

*Note 2:* Sufficiently recent versions of llvm and zlib come with the
installation of FreeBSD.

.. code-block:: shell
$ pkg install llvm10
$ pkg install boehm-gc # optional
*Note:* A version of zlib that is sufficiently recent comes with the
installation of FreeBSD.
*Note 3:* Using the boehm GC with multi-threaded binaries doesn't work
out-of-the-box yet.

*Note 4:* A number of tests, primarily unit-tests, are known to fail
or not terminate on FreeBSD. It is believed that the code-under-test
is correct and that the defect is in the test itself.
Work is underway to fix these tests.

**Nix/NixOS**

Expand Down
2 changes: 1 addition & 1 deletion scripts/scalafmt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
set -e

HERE="`dirname $0`"
VERSION=$(sed -nre "s#\s*version[^0-9]+([0-9.]+)#\1#p" $HERE/../.scalafmt.conf)
VERSION=$(sed -nre "s#[[:space:]]*version[^0-9]+([0-9.]+)#\1#p" $HERE/../.scalafmt.conf)
COURSIER="$HERE/.coursier"
SCALAFMT="$HERE/.scalafmt-$VERSION"

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,56 +28,26 @@ object TestMain {
|""".stripMargin
}

final val iPv4Loopback = "127.0.0.1"
final val iPv6Loopback = "::1"

private def getFreeBSDLoopbackAddr(): String = {
private def setFreeBSDWorkaround(): Unit = {
/* Standard out-of-the-box FreeBSD differs from Linux & macOS in
* not allowing IPv4 mapped IPv6 addresses, such as :FFFF:127.0.0.1
* or ::ffff:7f00:1. These can be enabled by setting the line
* ipv6_ipv4mapping="YES" in /etc/rc.conf (and rebooting).
* not allowing IPv4-mapped IPv6 addresses, such as :FFFF:127.0.0.1
* or ::ffff:7f00:1.
*
* FreeBSD TestMain initial connections should succeed on both IPv4
* and IPv6 systems without requiring arcane and non-standard system
* configuration. This method checks the protocol that Java connect()
* is likely used and returns the corresponding loopback address.
* Tests which use IPv4 addresses, either through hard-coding or
* bind resolution, on IPv6 systems will still fail. This allows to
* run the vast majority of tests which do not have this characteristic.
* Another difference is that Java versions >= 11 on FreeBSD set
* java.net.preferIPv4Stack=true by default, so the sbt server
* listens only on a tcp4 socket.
*
* Networking is complex, especially on j-random systems: full of
* joy & lamentation.
* Even if IPv4-mapped IPv6 addresses can be enabled (via the
* net.inet6.ip6.v6only=0 sysctl and/or via the ipv6_ipv4mapping="YES"
* rc.conf variable) and sbt can be instructed to listen on an IPv6
* socket (via the java.net.preferIPv4Stack=false system property),
* the easiest way to make TestMain to work on most FreeBSD machines,
* with different Java versions, is to set
* java.net.preferIPv4Stack=true in Scala Native, before the first
* Java network call, in order to always use an AF_INET IPv4 socket.
*/

if (!LinktimeInfo.isFreeBSD) iPv4Loopback // should never happen
else {
// These are the effective imports
import scalanative.posix.sys.socket._
import scalanative.posix.netinet.in
import scalanative.posix.unistd

/* These are to get this code to compile on Windows.
* Including all of them is cargo cult programming. Someone
* more patient or more knowledgeable about Windows may
* be able to reduce the set.
*/
import scala.scalanative.windows._
import scala.scalanative.windows.WinSocketApi._
import scala.scalanative.windows.WinSocketApiExt._
import scala.scalanative.windows.WinSocketApiOps._
import scala.scalanative.windows.ErrorHandlingApi._

/* The keen observer will note that this scheme could be used
* for Linux and macOS. That change is not introduced at this time
* in order to preserve historical behavior.
*/
val sd = socket(AF_INET6, SOCK_STREAM, in.IPPROTO_TCP)
if (sd == -1) iPv4Loopback
else {
unistd.close(sd)
iPv6Loopback
}
}
System.setProperty("java.net.preferIPv4Stack", "true")
}

/** Main method of the test runner. */
Expand All @@ -87,11 +57,9 @@ object TestMain {
throw new IllegalArgumentException("One argument expected")
}

val serverAddr =
if (!LinktimeInfo.isFreeBSD) iPv4Loopback
else getFreeBSDLoopbackAddr()
if (LinktimeInfo.isFreeBSD) setFreeBSDWorkaround()
val serverPort = args(0).toInt
val clientSocket = new Socket(serverAddr, serverPort)
val clientSocket = new Socket("127.0.0.1", serverPort)
val nativeRPC = new NativeRPC(clientSocket)(ExecutionContext.global)
val bridge = new TestAdapterBridge(nativeRPC)

Expand Down

0 comments on commit 313e876

Please sign in to comment.