# Shared CMake logic for every platform that builds the Nim library from # source. Included by android/, linux/ and windows/. cmake_minimum_required(VERSION 3.15) project(nimflutter LANGUAGES C) find_program(NIM_EXECUTABLE nim REQUIRED DOC "The Nim compiler. Set -DNIM_EXECUTABLE=/path/to/nim to override.") set(NF_SRC "${CMAKE_CURRENT_LIST_DIR}/nimflutter.nim") # Nim cross-compiles by emitting C, so the reliable pattern is: # Nim source -> C (Nim's job) C -> object/library (the toolchain's) # This keeps the NDK / MSVC / clang in charge of ABI, sysroot and flags. # # Nim writes one .c per module rather than a single file, and the set is only # known after it runs — so it runs at CONFIGURE time and the results are # globbed, instead of the add_custom_command a single-file emitter allows. set(NF_NIMCACHE "${CMAKE_CURRENT_BINARY_DIR}/nimcache") execute_process( COMMAND "${NIM_EXECUTABLE}" c --compileOnly --nimcache:${NF_NIMCACHE} --mm:arc -d:danger --threads:on --noMain "${NF_SRC}" RESULT_VARIABLE NF_NIM_RESULT OUTPUT_VARIABLE NF_NIM_OUTPUT ERROR_VARIABLE NF_NIM_OUTPUT) if(NOT NF_NIM_RESULT EQUAL 0) message(FATAL_ERROR "nim failed to emit C:\n${NF_NIM_OUTPUT}") endif() file(GLOB NF_GENERATED_C "${NF_NIMCACHE}/*.c") if(NF_GENERATED_C STREQUAL "") message(FATAL_ERROR "nim produced no C in ${NF_NIMCACHE}") endif() add_library(nimflutter SHARED ${NF_GENERATED_C}) # nimbase.h lives in Nim's own lib/, alongside the compiler. get_filename_component(NF_NIM_BIN "${NIM_EXECUTABLE}" DIRECTORY) get_filename_component(NF_NIM_ROOT "${NF_NIM_BIN}" DIRECTORY) target_include_directories(nimflutter PUBLIC "${CMAKE_CURRENT_LIST_DIR}" "${NF_NIM_ROOT}/lib") # Nim's generated C is machine output: silence the noise, keep real errors. # # -O2 is set unconditionally, including in Debug. This library is a numeric # kernel with no Dart-visible debugger story of its own, and at -O0 the # Mandelbrot path runs several times slower than the equivalent Dart — which # makes a debug run of the example wildly misrepresent the bridge. if(MSVC) target_compile_options(nimflutter PRIVATE /O2) else() target_compile_options(nimflutter PRIVATE -O2 -w -fPIC -Wno-int-conversion -Wno-incompatible-pointer-types) endif() if(ANDROID) target_link_libraries(nimflutter PRIVATE log) endif() # Nim's threading support needs pthreads where the platform has them. find_package(Threads) if(Threads_FOUND AND NOT ANDROID AND NOT WIN32) target_link_libraries(nimflutter PRIVATE Threads::Threads) endif() set_target_properties(nimflutter PROPERTIES OUTPUT_NAME "nimflutter" C_VISIBILITY_PRESET hidden)