Skip to content

Commit efc79ec

Browse files
committed
Add musl generator in the CI.
1 parent 406f50c commit efc79ec

File tree

8 files changed

+145
-40
lines changed

8 files changed

+145
-40
lines changed

.cargo/config-linux-musl.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[build]
2+
target = "x86_64-unknown-linux-musl"
3+
rustflags = ["-C", "target-feature=+crt-static"]

.github/workflows/ci.yml

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,24 +16,43 @@ jobs:
1616
- stable
1717
- beta
1818
- nightly
19+
toolchain:
20+
- default
21+
- musl
22+
exclude:
23+
- os: windows-latest
24+
toolchain: musl
1925
runs-on: ${{ matrix.os }}
2026
steps:
2127
- name: Checkout
2228
uses: actions/checkout@v1
2329
- name: Install Rust ${{ matrix.rust }}
30+
if: ${{ matrix.toolchain != 'musl' }}
2431
uses: actions-rs/toolchain@v1
2532
with:
2633
profile: minimal
2734
toolchain: ${{ matrix.rust }}
2835
override: true
36+
- name: Install Rust ${{ matrix.rust }} (musl)
37+
if: ${{ matrix.toolchain == 'musl' }}
38+
uses: actions-rs/toolchain@v1
39+
with:
40+
profile: minimal
41+
toolchain: ${{ matrix.rust }}
42+
target: x86_64-unknown-linux-musl
43+
override: true
2944
- name: Copy Windows config
3045
if: ${{ runner.os == 'Windows' }}
3146
shell: pwsh
3247
run: Copy-Item -Path .cargo/config-windows.toml -Destination .cargo/config.toml
3348
- name: Copy Linux config
34-
if: ${{ runner.os == 'Linux' }}
49+
if: ${{ runner.os == 'Linux' && matrix.toolchain == 'default' }}
3550
shell: pwsh
3651
run: Copy-Item -Path .cargo/config-linux.toml -Destination .cargo/config.toml
52+
- name: Copy Linux musl config
53+
if: ${{ runner.os == 'Linux' && matrix.toolchain == 'musl' }}
54+
shell: pwsh
55+
run: Copy-Item -Path .cargo/config-linux-musl.toml -Destination .cargo/config.toml
3756
- name: Run Rust unit tests
3857
uses: actions-rs/cargo@v1
3958
with:
@@ -44,11 +63,13 @@ jobs:
4463
command: run
4564
args: --release --bin foo-bindings -- --c
4665
- name: .NET bindings
66+
if: ${{ matrix.toolchain != 'musl' }}
4767
uses: actions-rs/cargo@v1
4868
with:
4969
command: run
5070
args: --release --bin foo-bindings -- --dotnet
5171
- name: Java bindings
72+
if: ${{ matrix.toolchain != 'musl' }}
5273
uses: actions-rs/cargo@v1
5374
with:
5475
command: run
@@ -60,7 +81,7 @@ jobs:
6081
name: ffi-modules
6182
path: tests/bindings/c/generated/lib
6283
- name: Upload compiled Java bindings
63-
if: ${{ matrix.rust == 'stable' }}
84+
if: ${{ matrix.rust == 'stable' && matrix.toolchain != 'musl' }}
6485
uses: actions/upload-artifact@v2
6586
with:
6687
name: ffi-modules

ci-script/src/lib.rs

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -80,25 +80,25 @@ fn run_builder<'a, B: BindingBuilder<'a>>(
8080
) -> B {
8181
let mut platforms = PlatformLocations::new();
8282
if let Some(package_src) = package_src {
83-
let platform_path = [package_src, Platform::Linux.to_string()]
83+
let platform_path = [package_src, Platform::Win64.to_string()]
8484
.iter()
8585
.collect::<PathBuf>();
8686
if platform_path.is_dir() {
87-
platforms.add(Platform::Linux, platform_path);
87+
platforms.add(Platform::Win64, platform_path);
8888
}
8989

90-
let platform_path = [package_src, Platform::Win64.to_string()]
90+
let platform_path = [package_src, Platform::Linux.to_string()]
9191
.iter()
9292
.collect::<PathBuf>();
9393
if platform_path.is_dir() {
94-
platforms.add(Platform::Win64, platform_path);
94+
platforms.add(Platform::Linux, platform_path);
9595
}
9696

97-
let platform_path = [package_src, Platform::Win32.to_string()]
97+
let platform_path = [package_src, Platform::LinuxMusl.to_string()]
9898
.iter()
9999
.collect::<PathBuf>();
100100
if platform_path.is_dir() {
101-
platforms.add(Platform::Win32, platform_path);
101+
platforms.add(Platform::LinuxMusl, platform_path);
102102
}
103103
} else {
104104
platforms.add(Platform::current(), ffi_path());
@@ -108,7 +108,18 @@ fn run_builder<'a, B: BindingBuilder<'a>>(
108108
panic!("No platforms found!");
109109
}
110110

111+
let has_dynamic_libs = platforms.has_dynamic_lib();
112+
111113
let mut builder = B::new(settings, platforms);
114+
115+
if B::requires_dynamic_lib() && !has_dynamic_libs {
116+
println!(
117+
"Skipping {} because it requires dynamic libraries",
118+
B::name()
119+
);
120+
return builder;
121+
}
122+
112123
builder.generate(package_src.is_some());
113124

114125
if package_src.is_none() {
@@ -132,6 +143,8 @@ pub struct BindingBuilderSettings<'a> {
132143
}
133144

134145
trait BindingBuilder<'a> {
146+
fn name() -> &'static str;
147+
fn requires_dynamic_lib() -> bool;
135148
fn new(settings: &'a BindingBuilderSettings<'a>, platforms: PlatformLocations) -> Self;
136149
fn generate(&mut self, is_packaging: bool);
137150
fn build(&mut self);
@@ -175,6 +188,14 @@ impl<'a> CBindingBuilder<'a> {
175188
}
176189

177190
impl<'a> BindingBuilder<'a> for CBindingBuilder<'a> {
191+
fn name() -> &'static str {
192+
"c"
193+
}
194+
195+
fn requires_dynamic_lib() -> bool {
196+
false
197+
}
198+
178199
fn new(settings: &'a BindingBuilderSettings<'a>, platforms: PlatformLocations) -> Self {
179200
Self {
180201
settings,
@@ -256,6 +277,14 @@ impl<'a> DotnetBindingBuilder<'a> {
256277
}
257278

258279
impl<'a> BindingBuilder<'a> for DotnetBindingBuilder<'a> {
280+
fn name() -> &'static str {
281+
"dotnet"
282+
}
283+
284+
fn requires_dynamic_lib() -> bool {
285+
true
286+
}
287+
259288
fn new(settings: &'a BindingBuilderSettings<'a>, platforms: PlatformLocations) -> Self {
260289
Self {
261290
settings,
@@ -359,6 +388,14 @@ impl<'a> JavaBindingBuilder<'a> {
359388
}
360389

361390
impl<'a> BindingBuilder<'a> for JavaBindingBuilder<'a> {
391+
fn name() -> &'static str {
392+
"java"
393+
}
394+
395+
fn requires_dynamic_lib() -> bool {
396+
true
397+
}
398+
362399
fn new(settings: &'a BindingBuilderSettings<'a>, platforms: PlatformLocations) -> Self {
363400
Self {
364401
settings,

generators/c-oo-bindgen/src/lib.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ clippy::all
4646

4747
use crate::doc::*;
4848
use crate::formatting::*;
49-
use heck::{CamelCase, SnakeCase};
49+
use heck::{CamelCase, ShoutySnakeCase, SnakeCase};
5050
use oo_bindgen::callback::*;
5151
use oo_bindgen::class::*;
5252
use oo_bindgen::doc::*;
@@ -760,11 +760,44 @@ fn generate_cmake_config(lib: &Library, config: &CBindgenConfig) -> FormattingRe
760760

761761
// Write each platform variation
762762
let mut is_first_if = true;
763+
764+
// Add a config value if we have two linux versions
765+
let has_static_choice =
766+
if config.platforms.linux.is_some() && config.platforms.linux_musl.is_some() {
767+
f.writeln(&format!(
768+
"set({}_STATIC_MUSL OFF CACHE BOOL \"Use statically built musl lib on Linux for {}\")",
769+
lib.name.to_shouty_snake_case(),
770+
lib.name
771+
))?;
772+
f.newline()?;
773+
true
774+
} else {
775+
false
776+
};
777+
763778
for p in config.platforms.iter() {
764779
let platform_check = match p.platform {
765-
Platform::Win64 => "WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8",
766-
Platform::Win32 => "WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4",
767-
Platform::Linux => "UNIX AND CMAKE_SIZEOF_VOID_P EQUAL 8",
780+
Platform::Win64 => "WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8".to_string(),
781+
Platform::Linux => {
782+
if !has_static_choice {
783+
"UNIX AND CMAKE_SIZEOF_VOID_P EQUAL 8".to_string()
784+
} else {
785+
format!(
786+
"UNIX AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT $CACHE{{{}_STATIC_MUSL}}",
787+
lib.name.to_shouty_snake_case()
788+
)
789+
}
790+
}
791+
Platform::LinuxMusl => {
792+
if !has_static_choice {
793+
"UNIX AND CMAKE_SIZEOF_VOID_P EQUAL 8".to_string()
794+
} else {
795+
format!(
796+
"UNIX AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND $CACHE{{{}_STATIC_MUSL}}",
797+
lib.name.to_shouty_snake_case()
798+
)
799+
}
800+
}
768801
};
769802

770803
if is_first_if {

generators/dotnet-oo-bindgen/src/lib.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,11 @@ fn generate_csproj(lib: &Library, config: &DotnetBindgenConfig) -> FormattingRes
108108
f.newline()?;
109109
f.writeln(" <ItemGroup>")?;
110110

111-
for p in config.platforms.iter() {
111+
for p in config
112+
.platforms
113+
.iter()
114+
.filter(|x| x.platform != Platform::LinuxMusl)
115+
{
112116
let filename = p.bin_filename(&config.ffi_name);
113117
let filepath = dunce::canonicalize(p.location.join(&filename))?;
114118
f.writeln(&format!(" <Content Include=\"{}\" Link=\"{}\" Pack=\"true\" PackagePath=\"runtimes/{}/native\" CopyToOutputDirectory=\"PreserveNewest\" />", filepath.to_string_lossy(), filename, p.platform.to_string()))?;

generators/java-oo-bindgen/src/java/mod.rs

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,11 @@ pub fn generate_java_bindings(lib: &Library, config: &JavaBindgenConfig) -> Form
2828
// Copy the compiled libraries to the resource folder
2929
let mut ffi_name = config.ffi_name.clone();
3030
ffi_name.push_str("_java");
31-
for platform in config.platforms.iter() {
31+
for platform in config
32+
.platforms
33+
.iter()
34+
.filter(|x| x.platform != Platform::LinuxMusl)
35+
{
3236
let mut target_dir = config.java_resource_dir();
3337
target_dir.push(platform.platform.to_string());
3438
fs::create_dir_all(&target_dir)?;
@@ -125,16 +129,6 @@ fn generate_native_func_class(lib: &Library, config: &JavaBindgenConfig) -> Form
125129
))
126130
})?;
127131
}
128-
Platform::Win32 => {
129-
f.writeln("if(org.apache.commons.lang3.SystemUtils.IS_OS_WINDOWS && org.apache.commons.lang3.ArchUtils.getProcessor().is32Bit())")?;
130-
blocked(f, |f| {
131-
f.writeln(&format!(
132-
"loadLibrary(\"{}\", \"{}\", \"dll\");",
133-
platform.platform.to_string(),
134-
libname
135-
))
136-
})?;
137-
}
138132
Platform::Linux => {
139133
f.writeln("if(org.apache.commons.lang3.SystemUtils.IS_OS_LINUX && org.apache.commons.lang3.ArchUtils.getProcessor().is64Bit())")?;
140134
blocked(f, |f| {
@@ -145,6 +139,7 @@ fn generate_native_func_class(lib: &Library, config: &JavaBindgenConfig) -> Form
145139
))
146140
})?;
147141
}
142+
Platform::LinuxMusl => (), // We do not generate Java bindings for Linux musl
148143
}
149144
}
150145
Ok(())

0 commit comments

Comments
 (0)