aboutsummaryrefslogtreecommitdiff
path: root/CMakeLists.txt
diff options
context:
space:
mode:
authorSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-11 02:37:39 -0600
committerSulfurNitride <SulfurNitride@users.noreply.github.com>2026-02-11 02:37:39 -0600
commit7ee008e150bc5bcf76082d726f719ee0fdfda982 (patch)
tree27fb39be241fdb5ac2734c574de678977d1856d0 /CMakeLists.txt
Fluorine Manager: full Linux port of Mod Organizer 2
Complete native Linux port with FUSE-based virtual filesystem, Proton/umu-run integration, and Flatpak packaging. Key features: - FUSE VFS replacing Windows USVFS (in-process + standalone helper for Flatpak) - Proton/GE-Proton/umu-run launcher with env var forwarding - Flatpak support (sandbox-aware VFS, NXM handler, umu-run) - Wine prefix management UI - Case-insensitive path resolution for Linux filesystems - QSettings-safe INI handling (avoids Bethesda INI corruption) - Portable instance support with auto-generated launcher scripts Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'CMakeLists.txt')
-rw-r--r--CMakeLists.txt204
1 files changed, 204 insertions, 0 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..9a688f7
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,204 @@
+cmake_minimum_required(VERSION 3.16)
+project(ModOrganizer2 VERSION 2.5.3 LANGUAGES C CXX)
+
+set(CMAKE_CXX_STANDARD 23)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+set(CMAKE_POSITION_INDEPENDENT_CODE ON)
+set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
+
+# Prevent COPY relocations against protected Qt6 symbols on modern distros
+# (Fedora 41+, etc.) that set GNU_PROPERTY_1_NEEDED_INDIRECT_EXTERN_ACCESS.
+include(CheckCXXCompilerFlag)
+check_cxx_compiler_flag(-mno-direct-extern-access HAS_NO_DIRECT_EXTERN_ACCESS)
+if(HAS_NO_DIRECT_EXTERN_ACCESS)
+ add_compile_options(-mno-direct-extern-access)
+endif()
+
+option(BUILD_TESTING "Build tests" OFF)
+option(BUILD_NAK_FFI "Build NaK Rust FFI library" ON)
+option(BUILD_BSA_FFI "Build Rust BSA/BA2 FFI library" ON)
+option(BUILD_DOTNET_PLUGINS "Build C++/CLI .NET plugins (Windows+MSVC only)" OFF)
+option(BUILD_PLUGIN_PYTHON "Build plugin_python bridge on Linux" ON)
+
+# Compatibility helpers for upstream MO2 plugin repos that expect mo2-cmake.
+if(NOT COMMAND mo2_configure_plugin)
+ function(mo2_configure_plugin target)
+ cmake_parse_arguments(MO2 "NO_SOURCES" "" "" ${ARGN})
+
+ set_target_properties(${target} PROPERTIES
+ AUTOMOC ON
+ AUTOUIC ON
+ AUTORCC ON
+ CXX_STANDARD 23
+ CXX_STANDARD_REQUIRED ON
+ POSITION_INDEPENDENT_CODE ON
+ )
+
+ if(NOT MO2_NO_SOURCES)
+ file(GLOB _mo2_plugin_sources CONFIGURE_DEPENDS
+ ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp
+ ${CMAKE_CURRENT_SOURCE_DIR}/*.h
+ ${CMAKE_CURRENT_SOURCE_DIR}/*.ui
+ ${CMAKE_CURRENT_SOURCE_DIR}/*.qrc
+ )
+ if(_mo2_plugin_sources)
+ target_sources(${target} PRIVATE ${_mo2_plugin_sources})
+ endif()
+ endif()
+
+ target_compile_options(${target} PRIVATE
+ "-idirafter" "${CMAKE_SOURCE_DIR}/libs/uibase/include/uibase"
+ )
+ set_property(TARGET ${target} APPEND PROPERTY AUTOMOC_MOC_OPTIONS
+ "-I${CMAKE_SOURCE_DIR}/libs/uibase/include/uibase"
+ )
+ endfunction()
+endif()
+
+if(NOT COMMAND mo2_install_plugin)
+ function(mo2_install_plugin target)
+ install(TARGETS ${target}
+ LIBRARY DESTINATION plugins
+ )
+ endfunction()
+endif()
+
+if(NOT COMMAND mo2_default_source_group)
+ function(mo2_default_source_group)
+ # no-op
+ endfunction()
+endif()
+
+if(NOT COMMAND mo2_configure_target)
+ function(mo2_configure_target target)
+ set_target_properties(${target} PROPERTIES
+ AUTOMOC ON
+ AUTOUIC ON
+ AUTORCC ON
+ CXX_STANDARD 23
+ CXX_STANDARD_REQUIRED ON
+ POSITION_INDEPENDENT_CODE ON
+ )
+ target_compile_options(${target} PRIVATE
+ "-idirafter" "${CMAKE_SOURCE_DIR}/libs/uibase/include/uibase"
+ )
+ set_property(TARGET ${target} APPEND PROPERTY AUTOMOC_MOC_OPTIONS
+ "-I${CMAKE_SOURCE_DIR}/libs/uibase/include/uibase"
+ )
+ endfunction()
+endif()
+
+if(NOT COMMAND mo2_target_sources)
+ function(mo2_target_sources target)
+ set(_scope PRIVATE)
+ set(_out)
+ set(_skip_next OFF)
+ foreach(_arg IN LISTS ARGN)
+ if(_skip_next)
+ set(_skip_next OFF)
+ continue()
+ endif()
+ if(_arg STREQUAL "FOLDER")
+ set(_skip_next ON)
+ continue()
+ endif()
+ if(_arg STREQUAL "PRIVATE" OR _arg STREQUAL "PUBLIC" OR _arg STREQUAL "INTERFACE")
+ set(_scope "${_arg}")
+ continue()
+ endif()
+ list(APPEND _out "${_arg}")
+ endforeach()
+ if(_out)
+ target_sources(${target} ${_scope} ${_out})
+ endif()
+ endfunction()
+endif()
+
+if(NOT COMMAND mo2_find_python_executable)
+ function(mo2_find_python_executable out_var)
+ if(DEFINED Python_EXECUTABLE AND Python_EXECUTABLE)
+ set(${out_var} "${Python_EXECUTABLE}" PARENT_SCOPE)
+ return()
+ endif()
+ find_program(_mo2_python_exe NAMES python3 python)
+ set(${out_var} "${_mo2_python_exe}" PARENT_SCOPE)
+ endfunction()
+endif()
+
+if(NOT COMMAND mo2_add_translations)
+ function(mo2_add_translations)
+ # no-op on Linux port for now
+ endfunction()
+endif()
+
+if(NOT COMMAND mo2_python_install_pyqt)
+ function(mo2_python_install_pyqt)
+ # Use system/venv PyQt6 directly; no bundled wheel install step.
+ endfunction()
+endif()
+
+# Make dds-header findable by bsatk and libbsarch
+set(mo2-dds-header_DIR "${CMAKE_CURRENT_SOURCE_DIR}/libs/dds-header")
+
+# Sub-libraries in dependency order
+add_subdirectory(libs/esptk) # static lib, no deps
+add_subdirectory(libs/bsatk) # static lib, needs dds-header + boost + zlib + lz4
+add_subdirectory(libs/libbsarch) # shared + static, needs dds-header
+add_subdirectory(libs/7zip) # builds 7z.so from source (Linux only)
+add_subdirectory(libs/archive) # shared lib, needs dl
+add_subdirectory(libs/lootcli) # executable, needs Qt6 + boost + libloot + curl
+add_subdirectory(libs/uibase) # shared lib, needs Qt6 + spdlog
+
+if(BUILD_NAK_FFI)
+ add_subdirectory(libs/nak_ffi)
+endif()
+
+if(BUILD_BSA_FFI)
+ add_subdirectory(libs/bsa_ffi)
+endif()
+
+if(BUILD_PLUGIN_PYTHON)
+ set(_mo2_pyvenv_python "${CMAKE_SOURCE_DIR}/build/pyvenv/bin/python")
+ if(EXISTS "${_mo2_pyvenv_python}")
+ set(Python_EXECUTABLE "${_mo2_pyvenv_python}" CACHE FILEPATH
+ "Python executable for plugin_python build" FORCE)
+ set(pybind11_DIR
+ "${CMAKE_SOURCE_DIR}/build/pyvenv/lib/python3.14/site-packages/pybind11/share/cmake/pybind11"
+ CACHE PATH "pybind11 cmake dir for plugin_python" FORCE)
+ set(MO2_PYLIBS_DIR "${CMAKE_SOURCE_DIR}/build/pyvenv"
+ CACHE PATH "Python runtime root for plugin_python" FORCE)
+ endif()
+ add_subdirectory(libs/plugin_python)
+endif()
+
+# Game plugin chain: features (headers) → gamebryo (static) → creation (static) → game .so plugins
+add_subdirectory(libs/game_features)
+add_subdirectory(libs/game_bethesda)
+add_subdirectory(libs/installer_fomod)
+add_subdirectory(libs/installer_bain)
+add_subdirectory(libs/installer_bundle)
+add_subdirectory(libs/installer_manual)
+add_subdirectory(libs/installer_quick)
+add_subdirectory(libs/preview_base)
+add_subdirectory(libs/preview_bsa)
+add_subdirectory(libs/bsa_extractor)
+add_subdirectory(libs/bsapacker)
+add_subdirectory(libs/diagnose_basic)
+add_subdirectory(libs/check_fnis)
+add_subdirectory(libs/tool_inibakery)
+add_subdirectory(libs/tool_inieditor)
+
+if(BUILD_DOTNET_PLUGINS)
+ if(WIN32 AND MSVC)
+ add_subdirectory(libs/installer_fomod_csharp)
+ add_subdirectory(libs/installer_omod)
+ else()
+ message(WARNING
+ "BUILD_DOTNET_PLUGINS was enabled, but installer_fomod_csharp/installer_omod "
+ "are C++/CLI targets that require Windows + MSVC. Skipping on this platform."
+ )
+ endif()
+endif()
+
+# Main organizer executable
+add_subdirectory(src/src)