If you're writing CMake-based tests for mulle-objc and targeting Windows, there are a few gotchas that may bite you. Here's some tips to have it easy in a MulleObjC/mulle-sde based test suite.
The _mulle_atinit is not available yet Problem #
When building Windows executables that link against mulle-objc DLLs, may have
DLLs trying to call _mulle_atinit
(which lives in the executable) but they fail with:
_mulle_atinit is not available yet, bummer
Possibly followed by a universe initialization crash. Not fun.
The Solution: Export Your Symbols #
On Windows, executables need to explicitly export symbols that DLLs will call. Add this to your CMakeLists.txt:
1# Export symbols needed for Windows DLL dynamic linking
2if( WIN32)
3 target_link_options( your-test.exe
4 PUBLIC
5 "-Wl,--export-all-symbols"
6 )
7endif()
This exports _mulle_atinit, _mulle_atexit, and ___register_mulle_objc_universe
so DLLs can find them during initialization.
Enable TAO for Debug Builds #
If you're testing in Debug you are testing with Thread Affine Objects (TAO), make sure to enable the flag for Debug builds:
1if( CMAKE_BUILD_TYPE MATCHES "^Debug|^Test")
2 target_compile_options( your-test.exe PRIVATE -fobjc-tao)
3 message( STATUS "TAO enabled via compiler flag")
4endif()
Complete CMakeLists.txt Template #
Here's a minimal working example:
1cmake_minimum_required( VERSION 3.13...99.99)
2
3set(CMAKE_C_COMPILER_WORKS 1)
4
5project( your-test C)
6
7set( SOURCES
8 main.m
9 Foo.m
10)
11
12add_executable( your-test.exe
13 ${SOURCES}
14)
15
16# Enable TAO for Debug/Test builds
17if( CMAKE_BUILD_TYPE MATCHES "^Debug|^Test")
18 target_compile_options( "your-test.exe" PRIVATE -fobjc-tao)
19 message( STATUS "TAO enabled via compiler flag")
20endif()
21
22# Link against test libraries
23target_link_libraries( your-test.exe
24 ${TEST_LIBRARIES}
25)
26
27# Export symbols for Windows DLL dynamic linking
28if( WIN32)
29 target_link_options( your-test.exe
30 PUBLIC
31 "-Wl,--export-all-symbols"
32 )
33endif()
File Structure #
Place your CMake test in the test directory:
test/
test-category/
your-test/
CMakeLists.txt
main.m
Foo.m
Foo.h
your-test.stdout # Expected output
The test name comes from the CMake project name, not the directory name.
Why This Matters #
Without proper symbol exports, Windows DLLs can't find the initialization
functions they need. The runtime tries to use mulle_dlsym_exe() to
locate _mulle_atinit, but if it's not exportedy.
On Linux/macOS, this "just works" because of different dynamic linking semantics. Windows requires explicit exports.
Testing #
Run your test with:
1cd test && mulle-sde test run --platform windows YourCategory/your-test/your-test
Or for the full suite:
1cd test && mulle-sde test run --platform windows
The Gotcha #
If you see TAO mismatch errors like:
the runtime is compiled for thread affine objects -fobjc-tao,
but these objects are compiled -fno-objc-tao
You forgot to enable TAO for Debug builds. Add the target_compile_options block above.
This text is mostly AI written, with some edits