cmake: add SOGEN_STATIC_CRT option for static runtime linking (#606)

## Summary

Adds a CMake option to use static CRT (`/MT`) instead of the default
dynamic CRT (`/MD`).

**Use case:** Projects that require static linking (e.g., IDA Pro
plugins) cannot use the default `/MD` runtime because they must link
with `/MT`.

## Changes

- Add `SOGEN_STATIC_CRT` option (default: `OFF`)
- When `ON`, sets `CMAKE_MSVC_RUNTIME_LIBRARY` to static (`/MT` or
`/MTd`)
- Also respects parent project's `CMAKE_MSVC_RUNTIME_LIBRARY` if already
defined
- Includes documentation warning about heap allocation boundaries

## Backwards Compatibility

- Default behavior unchanged (`/MD`)
- Existing projects unaffected

## Usage

```bash
cmake -B build -DSOGEN_STATIC_CRT=ON
```

Or in parent CMakeLists.txt:
```cmake
set(SOGEN_STATIC_CRT ON CACHE BOOL "")
add_subdirectory(sogen)
```

## Test plan

- [x] Verified default build still uses `/MD`
- [x] Verified `-DSOGEN_STATIC_CRT=ON` produces `/MT` build
- [x] Tested with IDA Pro plugin project (emudbg) - links successfully
This commit is contained in:
Maurice Heumann
2025-12-06 08:22:42 +01:00
committed by GitHub
7 changed files with 35 additions and 12 deletions

View File

@@ -44,7 +44,7 @@ endif()
##########################################
option(MOMO_BUILD_AS_LIBRARY "Configure and Build the sogen as a shared library (without the samples and tests)" ${MOMO_IS_SUBPROJECT})
option(SOGEN_BUILD_STATIC "Build sogen as static libraries for embedding (e.g., IDA plugins)" ${MOMO_IS_SUBPROJECT})
##########################################

View File

@@ -31,10 +31,10 @@ endif()
##########################################
if(MOMO_BUILD_AS_LIBRARY)
add_compile_definitions(MOMO_BUILD_AS_LIBRARY=1)
if(SOGEN_BUILD_STATIC)
add_compile_definitions(SOGEN_BUILD_STATIC=1)
else()
add_compile_definitions(MOMO_BUILD_AS_LIBRARY=0)
add_compile_definitions(SOGEN_BUILD_STATIC=0)
endif()
##########################################
@@ -217,10 +217,33 @@ if(MOMO_ENABLE_SANITIZER)
endif()
##########################################
# Must be a dynamic runtime (/MD or /MDd) to enforce
# shared allocators between emulator and implementation
# MSVC Runtime Library Selection
#
# Default is dynamic runtime (/MD or /MDd) to enforce shared allocators
# between emulator and implementation.
#
# Use SOGEN_STATIC_CRT=ON for static runtime (/MT or /MTd) when embedding
# in projects that require it (e.g., IDA plugins).
#
# WARNING: Static CRT may cause heap corruption if memory is allocated
# in one module and freed in another. Ensure allocation ownership is clear.
set(CMAKE_MSVC_RUNTIME_LIBRARY MultiThreaded$<$<CONFIG:Debug>:Debug>DLL)
option(SOGEN_STATIC_CRT "Use static CRT (/MT) instead of dynamic (/MD)" OFF)
if(SOGEN_STATIC_CRT AND NOT SOGEN_BUILD_STATIC)
message(FATAL_ERROR
"SOGEN_STATIC_CRT=ON requires SOGEN_BUILD_STATIC=ON.\n"
"Static CRT with shared libraries causes heap corruption - "
"each DLL gets its own allocator, but sogen passes ownership across boundaries.")
endif()
if(SOGEN_STATIC_CRT)
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
elseif(DEFINED CMAKE_MSVC_RUNTIME_LIBRARY)
# Respect parent project's setting
else()
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
endif()
##########################################

View File

@@ -8,7 +8,7 @@ add_subdirectory(backend-selection)
momo_add_subdirectory_and_get_targets("backends" BACKEND_TARGETS)
momo_targets_set_folder("backends" ${BACKEND_TARGETS})
if (NOT MOMO_BUILD_AS_LIBRARY)
if (NOT SOGEN_BUILD_STATIC)
add_subdirectory(analyzer)
add_subdirectory(debugger)
add_subdirectory(fuzzing-engine)

View File

@@ -8,7 +8,7 @@ file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS
list(SORT SRC_FILES)
if(MOMO_BUILD_AS_LIBRARY)
if(SOGEN_BUILD_STATIC)
add_library(icicle-emulator STATIC ${SRC_FILES})
else()
add_library(icicle-emulator SHARED ${SRC_FILES})

View File

@@ -12,7 +12,7 @@
namespace icicle
{
#if !MOMO_BUILD_AS_LIBRARY
#if !SOGEN_BUILD_STATIC
ICICLE_EMULATOR_DLL_STORAGE
#endif
std::unique_ptr<x86_64_emulator> create_x86_64_emulator();

View File

@@ -6,7 +6,7 @@ file(GLOB_RECURSE SRC_FILES CONFIGURE_DEPENDS
list(SORT SRC_FILES)
if(MOMO_BUILD_AS_LIBRARY)
if(SOGEN_BUILD_STATIC)
add_library(unicorn-emulator STATIC ${SRC_FILES})
else()
add_library(unicorn-emulator SHARED ${SRC_FILES})

View File

@@ -12,7 +12,7 @@
namespace unicorn
{
#if !MOMO_BUILD_AS_LIBRARY
#if !SOGEN_BUILD_STATIC
UNICORN_EMULATOR_DLL_STORAGE
#endif
std::unique_ptr<x86_64_emulator> create_x86_64_emulator();