Skip to content

An Idea how to add x86_64-unknown-linux-musl build target #45

Closed
@LouneCode

Description

@LouneCode

Add x86_64-unknown-linux-musl build target


Will be done as follows. At first clone this repository.

git clone https://github.com/chirpstack/chirpstack-mqtt-forwarder.git

Copy the following lines to the add_cross-compile-target_x86_64.patch file (should be in the UTF-8 format).

diff --git a/.cargo/config.toml b/.cargo/config.toml
index ff7c12a..565ff2f 100644
--- a/.cargo/config.toml
+++ b/.cargo/config.toml
@@ -1,3 +1,13 @@
+[target.x86_64-unknown-linux-musl]
+  rustflags = [
+    "-C", "target-feature=+crt-static",
+    "-C", "link-arg=-s",
+    "-C", "link-arg=-lc",
+    "-C", "link-arg=-lgcc",
+    "-L", "native=/usr/local/x86_64-linux-musl-target/lib",
+    "-l", "static=stdc++",
+  ]
+
 [target.aarch64-unknown-linux-musl]
   rustflags = [
     "-C", "target-feature=+crt-static",
diff --git a/Cargo.lock b/Cargo.lock
index e65efaa..e78b2d0 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -954,6 +954,15 @@ version = "1.18.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d"
 
+[[package]]
+name = "openssl-src"
+version = "300.1.5+3.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "559068e4c12950d7dcaa1857a61725c0d38d4fc03ff8e070ab31a75d6e316491"
+dependencies = [
+ "cc",
+]
+
 [[package]]
 name = "openssl-sys"
 version = "0.9.93"
@@ -962,6 +971,7 @@ checksum = "db4d56a4c0478783083cfafcc42493dd4a981d41669da64b4572a2a089b51b1d"
 dependencies = [
  "cc",
  "libc",
+ "openssl-src",
  "pkg-config",
  "vcpkg",
 ]
diff --git a/Cargo.toml b/Cargo.toml
index 5eaf3f5..404aee0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -35,7 +35,8 @@ hex = "0.4"
 base64 = "0.21"
 rand = "0.8"
 pbjson-types = "0.5"
-paho-mqtt = { version = "0.12", features = ["ssl", "build_bindgen"] }
+# See features section: "paho-mqtt:build_bindgen" or "paho-mqtt:vendored-ssl"
+paho-mqtt = { version = "0.12", features = ["ssl"] } 
 handlebars = "4.4"
 tokio = { version = "1.32", features = [
     "macros",
@@ -54,9 +55,11 @@ zmq = { version = "0.10", optional = true }
 dotenv = "0.15"
 
 [features]
-default = ["semtech_udp", "concentratord"]
+default = ["semtech_udp", "concentratord", "paho-mqtt/build_bindgen"]
 semtech_udp = []
 concentratord = ["zmq"]
+paho_mqtt_vendored_ssl = ["paho-mqtt/vendored-ssl"]
+paho_mqtt_bindgen_ssl = ["paho-mqtt/build_bindgen"]
 
 # Debian packaging.
 [package.metadata.deb]
diff --git a/Cross.toml b/Cross.toml
index 4300cba..98e7d79 100644
--- a/Cross.toml
+++ b/Cross.toml
@@ -1,3 +1,6 @@
+[target.x86_64-unknown-linux-musl]
+dockerfile="cross/Dockerfile.x86_64-unknown-linux-musl"
+
 [target.aarch64-unknown-linux-musl]
 dockerfile="cross/Dockerfile.aarch64-unknown-linux-musl"
 
diff --git a/Makefile b/Makefile
index abf5e0a..d95cdbb 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,8 @@ build: build-aarch64-unknown-linux-musl \
 	build-armv5te-unknown-linux-musleabi \
 	build-armv7-unknown-linux-musleabihf \
 	build-mips-unknown-linux-musl \
-	build-mipsel-unknown-linux-musl
+	build-mipsel-unknown-linux-musl \
+	build-x86_64-unknown-linux-musl
 
 build-aarch64-unknown-linux-musl:
 	cross build --target aarch64-unknown-linux-musl --release
@@ -17,18 +18,22 @@ build-armv7-unknown-linux-musleabihf:
 	cross build --target armv7-unknown-linux-musleabihf --release
 
 build-mips-unknown-linux-musl:
-	cross build --target mips-unknown-linux-musl --release --no-default-features --features semtech_udp
+	cross build --target mips-unknown-linux-musl --release --no-default-features --features semtech_udp,paho_mqtt_bindgen_ssl
 
 build-mipsel-unknown-linux-musl:
-	cross build --target mipsel-unknown-linux-musl --release --no-default-features --features semtech_udp
+	cross build --target mipsel-unknown-linux-musl --release --no-default-features --features semtech_udp,paho_mqtt_bindgen_ssl	
+
+build-x86_64-unknown-linux-musl:
+	cross build --target x86_64-unknown-linux-musl --release --no-default-features --features semtech_udp,concentratord,paho_mqtt_vendored_ssl
 
 # Build distributable binaries for all targets.
 dist: dist-aarch64-unknown-linux-musl \
 	dist-armv5te-unknown-linux-musleabi \
 	dist-armv7-unknown-linux-musleabihf \
 	dist-mips-unknown-linux-musl \
-	dist-mipsel-unknown-linux-musl
-
+	dist-mipsel-unknown-linux-musl \
+	dist-x86_64-unknown-linux-musl
+	
 dist-aarch64-unknown-linux-musl: build-aarch64-unknown-linux-musl package-aarch64-unknown-linux-musl
 
 dist-armv5te-unknown-linux-musleabi: build-armv5te-unknown-linux-musleabi package-armv5te-unknown-linux-musleabi
@@ -39,6 +44,8 @@ dist-mips-unknown-linux-musl: build-mips-unknown-linux-musl package-mips-unknown
 
 dist-mipsel-unknown-linux-musl: build-mipsel-unknown-linux-musl package-mipsel-unknown-linux-musl
 
+dist-x86_64-unknown-linux-musl: build-x86_64-unknown-linux-musl package-x86_64-unknown-linux-musl
+
 # Package the compiled binaries
 package-aarch64-unknown-linux-musl:
 	$(eval PKG_VERSION := $(shell cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version'))
@@ -68,6 +75,17 @@ package-mips-unknown-linux-musl: package-dragino
 
 package-mipsel-unknown-linux-musl: package-rak-ramips-24kec
 
+package-x86_64-unknown-linux-musl:
+	$(eval PKG_VERSION := $(shell cargo metadata --no-deps --format-version 1 | jq -r '.packages[0].version'))
+	mkdir -p dist
+
+	# .tar.gz
+	tar -czvf dist/chirpstack-mqtt-forwarder_$(PKG_VERSION)_x86_64.tar.gz -C target/x86_64-unknown-linux-musl/release chirpstack-mqtt-forwarder
+
+	# .deb
+	cargo deb --target x86_64-unknown-linux-musl --no-build --no-strip
+	cp target/x86_64-unknown-linux-musl/debian/*.deb ./dist	
+
 # Gateway specific packaging.
 package-dragino:
 	cd packaging/vendor/dragino/mips_24kc && ./package.sh
diff --git a/cross/Dockerfile.x86_64-unknown-linux-musl b/cross/Dockerfile.x86_64-unknown-linux-musl
new file mode 100644
index 0000000..f78bef4
--- /dev/null
+++ b/cross/Dockerfile.x86_64-unknown-linux-musl
@@ -0,0 +1,30 @@
+FROM ghcr.io/cross-rs/x86_64-unknown-linux-musl:latest
+
+ENV OPENSSL_VERSION=3.1.2
+ENV OPENSSL_TARGET=linux-x86_64
+ENV MUSL_PREFIX=x86_64-linux-musl
+ENV OPENSSL_STATIC=1
+
+RUN apt-get update && \
+    apt-get --assume-yes install \
+    protobuf-compiler \
+    libprotobuf-dev \
+    pkg-config \
+    libssl-dev
+
+RUN echo "Building OpenSSL" && \
+    cd /tmp && \
+    curl -fLO "https://www.openssl.org/source/openssl-$OPENSSL_VERSION.tar.gz" && \
+    tar xvzf "openssl-$OPENSSL_VERSION.tar.gz" && cd "openssl-$OPENSSL_VERSION" && \
+    env CC=$MUSL_PREFIX-gcc ./Configure no-shared no-zlib -fPIC --prefix=/usr/local/$MUSL_PREFIX-target -DOPENSSL_NO_SECURE_MEMORY $OPENSSL_TARGET && \
+    env C_INCLUDE_PATH=/usr/local/$MUSL_PREFIX/include/ make depend && \
+    env C_INCLUDE_PATH=/usr/local/$MUSL_PREFIX/include/ make && \
+    make install_sw && \
+    rm -r /tmp/*
+
+RUN echo "Copy libstdc++" && \
+    mkdir -p /usr/local/$MUSL_PREFIX-target/lib && \
+    cp /usr/local/$MUSL_PREFIX/lib/libstdc++* /usr/local/$MUSL_PREFIX-target/lib
+
+
+ENV PKG_CONFIG_PATH=/usr/local/$MUSL_PREFIX-target/lib/pkgconfig
\ No newline at end of file


Patch repository

And next, patch the chirpstack-mqtt-forwarder repository.

$ cd ./chirpstack-mqtt-forwarder
$ git apply --ignore-space-change --ignore-whitespace add_cross-compile-target_x86_64.patch  

The command may display warnings. don't panic...

/home/lab/add_cross-compile-target_x86_6
[target.x86_64-unknown-linux-musl]
/home/lab/add_cross-compile-target_x86_6
  rustflags = [
/home/lab/add_cross-compile-target_x86_6
    "-C", "target-feature=+crt-static",
/home/lab/add_cross-compile-target_x86_6
    "-C", "link-arg=-s",
/home/lab/add_cross-compile-target_x86_6
    "-C", "link-arg=-lc",
warning: squelched 42 whitespace errors
warning: 47 lines add whitespace errors.

...It's OK.



Build

$ make clean
$ make build

Optional command $ docker system prune -a cleans all unused images from docker repository. You been warned.

$ docker system prune -a


Changes shortly

  • Makefile - add x86_64-unknown-linux-musl build instructions
  • cross.toml - add [target.x86_64-unknown-linux-musl]
  • cross/Dockerfile.x86_64-unknown-linux-musl - A new Docker build file
  • .cargo/config.toml - [target.x86_64-unknown-linux-musl] compilation flags

In the Cargo.toml is used the features of dependencies to control how to ssl of the paho-mqtt package will be built (paho_mqtt_vendored_ssl and paho_mqtt_bindgen_ss features).
For more details see Cargo book, feature

[features]
default = ["semtech_udp", "concentratord", "paho-mqtt/build_bindgen"]
semtech_udp = []
concentratord = ["zmq"]
paho_mqtt_vendored_ssl = ["paho-mqtt/vendored-ssl"]
paho_mqtt_bindgen_ssl = ["paho-mqtt/build_bindgen"]

A build parameters in the Make file controls how to ssl layer will be built for paho_mqtt package. Simplified building logics is described in examples below:


Makefile:

cross build --target aarch64-unknown-linux-musl --release

Cargo will build paho_mqtt with following fetures: paho-mqtt = { version = "0.12", features = ["ssl","build_bindgen"] } by using default features of the Cargo.toml file.

cross build --target x86_64-unknown-linux-musl --release --no-default-features --features semtech_udp,concentratord,paho_mqtt_vendored_ssl

Cargo will build paho_mqtt with following features: paho-mqtt = { version = "0.12", features = ["ssl","vendored-ssl"] }


Hints:




Let's do IoT better

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions