1+ include (CheckLinkerFlag )
2+
13find_program (PATCHELF_EXECUTABLE NAMES patchelf )
24
35if (NOT PATCHELF_EXECUTABLE AND LINUX )
@@ -10,19 +12,15 @@ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/lib)
1012set (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
1518set (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} )
3432endforeach ()
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-
7634add_custom_target (gosling_c_bindings_target
7735 DEPENDS ${gosling_c_bindings_outputs} )
7836add_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-
10153if (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 )
12697endif ()
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+
128109add_custom_target (gosling_c_shared_bindings_target ALL )
129110add_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)
137118install (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