Skip to content

Commit 9ae019e

Browse files
author
Richard Pospesel
committed
cgosling: build our own shared library instead of using rust's cdylib target
1 parent 757fe0f commit 9ae019e

File tree

9 files changed

+465
-142
lines changed

9 files changed

+465
-142
lines changed

source/bindings/c/CMakeLists.txt

Lines changed: 44 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
include(CheckLinkerFlag)
2+
13
find_program(PATCHELF_EXECUTABLE NAMES patchelf)
24

35
if (NOT PATCHELF_EXECUTABLE AND LINUX)
@@ -10,19 +12,15 @@ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
1012
set(gosling_c_bindings_sources
1113
${CARGO_TARGET_DIR}/include/cgosling.h
1214
${CARGO_TARGET_DIR}/${CARGO_PROFILE}/${CGOSLING_STATIC}
15+
${CARGO_TARGET_DIR}/${CARGO_PROFILE}/${CGOSLING_IMPL_STATIC}
1316
)
1417

1518
set(gosling_c_bindings_outputs
1619
${CMAKE_CURRENT_BINARY_DIR}/include/cgosling.h
1720
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_STATIC}
21+
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_IMPL_STATIC}
1822
)
1923

20-
# add Shared library import library
21-
if (WINDOWS)
22-
list(APPEND gosling_c_bindings_sources ${CARGO_TARGET_DIR}/${CARGO_PROFILE}/${CGOSLING_IMPORT})
23-
list(APPEND gosling_c_bindings_outputs ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_IMPORT})
24-
endif()
25-
2624
#
2725
# Just copy header and libs from the cgosling crate build outputs
2826
#
@@ -33,46 +31,6 @@ foreach(src dest IN ZIP_LISTS gosling_c_bindings_sources gosling_c_bindings_outp
3331
COMMAND cp -P ${src} ${dest})
3432
endforeach()
3533

36-
# Shared Library + Symlinks
37-
if (LINUX)
38-
add_custom_command(
39-
DEPENDS ${CARGO_TARGET_DIR}/${CARGO_PROFILE}/${CGOSLING_SHARED}
40-
OUTPUT
41-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}.${CGOSLING_VERSION}
42-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}.${CGOSLING_MAJOR_VERSION}
43-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}
44-
# copy shared library and set soname
45-
COMMAND ${CMAKE_COMMAND} -E copy ${CARGO_TARGET_DIR}/${CARGO_PROFILE}/${CGOSLING_SHARED} ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}.${CGOSLING_VERSION}
46-
COMMAND patchelf --set-soname libcgosling.so.${CGOSLING_MAJOR_VERSION} ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}.${CGOSLING_VERSION}
47-
# create symlinks
48-
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CGOSLING_SHARED}.${CGOSLING_VERSION} ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}.${CGOSLING_MAJOR_VERSION}
49-
COMMAND ${CMAKE_COMMAND} -E create_symlink ${CGOSLING_SHARED}.${CGOSLING_MAJOR_VERSION} ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED})
50-
list(APPEND gosling_c_bindings_outputs ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}.${CGOSLING_VERSION})
51-
list(APPEND gosling_c_bindings_outputs ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}.${CGOSLING_MAJOR_VERSION})
52-
list(APPEND gosling_c_bindings_outputs ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED})
53-
elseif(MACOS)
54-
add_custom_command(
55-
DEPENDS ${CARGO_TARGET_DIR}/${CARGO_PROFILE}/${CGOSLING_SHARED}
56-
OUTPUT
57-
${CMAKE_CURRENT_BINARY_DIR}/lib/libcgosling.${CGOSLING_VERSION}.dylib
58-
${CMAKE_CURRENT_BINARY_DIR}/lib/libcgosling.${CGOSLING_MAJOR_VERSION}.dylib
59-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}
60-
# copy shared library
61-
COMMAND ${CMAKE_COMMAND} -E copy ${CARGO_TARGET_DIR}/${CARGO_PROFILE}/${CGOSLING_SHARED} ${CMAKE_CURRENT_BINARY_DIR}/lib/libcgosling.${CGOSLING_VERSION}.dylib
62-
# create symlinks
63-
COMMAND ${CMAKE_COMMAND} -E create_symlink libcgosling.${CGOSLING_VERSION}.dylib ${CMAKE_CURRENT_BINARY_DIR}/lib/libcgosling.${CGOSLING_MAJOR_VERSION}.dylib
64-
COMMAND ${CMAKE_COMMAND} -E create_symlink libcgosling.${CGOSLING_MAJOR_VERSION}.dylib ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED})
65-
list(APPEND gosling_c_bindings_outputs ${CMAKE_CURRENT_BINARY_DIR}/lib/libcgosling.${CGOSLING_VERSION}.dylib)
66-
list(APPEND gosling_c_bindings_outputs ${CMAKE_CURRENT_BINARY_DIR}/lib/libcgosling.${CGOSLING_MAJOR_VERSION}.dylib)
67-
list(APPEND gosling_c_bindings_outputs ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED})
68-
else()
69-
add_custom_command(
70-
DEPENDS ${CARGO_TARGET_DIR}/${CARGO_PROFILE}/${CGOSLING_SHARED}
71-
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}
72-
COMMAND ${CMAKE_COMMAND} -E copy ${CARGO_TARGET_DIR}/${CARGO_PROFILE}/${CGOSLING_SHARED} ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED})
73-
list(APPEND gosling_c_bindings_outputs ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED})
74-
endif()
75-
7634
add_custom_target(gosling_c_bindings_target
7735
DEPENDS ${gosling_c_bindings_outputs})
7836
add_dependencies(gosling_c_bindings_target cgosling_target)
@@ -92,12 +50,6 @@ set_target_properties(gosling_c_static_bindings PROPERTIES
9250
IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_STATIC}
9351
)
9452

95-
# Linux targets needed by rust runtime
96-
if(LINUX)
97-
target_link_libraries(gosling_c_static_bindings INTERFACE pthread)
98-
target_link_libraries(gosling_c_static_bindings INTERFACE dl)
99-
endif()
100-
10153
if(WINDOWS)
10254
target_link_libraries(gosling_c_static_bindings INTERFACE ws2_32)
10355
target_link_libraries(gosling_c_static_bindings INTERFACE userenv)
@@ -112,19 +64,48 @@ add_dependencies(gosling_c_static_bindings_target gosling_c_static_bindings)
11264
# Shared Library
11365
#
11466

115-
add_library(gosling_c_shared_bindings SHARED IMPORTED GLOBAL)
116-
add_dependencies(gosling_c_shared_bindings gosling_c_bindings_target)
117-
118-
target_include_directories(gosling_c_shared_bindings INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/include)
119-
set_target_properties(gosling_c_shared_bindings PROPERTIES
120-
IMPORTED_LOCATION ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}
67+
# generate cgosling.c
68+
set(gosling_c_shared_bindings_sources
69+
build_c_shared_bindings.rs
70+
Cargo.toml
71+
cgosling.c.handlebars)
72+
73+
# cgosling.c basically forwards the various gosling calls in the public header
74+
# to the _impl methods
75+
add_custom_command(
76+
DEPENDS ${gosling_c_shared_bindings_sources} gosling_c_bindings_target
77+
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/cgosling.c
78+
# generate c source
79+
COMMAND env CARGO_TARGET_DIR=${CARGO_TARGET_DIR} RUSTFLAGS=${RUSTFLAGS} RUST_BACKTRACE=full cargo run ${CARGO_FLAGS} --bin build_c_shared_bindings ${CARGO_TARGET_DIR}/cgosling.json cgosling.c.handlebars ${CMAKE_CURRENT_BINARY_DIR}/cgosling.c
80+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
12181
)
122-
if (WINDOWS)
123-
set_target_properties(gosling_c_shared_bindings PROPERTIES
124-
IMPORTED_IMPLIB ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_IMPORT}
125-
)
82+
83+
# build our shared library
84+
add_library(gosling_c_shared_bindings SHARED ${CMAKE_CURRENT_BINARY_DIR}/cgosling.c)
85+
set_target_properties(gosling_c_shared_bindings
86+
PROPERTIES
87+
OUTPUT_NAME cgosling
88+
VERSION ${CGOSLING_VERSION}
89+
SOVERSION ${CGOSLING_MAJOR_VERSION})
90+
target_include_directories(gosling_c_shared_bindings PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include)
91+
target_link_libraries(gosling_c_shared_bindings PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_IMPL_STATIC})
92+
if(WINDOWS)
93+
target_link_libraries(gosling_c_shared_bindings PRIVATE ws2_32)
94+
target_link_libraries(gosling_c_shared_bindings PRIVATE userenv)
95+
target_link_libraries(gosling_c_shared_bindings PRIVATE bcrypt)
96+
target_link_libraries(gosling_c_shared_bindings PRIVATE ntdll)
12697
endif()
12798

99+
# check if the --exclude-libs flag is supported by the linker
100+
check_linker_flag(C "-Wl,--exclude-libs,ALL" LINKER_SUPPORTS_EXCLUDE_LIBS)
101+
102+
if(LINKER_SUPPORTS_EXCLUDE_LIBS)
103+
# prevents the result so from re-exporting all of the static libs symbols out of the shared library
104+
target_link_options(gosling_c_shared_bindings PRIVATE "-Wl,--exclude-libs,ALL")
105+
endif()
106+
107+
target_include_directories(gosling_c_shared_bindings PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/include)
108+
128109
add_custom_target(gosling_c_shared_bindings_target ALL)
129110
add_dependencies(gosling_c_shared_bindings_target gosling_c_shared_bindings)
130111

@@ -136,44 +117,5 @@ install(FILES ${CMAKE_CURRENT_BINARY_DIR}/include/cgosling.h
136117
TYPE INCLUDE)
137118
install(FILES
138119
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_STATIC}
139-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}
140120
TYPE LIB)
141-
if (WINDOWS)
142-
# .a + .dll.a goes to lib
143-
install(FILES
144-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_STATIC}
145-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_IMPORT}
146-
TYPE LIB)
147-
# .dll goes to bin
148-
install(FILES
149-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}
150-
TYPE BIN)
151-
elseif (LINUX)
152-
# .so and .a go to lib
153-
install(FILES
154-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_STATIC}
155-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}
156-
TYPE LIB)
157-
# versioned symlinks go to lib
158-
install(FILES
159-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}.${CGOSLING_MAJOR_VERSION}
160-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}.${CGOSLING_VERSION}
161-
TYPE LIB)
162-
elseif (MACOS)
163-
# .dylib and .a go to lib
164-
install(FILES
165-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_STATIC}
166-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}
167-
TYPE LIB)
168-
# versioned symlinks go to lib
169-
install(FILES
170-
${CMAKE_CURRENT_BINARY_DIR}/lib/libcgosling.${CGOSLING_MAJOR_VERSION}.dylib
171-
${CMAKE_CURRENT_BINARY_DIR}/lib/libcgosling.${CGOSLING_VERSION}.dylib
172-
TYPE LIB)
173-
else()
174-
install(FILES
175-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_STATIC}
176-
${CMAKE_CURRENT_BINARY_DIR}/lib/${CGOSLING_SHARED}
177-
TYPE LIB)
178-
endif()
179-
121+
install(TARGETS gosling_c_shared_bindings)

0 commit comments

Comments
 (0)