diff --git a/cmake/flink.cmake b/cmake/flink.cmake
new file mode 100644
index 0000000..e0d826e
--- /dev/null
+++ b/cmake/flink.cmake
@@ -0,0 +1,32 @@
+include(CMakeParseArguments)
+
+function(target_do_force_link_libraries target visibility lib)
+  if(MSVC)
+    target_link_libraries(${target} ${visibility} "/WHOLEARCHIVE:${lib}")
+  elseif(APPLE)
+    target_link_libraries(${target} ${visibility} -Wl,-force_load ${lib})
+  else()
+    target_link_libraries(${target} ${visibility} -Wl,--whole-archive ${lib} -Wl,--no-whole-archive)
+  endif()
+endfunction()
+
+function(target_force_link_libraries target)
+  cmake_parse_arguments(FLINK
+    ""
+    ""
+    "PUBLIC;INTERFACE;PRIVATE"
+    ${ARGN}
+  )
+  
+  foreach(lib IN LISTS FLINK_PUBLIC)
+    target_do_force_link_libraries(${target} PUBLIC ${lib})
+  endforeach()
+
+  foreach(lib IN LISTS FLINK_INTERFACE)
+    target_do_force_link_libraries(${target} INTERFACE ${lib})
+  endforeach()
+  
+  foreach(lib IN LISTS FLINK_PRIVATE)
+    target_do_force_link_libraries(${target} PRIVATE ${lib})
+  endforeach()
+endfunction()
\ No newline at end of file
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7ebe6a9..da06a90 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,4 +1,5 @@
 include(../cmake/swifft_defaults.cmake)
+include(../cmake/flink.cmake)
 
 add_executable(swifft_keygen swifft_keygen.cpp)
 
@@ -57,10 +58,8 @@ add_library(swifft_shared SHARED ${CMAKE_CURRENT_BINARY_DIR}/swifft_so_dummy.c)
 install(TARGETS swifft_shared DESTINATION lib)
 set_target_properties(swifft_shared PROPERTIES OUTPUT_NAME swifft)
 set_target_properties(swifft_shared PROPERTIES LINKER_LANGUAGE CXX)
-target_link_libraries(swifft_shared PUBLIC
-	-Wl,--whole-archive
-	$<TARGET_PROPERTY:swifft_static,NAME>
-	-Wl,--no-whole-archive
+target_force_link_libraries(swifft_shared
+	PUBLIC $<TARGET_PROPERTY:swifft_static,NAME>
 )