diff options
| author | kasull <qsullian@gmail.com> | 2026-02-24 06:45:56 -0500 |
|---|---|---|
| committer | kasull <qsullian@gmail.com> | 2026-02-24 06:45:56 -0500 |
| commit | d97e17b180257f3425574eb3ba4189d312eb590a (patch) | |
| tree | 97c8ea7b10158d8558e50d7150989082600c3493 | |
| parent | 3af651e5b65f51d9296c7a1a8ffc8adae6299f28 (diff) | |
enforce static Windows linkage and remove runtime DLL copy step
| -rw-r--r-- | CMakeLists.txt | 113 | ||||
| -rw-r--r-- | cmake/copy_runtime_deps.cmake | 123 |
2 files changed, 83 insertions, 153 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index f3638cb..561d10c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,49 +20,95 @@ pkg_check_modules(FREETYPE REQUIRED freetype2) pkg_check_modules(GLEW REQUIRED glew) find_package(OpenGL REQUIRED) + # release build settings set(CMAKE_CXX_FLAGS_RELEASE "-O3 -Wno-nontrivial-memcall") # debug build settings -set(CMAKE_CXX_FLAGS_DEBUG "-g -DDEBUG=1 -fsanitize=address -Wno-nontrivial-memcall") - -target_include_directories(app PRIVATE - ${SDL2_INCLUDE_DIRS} - ${FREETYPE_INCLUDE_DIRS} - ${GLEW_INCLUDE_DIRS} - ${OPENGL_INCLUDE_DIR} -) +if(WIN32) + set(CMAKE_CXX_FLAGS_DEBUG "-g -DDEBUG=1 -Wno-nontrivial-memcall") +else() + set(CMAKE_CXX_FLAGS_DEBUG "-g -DDEBUG=1 -fsanitize=address -Wno-nontrivial-memcall") +endif() # Platform-specific linking if(WIN32) + function(resolve_static_archives OUT_VAR LIB_DIRS_VAR LIBS_VAR) + set(_resolved "") + foreach(_lib IN LISTS ${LIBS_VAR}) + if(IS_ABSOLUTE "${_lib}") + set(_archive_path "${_lib}") + else() + if(_lib MATCHES "^-") + message(FATAL_ERROR "Unexpected link flag in static library list: ${_lib}") + endif() + + find_file( + _archive_path + NAMES "lib${_lib}.a" "${_lib}.a" + PATHS ${${LIB_DIRS_VAR}} + NO_DEFAULT_PATH + ) + if(NOT _archive_path) + message(FATAL_ERROR "Could not find static archive for '${_lib}' in: ${${LIB_DIRS_VAR}}") + endif() + endif() + + string(TOLOWER "${_archive_path}" _archive_path_lower) + if(NOT _archive_path_lower MATCHES "\\.a$" OR _archive_path_lower MATCHES "\\.dll\\.a$") + message(FATAL_ERROR "Expected static archive (.a), got: ${_archive_path}") + endif() + + list(APPEND _resolved "${_archive_path}") + unset(_archive_path CACHE) + endforeach() + + set(${OUT_VAR} "${_resolved}" PARENT_SCOPE) + endfunction() + + set(SDL2_INCLUDE_DIRS ${SDL2_STATIC_INCLUDE_DIRS}) + set(FREETYPE_INCLUDE_DIRS ${FREETYPE_STATIC_INCLUDE_DIRS}) + set(GLEW_INCLUDE_DIRS ${GLEW_STATIC_INCLUDE_DIRS}) + + resolve_static_archives( + SDL2_LIBRARIES + SDL2_STATIC_LIBRARY_DIRS + SDL2_STATIC_LIBRARIES + ) + resolve_static_archives( + FREETYPE_LIBRARIES + FREETYPE_STATIC_LIBRARY_DIRS + FREETYPE_STATIC_LIBRARIES + ) + resolve_static_archives( + GLEW_LIBRARIES + GLEW_STATIC_LIBRARY_DIRS + GLEW_STATIC_LIBRARIES + ) + set(CXX_STDLIB_LIBRARY_DIRS + ${CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES} + ${SDL2_STATIC_LIBRARY_DIRS} + ) + set(CXX_STDLIB_LIBRARY_NAMES c++ c++abi unwind) + resolve_static_archives( + CXX_STDLIB_LIBRARIES + CXX_STDLIB_LIBRARY_DIRS + CXX_STDLIB_LIBRARY_NAMES + ) + foreach(APP_LINK_OPTION IN LISTS SDL2_STATIC_LDFLAGS_OTHER FREETYPE_STATIC_LDFLAGS_OTHER GLEW_STATIC_LDFLAGS_OTHER) + if(NOT APP_LINK_OPTION STREQUAL "") + set_property(TARGET app APPEND_STRING PROPERTY LINK_FLAGS " ${APP_LINK_OPTION}") + endif() + endforeach() + + target_compile_definitions(app PRIVATE GLEW_STATIC) target_link_libraries(app PRIVATE ${SDL2_LIBRARIES} ${FREETYPE_LIBRARIES} ${GLEW_LIBRARIES} + ${CXX_STDLIB_LIBRARIES} ${OPENGL_LIBRARIES} winmm # For timeGetDevCaps, timeBeginPeriod, timeEndPeriod ) - - set(TOOLCHAIN_BIN_DIR "") - if(CMAKE_CXX_COMPILER) - get_filename_component(TOOLCHAIN_BIN_DIR "${CMAKE_CXX_COMPILER}" DIRECTORY) - endif() - if(NOT TOOLCHAIN_BIN_DIR OR TOOLCHAIN_BIN_DIR STREQUAL ".") - find_program(CLANGXX_PATH NAMES clang++ clang++.exe) - if(CLANGXX_PATH) - get_filename_component(TOOLCHAIN_BIN_DIR "${CLANGXX_PATH}" DIRECTORY) - endif() - endif() - - add_custom_command( - TARGET app - POST_BUILD - COMMAND "${CMAKE_COMMAND}" - -DAPP_EXE=$<TARGET_FILE:app> - -DAPP_OUT_DIR=$<TARGET_FILE_DIR:app> - -DTOOLCHAIN_BIN_DIR=${TOOLCHAIN_BIN_DIR} - -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/copy_runtime_deps.cmake - VERBATIM - ) else() target_link_libraries(app PRIVATE ${SDL2_LIBRARIES} @@ -72,6 +118,13 @@ else() ) endif() +target_include_directories(app PRIVATE + ${SDL2_INCLUDE_DIRS} + ${FREETYPE_INCLUDE_DIRS} + ${GLEW_INCLUDE_DIRS} + ${OPENGL_INCLUDE_DIR} +) + target_compile_options(app PRIVATE -Wall) target_compile_options(app PRIVATE -Wno-nontrivial-memcall) diff --git a/cmake/copy_runtime_deps.cmake b/cmake/copy_runtime_deps.cmake deleted file mode 100644 index 9317e74..0000000 --- a/cmake/copy_runtime_deps.cmake +++ /dev/null @@ -1,123 +0,0 @@ -if(NOT DEFINED APP_EXE OR NOT DEFINED APP_OUT_DIR) - message(FATAL_ERROR "APP_EXE and APP_OUT_DIR must be set") -endif() - -if(NOT EXISTS "${APP_EXE}") - message(FATAL_ERROR "Executable not found: ${APP_EXE}") -endif() - -set(_search_dirs "") -if((NOT DEFINED TOOLCHAIN_BIN_DIR OR TOOLCHAIN_BIN_DIR STREQUAL "") AND EXISTS "${APP_OUT_DIR}/CMakeCache.txt") - file( - STRINGS "${APP_OUT_DIR}/CMakeCache.txt" - _compiler_line - REGEX "^CMAKE_CXX_COMPILER:FILEPATH=" - LIMIT_COUNT 1 - ) - if(_compiler_line) - string(REPLACE "CMAKE_CXX_COMPILER:FILEPATH=" "" TOOLCHAIN_BIN_DIR "${_compiler_line}") - get_filename_component(TOOLCHAIN_BIN_DIR "${TOOLCHAIN_BIN_DIR}" DIRECTORY) - endif() -endif() - -if(DEFINED TOOLCHAIN_BIN_DIR AND NOT TOOLCHAIN_BIN_DIR STREQUAL "" AND EXISTS "${TOOLCHAIN_BIN_DIR}") - list(APPEND _search_dirs "${TOOLCHAIN_BIN_DIR}") -endif() - -if(NOT DEFINED TOOLCHAIN_BIN_DIR OR TOOLCHAIN_BIN_DIR STREQUAL "" OR NOT EXISTS "${TOOLCHAIN_BIN_DIR}") - message(FATAL_ERROR "TOOLCHAIN_BIN_DIR is required and must exist") -endif() - -file(TO_CMAKE_PATH "${TOOLCHAIN_BIN_DIR}" _toolchain_bin_dir_norm) -string(TOLOWER "${_toolchain_bin_dir_norm}" _toolchain_bin_dir_norm_lower) - -function(_literal_to_case_insensitive_regex _literal _out_var) - string(LENGTH "${_literal}" _len) - if(_len EQUAL 0) - set(${_out_var} "" PARENT_SCOPE) - return() - endif() - - set(_regex "") - math(EXPR _last "${_len} - 1") - foreach(_i RANGE 0 ${_last}) - string(SUBSTRING "${_literal}" ${_i} 1 _ch) - if(_ch MATCHES "[A-Za-z]") - string(TOUPPER "${_ch}" _up) - string(TOLOWER "${_ch}" _lo) - string(APPEND _regex "[${_up}${_lo}]") - elseif(_ch STREQUAL ".") - string(APPEND _regex "\\\\.") - else() - string(APPEND _regex "${_ch}") - endif() - endforeach() - - set(${_out_var} "${_regex}" PARENT_SCOPE) -endfunction() - -set(_pre_exclude_regexes - "^api-ms-win-.*" - "^ext-ms-.*" -) - -set(_windows_system_dlls - "KERNEL32.dll" - "USER32.dll" - "GDI32.dll" - "SHELL32.dll" - "WINMM.dll" - "OPENGL32.dll" - "ADVAPI32.dll" - "OLE32.dll" - "OLEAUT32.dll" - "COMDLG32.dll" - "WS2_32.dll" - "SECUR32.dll" - "NTDLL.dll" -) - -foreach(_dll IN LISTS _windows_system_dlls) - _literal_to_case_insensitive_regex("${_dll}" _dll_regex) - list(APPEND _pre_exclude_regexes "(^|.*[/\\\\])${_dll_regex}$") -endforeach() - -file(GET_RUNTIME_DEPENDENCIES - EXECUTABLES "${APP_EXE}" - RESOLVED_DEPENDENCIES_VAR _resolved_deps - UNRESOLVED_DEPENDENCIES_VAR _unresolved_deps - CONFLICTING_DEPENDENCIES_PREFIX _conflicting_deps - DIRECTORIES ${_search_dirs} - PRE_EXCLUDE_REGEXES ${_pre_exclude_regexes} - POST_EXCLUDE_REGEXES - ".*[/\\\\]Windows[/\\\\]System32[/\\\\].*" -) - -if(_unresolved_deps) - message(STATUS "Unresolved runtime dependencies: ${_unresolved_deps}") -endif() - -if(_conflicting_deps_FILENAMES) - message(STATUS "Conflicting runtime dependency names: ${_conflicting_deps_FILENAMES}") -endif() - -foreach(_dep IN LISTS _resolved_deps) - file(TO_CMAKE_PATH "${_dep}" _dep_norm) - string(TOLOWER "${_dep_norm}" _dep_norm_lower) - if(NOT _dep_norm_lower MATCHES "^${_toolchain_bin_dir_norm_lower}/") - continue() - endif() - - get_filename_component(_name "${_dep}" NAME) - if(_name STREQUAL "") - continue() - endif() - - execute_process( - COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${_dep}" "${APP_OUT_DIR}/${_name}" - RESULT_VARIABLE _copy_rc - ) - if(NOT _copy_rc EQUAL 0) - message(FATAL_ERROR "Failed to copy runtime dependency: ${_dep}") - endif() -endforeach() |
