diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7a54df0..3187e53 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -354,15 +354,30 @@ if(APPLE AND ENABLE_MACOS_FRAMEWORK)
set(FRAMEWORK_NAME ChapterForge)
set(FRAMEWORK_DIR ${CMAKE_CURRENT_BINARY_DIR}/${FRAMEWORK_NAME}.framework)
set(FRAMEWORK_VER_DIR ${FRAMEWORK_DIR}/Versions/A)
+ set(FRAMEWORK_INFO_PLIST ${CMAKE_CURRENT_BINARY_DIR}/${FRAMEWORK_NAME}-Info.plist)
# Ship all public headers (developers can opt into lower-level APIs).
file(GLOB FRAMEWORK_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp)
+ # Generate the plist at configure time. A multiline echo inside the custom target produces
+ # invalid Makefiles because the generated recipe contains unindented lines.
+ file(WRITE ${FRAMEWORK_INFO_PLIST}
+ "\n"
+ "\n"
+ "\n"
+ "\n"
+ " CFBundleIdentifiercom.chapterforge\n"
+ " CFBundleNameChapterForge\n"
+ " CFBundleVersion${CHAPTERFORGE_VERSION_DISPLAY}\n"
+ " CFBundleShortVersionString${CHAPTERFORGE_VERSION_DISPLAY}\n"
+ "\n"
+ "\n")
+
add_custom_target(ChapterForgeFramework ALL
DEPENDS chapterforge ${FRAMEWORK_HEADERS}
COMMAND ${CMAKE_COMMAND} -E make_directory ${FRAMEWORK_VER_DIR}/Headers
COMMAND ${CMAKE_COMMAND} -E make_directory ${FRAMEWORK_VER_DIR}/Resources
- # Write a minimal Info.plist carrying our version strings.
- COMMAND ${CMAKE_COMMAND} -E echo "\n \n \n \n CFBundleIdentifiercom.chapterforge \n CFBundleNameChapterForge \n CFBundleVersion${CHAPTERFORGE_VERSION_DISPLAY} \n CFBundleShortVersionString${CHAPTERFORGE_VERSION_DISPLAY} \n \n" > ${FRAMEWORK_VER_DIR}/Resources/Info.plist
+ # Copy the generated Info.plist carrying our version strings.
+ COMMAND ${CMAKE_COMMAND} -E copy_if_different ${FRAMEWORK_INFO_PLIST} ${FRAMEWORK_VER_DIR}/Resources/Info.plist
# Copy the static lib into the bundle as the framework binary.
COMMAND ${CMAKE_COMMAND} -E copy $ ${FRAMEWORK_VER_DIR}/${FRAMEWORK_NAME}
# Copy public headers.