Skip to content

Support multi configuration build tools (MSVC) with CMake #1229

Closed
@Torets

Description

@Torets

Godot version

4.1-dev

godot-cpp version

4.1

System information

Windows10

Issue description

When creating GDExtention C++ module using CMake, both Release and Debug configurations are linked against debug runtime libraries for MSVC, wich causes multiple errors like that:

LNK2038	mismatch detected for '_ITERATOR_DEBUG_LEVEL': value '2' doesn't match value '0' in ****.obj	
LNK2038	mismatch detected for 'RuntimeLibrary': value 'MDd_DynamicDebug' doesn't match value 'MD_DynamicRelease' in ****\.build\godot-cpp.windows.debug.64.lib(string.obj)

This happens because in CMakeLists.txt there is a static check for CMAKE_BUILD_TYPE, which is not used for multi-config build generators (MSVC, Ninja-MultiConfig, xcode) at this point of CMakeLists.txt

set(GODOT_COMPILE_FLAGS )

if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
	# using Visual Studio C++
	set(GODOT_COMPILE_FLAGS "/EHsc /utf-8") # /GF /MP

	if(CMAKE_BUILD_TYPE MATCHES Debug)
		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MDd") # /Od /RTC1 /Zi
	else()
		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MD /O2") # /Oy /GL /Gy
		STRING(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
		string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
	endif(CMAKE_BUILD_TYPE MATCHES Debug)

	add_definitions(-DNOMINMAX)
else()  # GCC/Clang
	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -g")

	if(CMAKE_BUILD_TYPE MATCHES Debug)
		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0")
	else()
		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -O3")
	endif(CMAKE_BUILD_TYPE MATCHES Debug)
endif()

Its better to use CMAKE_CXX_FLAGS_DEBUG, CMAKE_CXX_FLAGS_RELEASE etc for Release|Debug configurations without any condition on CMAKE_BUILD_TYPE, because it will break any multi-config generators (while using CMAKE_CXX_FLAGS_ is universal). Using CMAKE_CXX_FLAGS should be reserved for common flags: in the example of MSCV: "/EHsc /utf-8".

here is how I propose to change this segment (removed project-specific options, because it might be better to have same compile options for godot-cpp and GDExtention project):

diff -r  
84,85d83
< 
< set(GODOT_COMPILE_FLAGS )
89,97c87,90
< 	set(GODOT_COMPILE_FLAGS "/EHsc /utf-8") # /GF /MP
< 
< 	if(CMAKE_BUILD_TYPE MATCHES Debug)
< 		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MDd") # /Od /RTC1 /Zi
< 	else()
< 		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MD /O2") # /Oy /GL /Gy
< 		STRING(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
< 		string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
< 	endif(CMAKE_BUILD_TYPE MATCHES Debug)
---
> 	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc /utf-8") # /GF /MP
> 	set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MDd") # /Od /RTC1 /Zi
> 	set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MD /O2") # /Oy /GL /Gy
> 	STRING(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
100,107c93,98
< else()  # GCC/Clang
< 	set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -g")
< 
< 	if(CMAKE_BUILD_TYPE MATCHES Debug)
< 		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0")
< 	else()
< 		set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -O3")
< 	endif(CMAKE_BUILD_TYPE MATCHES Debug)
---
> elseif("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNUC" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")  # GCC/Clang
> 	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
> 	set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -O0")
> 	set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")
> else()
> 	message(FATAL_ERROR "godot-cpp supports only MSVC, GCC and Clang")
108a100,106
> 
> # make sure only debug and release are used, otherwise 
> # CMAKE_CXX_FLAGS_RELWITHDEBINFO and CMAKE_CXX_FLAGS_MINSIZEREL
> # should be supported in code above as well
> if(GENERATOR_IS_MULTI_CONFIG)
> 	set(CMAKE_CONFIGURATION_TYPES Debug Release)
> endif()
188c186
< set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS ${GODOT_COMPILE_FLAGS})
---
> # set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS ${GODOT_COMPILE_FLAGS})

Steps to reproduce

  1. Create any GDExtetion project with CMAKE and default settings
  2. Attempt to compile release configuration

Minimal reproduction project

N/A

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions