Skip to content

Commit ebfbb6e

Browse files
committed
Follow-up to #41. CMake now defines a {libname}_static target instead of relying on a cache variable.
1 parent f3da890 commit ebfbb6e

File tree

3 files changed

+80
-60
lines changed

3 files changed

+80
-60
lines changed

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

Lines changed: 54 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -783,54 +783,12 @@ fn generate_cmake_config(lib: &Library, config: &CBindgenConfig) -> FormattingRe
783783
f.writeln("set(prefix \"${CMAKE_CURRENT_LIST_DIR}/../\")")?;
784784
f.newline()?;
785785

786-
// Write each platform variation
787786
let mut is_first_if = true;
788787

789-
// Add a config value if we have two linux versions
790-
let has_static_choice =
791-
if config.platforms.linux.is_some() && config.platforms.linux_musl.is_some() {
792-
f.writeln(&format!(
793-
"set({}_STATIC_MUSL OFF CACHE BOOL \"Use statically built musl lib on Linux for {}\")",
794-
lib.name.to_shouty_snake_case(),
795-
lib.name
796-
))?;
797-
f.newline()?;
798-
true
799-
} else {
800-
false
801-
};
802-
803-
for p in config.platforms.iter() {
804-
let platform_check = match p.platform {
805-
Platform::Win64 => "WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8".to_string(),
806-
Platform::Linux => {
807-
if !has_static_choice {
808-
"UNIX AND CMAKE_SIZEOF_VOID_P EQUAL 8".to_string()
809-
} else {
810-
format!(
811-
"UNIX AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND NOT $CACHE{{{}_STATIC_MUSL}}",
812-
lib.name.to_shouty_snake_case()
813-
)
814-
}
815-
}
816-
Platform::LinuxMusl => {
817-
if !has_static_choice {
818-
"UNIX AND CMAKE_SIZEOF_VOID_P EQUAL 8".to_string()
819-
} else {
820-
format!(
821-
"UNIX AND CMAKE_SIZEOF_VOID_P EQUAL 8 AND $CACHE{{{}_STATIC_MUSL}}",
822-
lib.name.to_shouty_snake_case()
823-
)
824-
}
825-
}
826-
};
827-
828-
if is_first_if {
829-
f.writeln(&format!("if({})", platform_check))?;
830-
is_first_if = false;
831-
} else {
832-
f.writeln(&format!("elseif({})", platform_check))?;
833-
}
788+
// Windows platform
789+
if let Some(p) = &config.platforms.win64 {
790+
f.writeln("if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8)")?;
791+
is_first_if = false;
834792

835793
indented(&mut f, |f| {
836794
f.writeln(&format!("add_library({} SHARED IMPORTED GLOBAL)", lib.name))?;
@@ -852,6 +810,56 @@ fn generate_cmake_config(lib: &Library, config: &CBindgenConfig) -> FormattingRe
852810
})?;
853811
}
854812

813+
const LINUX_PLATFORM_CHECK: &str = "UNIX AND CMAKE_SIZEOF_VOID_P EQUAL 8";
814+
815+
// Linux dynamic lib
816+
if config.platforms.linux.is_some() || config.platforms.linux_musl.is_some() {
817+
if is_first_if {
818+
f.writeln(&format!("if({})", LINUX_PLATFORM_CHECK))?;
819+
//is_first_if = false;
820+
} else {
821+
f.writeln(&format!("elseif({})", LINUX_PLATFORM_CHECK))?;
822+
}
823+
824+
if let Some(p) = &config.platforms.linux {
825+
indented(&mut f, |f| {
826+
f.writeln(&format!("add_library({} SHARED IMPORTED GLOBAL)", lib.name))?;
827+
f.writeln(&format!("set_target_properties({} PROPERTIES", lib.name))?;
828+
indented(f, |f| {
829+
f.writeln(&format!(
830+
"IMPORTED_LOCATION \"${{prefix}}/lib/{}/{}\"",
831+
p.platform.to_string(),
832+
p.bin_filename(&config.ffi_name)
833+
))?;
834+
f.writeln("INTERFACE_INCLUDE_DIRECTORIES \"${prefix}/include\"")
835+
})?;
836+
f.writeln(")")
837+
})?;
838+
}
839+
840+
if let Some(p) = &config.platforms.linux_musl {
841+
indented(&mut f, |f| {
842+
f.writeln(&format!(
843+
"add_library({}_static STATIC IMPORTED GLOBAL)",
844+
lib.name
845+
))?;
846+
f.writeln(&format!(
847+
"set_target_properties({}_static PROPERTIES",
848+
lib.name
849+
))?;
850+
indented(f, |f| {
851+
f.writeln(&format!(
852+
"IMPORTED_LOCATION \"${{prefix}}/lib/{}/{}\"",
853+
p.platform.to_string(),
854+
p.bin_filename(&config.ffi_name)
855+
))?;
856+
f.writeln("INTERFACE_INCLUDE_DIRECTORIES \"${prefix}/include\"")
857+
})?;
858+
f.writeln(")")
859+
})?;
860+
}
861+
}
862+
855863
// Write error message if platform not found
856864
f.writeln("else()")?;
857865
indented(&mut f, |f| {

oo-bindgen/src/platforms.rs

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ impl Platform {
3737
}
3838
}
3939

40+
#[derive(Clone)]
4041
pub struct PlatformLocation {
4142
pub platform: Platform,
4243
pub location: PathBuf,
@@ -66,9 +67,9 @@ impl PlatformLocation {
6667

6768
#[derive(Clone)]
6869
pub struct PlatformLocations {
69-
pub win64: Option<PathBuf>,
70-
pub linux: Option<PathBuf>,
71-
pub linux_musl: Option<PathBuf>,
70+
pub win64: Option<PlatformLocation>,
71+
pub linux: Option<PlatformLocation>,
72+
pub linux_musl: Option<PlatformLocation>,
7273
}
7374

7475
impl PlatformLocations {
@@ -81,23 +82,24 @@ impl PlatformLocations {
8182
}
8283

8384
pub fn add(&mut self, platform: Platform, location: PathBuf) {
85+
let loc = PlatformLocation::new(platform, location);
8486
match platform {
85-
Platform::Win64 => self.win64 = Some(location),
86-
Platform::Linux => self.linux = Some(location),
87-
Platform::LinuxMusl => self.linux_musl = Some(location),
87+
Platform::Win64 => self.win64 = Some(loc),
88+
Platform::Linux => self.linux = Some(loc),
89+
Platform::LinuxMusl => self.linux_musl = Some(loc),
8890
}
8991
}
9092

9193
pub fn iter(&self) -> impl Iterator<Item = PlatformLocation> {
9294
let mut vec = Vec::new();
9395
if let Some(loc) = &self.win64 {
94-
vec.push(PlatformLocation::new(Platform::Win64, loc.clone()))
96+
vec.push(loc.clone())
9597
}
9698
if let Some(loc) = &self.linux {
97-
vec.push(PlatformLocation::new(Platform::Linux, loc.clone()))
99+
vec.push(loc.clone())
98100
}
99101
if let Some(loc) = &self.linux_musl {
100-
vec.push(PlatformLocation::new(Platform::LinuxMusl, loc.clone()))
102+
vec.push(loc.clone())
101103
}
102104
vec.into_iter()
103105
}

tests/bindings/c/CMakeLists.txt

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@ project(foo_c LANGUAGES C)
66
set(CMAKE_PREFIX_PATH ${CMAKE_CURRENT_LIST_DIR}/generated/cmake)
77
find_package(foo REQUIRED)
88

9+
# You probably don't need do this, just pick either the dynamic or the static
10+
# one if you are on Linux. Here we do CMake trickery to make it work on the CI.
11+
if(TARGET foo)
12+
set(foo_target foo)
13+
else()
14+
set(foo_target foo_static)
15+
endif()
16+
917
set(tests
1018
./version_tests.c
1119
./enum_tests.c
@@ -18,12 +26,14 @@ set(tests
1826
)
1927

2028
add_executable(foo_c main.c ${tests})
21-
target_link_libraries(foo_c PRIVATE foo)
29+
target_link_libraries(foo_c PRIVATE ${foo_target})
2230

23-
# Copy the DLL after build
24-
add_custom_command(TARGET foo_c POST_BUILD
25-
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:foo> $<TARGET_FILE_DIR:foo_c>
26-
)
31+
# Copy the DLL after build (if using dynamic)
32+
if(${foo_target} EQUAL "foo")
33+
add_custom_command(TARGET foo_c POST_BUILD
34+
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:foo> $<TARGET_FILE_DIR:foo_c>
35+
)
36+
endif()
2737

2838
enable_testing()
2939
add_test(NAME foo_c COMMAND foo_c)

0 commit comments

Comments
 (0)