Fix MinGW build on Windows host system.

Close #1247. Close #1251.
This commit is contained in:
Yao Wei Tjong 姚伟忠 2016-03-17 22:58:27 +08:00
parent 8f4884f1fb
commit ccbc15f6a6
2 changed files with 81 additions and 89 deletions

View File

@ -79,37 +79,12 @@ macro (check_native_define REGEX OUTPUT_VAR)
endmacro ()
if (MSVC)
# On MSVC compiler, use the chosen CMake/VS generator to determine the ABI
# TODO: revisit this later because VS may use Clang as compiler in the future
if (CMAKE_CL_64)
set (NATIVE_64BIT 1)
endif ()
# On MSVC compiler, use the chosen CMake/VS generator to determine the ABI
set (NATIVE_64BIT ${CMAKE_CL_64})
# Determine MSVC compiler version based on CMake informational variables
if (NOT DEFINED COMPILER_VERSION)
# TODO: fix this ugly hardcoding that needs to be constantly maintained
if (MSVC_VERSION EQUAL 1200)
set (COMPILER_VERSION 6.0)
elseif (MSVC_VERSION EQUAL 1300)
set (COMPILER_VERSION 7.0)
elseif (MSVC_VERSION EQUAL 1310)
set (COMPILER_VERSION 7.1)
elseif (MSVC_VERSION EQUAL 1400)
set (COMPILER_VERSION 8.0)
elseif (MSVC_VERSION EQUAL 1500)
set (COMPILER_VERSION 9.0)
elseif (MSVC_VERSION EQUAL 1600)
set (COMPILER_VERSION 10.0)
elseif (MSVC_VERSION EQUAL 1700)
set (COMPILER_VERSION 11.0)
elseif (MSVC_VERSION EQUAL 1800)
set (COMPILER_VERSION 12.0)
elseif (MSVC_VERSION EQUAL 1900)
set (COMPILER_VERSION 14.0)
elseif (MSVC_VERSION GREATER 1900)
set (COMPILER_VERSION 14.0+)
else ()
set (COMPILER_VERSION 6.0-)
endif ()
string (REGEX REPLACE "^.*Visual Studio ([0-9]+\.[0-9]+).*$" \\1 COMPILER_VERSION "${CMAKE_C_COMPILER}") # Stringify for string replacement
set (COMPILER_VERSION ${COMPILER_VERSION} CACHE INTERNAL "MSVC Compiler version")
endif ()
else ()

View File

@ -70,6 +70,25 @@ if (NOT MSVC_VERSION GREATER 1600 OR MINGW) # MinGW meets both conditional c
if (MINGW)
# Intentionally searching for d3dcompiler(_XX) libraries in this particular order, avoiding unversioned d3dcompiler library so we know exactly which DLL to use
set (D3DCOMPILER_NAMES d3dcompiler_47 d3dcompiler_46 d3dcompiler_43 d3dcompiler_42)
if (NOT MINGW_SYSROOT)
if (DEFINED ENV{MINGW_SYSROOT})
file (TO_CMAKE_PATH $ENV{MINGW_SYSROOT} MINGW_SYSROOT)
else ()
execute_process (COMMAND ${CMAKE_COMMAND} -E echo "#include <d3dcompiler.h>" COMMAND ${CMAKE_C_COMPILER} -E -M - OUTPUT_FILE find_mingw_sysroot_output ERROR_QUIET)
file (STRINGS ${CMAKE_BINARY_DIR}/find_mingw_sysroot_output MINGW_SYSROOT REGEX d3dcompiler\.h)
string (REGEX REPLACE "^ *(.*)/include.*$" \\1 MINGW_SYSROOT "${MINGW_SYSROOT}") # Stringify for string replacement
string (REPLACE "\\ " " " MINGW_SYSROOT "${MINGW_SYSROOT}")
endif ()
if (NOT EXISTS ${MINGW_SYSROOT})
message (FATAL_ERROR "Could not find MinGW system root. "
"Use MINGW_SYSROOT environment variable or build option to specify the location of system root.")
endif ()
set (MINGW_SYSROOT ${MINGW_SYSROOT} CACHE PATH "Path to MinGW system root (MinGW on Windows host only)" FORCE)
endif ()
# MinGW Cross-compiling uses CMAKE_FIND_ROOT_PATH while MinGW on Windows host uses CMAKE_PREFIX_PATH
if (NOT CMAKE_FIND_ROOT_PATH OR CMAKE_HOST_WIN32)
set (CMAKE_PREFIX_PATH ${MINGW_SYSROOT})
endif ()
# MinGW does not need search paths as DirectX headers and libraries (when installed) are in its default search path
# However, we do not explicitly unset the DIRECTX_INC_SEARCH_PATHS and DIRECTX_LIB_SEARCH_PATHS variables here, so module user could set these two variables externally when for some reasons the DirectX headers and libraries are not installed in MinGW default search path
else ()
@ -98,40 +117,38 @@ if (NOT MSVC_VERSION GREATER 1600 OR MINGW) # MinGW meets both conditional c
set (CMAKE_REQUIRED_INCLUDES ${DIRECTX_INCLUDE_DIRS})
set (DIRECTX_LIBRARY_DIRS)
set (DIRECT3D_LIBRARIES)
if (NOT URHO3D_OPENGL)
find_library (DIRECTX_D3DCOMPILER NAMES ${D3DCOMPILER_NAMES} PATHS ${DIRECTX_LIB_SEARCH_PATHS} DOC "DirectX d3dcompiler library")
if (DIRECTX_D3DCOMPILER)
get_filename_component (NAME ${DIRECTX_D3DCOMPILER} NAME)
string (REGEX REPLACE "^.*(d3dcompiler[_0-9]*).*$" \\1 D3DCOMPILER_LIB_NAME ${NAME})
if (URHO3D_D3D11)
set (DIRECT3D_LIB_NAMES d3d11 dxgi dxguid)
find_library (DIRECTX_D3DCOMPILER NAMES ${D3DCOMPILER_NAMES} PATHS ${DIRECTX_LIB_SEARCH_PATHS} DOC "DirectX d3dcompiler library")
if (DIRECTX_D3DCOMPILER)
get_filename_component (NAME ${DIRECTX_D3DCOMPILER} NAME)
string (REGEX REPLACE "^.*(d3dcompiler[_0-9]*).*$" \\1 D3DCOMPILER_LIB_NAME ${NAME})
if (URHO3D_D3D11)
set (DIRECT3D_LIB_NAMES d3d11 dxgi dxguid)
else ()
set (DIRECT3D_LIB_NAMES d3d9)
endif ()
foreach (NAME ${D3DCOMPILER_LIB_NAME} ${DIRECT3D_LIB_NAMES})
string (REGEX REPLACE _[0-9]+$ "" BASE_NAME ${NAME})
string (TOUPPER ${BASE_NAME} UPCASE_NAME)
find_library (DIRECTX_${UPCASE_NAME} NAMES ${NAME} PATHS ${DIRECTX_LIB_SEARCH_PATHS} DOC "DirectX ${BASE_NAME} library")
if (DIRECTX_${UPCASE_NAME})
get_filename_component (PATH ${DIRECTX_${UPCASE_NAME}} PATH)
list (APPEND DIRECTX_LIBRARY_DIRS ${PATH}) # All the libs should be found in a same place, but just in case
list (APPEND DIRECT3D_LIBRARIES ${NAME})
else ()
set (DIRECT3D_LIB_NAMES d3d9)
set (MISSING_DIRECT3D_LIB TRUE)
endif ()
foreach (NAME ${D3DCOMPILER_LIB_NAME} ${DIRECT3D_LIB_NAMES})
string (REGEX REPLACE _[0-9]+$ "" BASE_NAME ${NAME})
string (TOUPPER ${BASE_NAME} UPCASE_NAME)
find_library (DIRECTX_${UPCASE_NAME} NAMES ${NAME} PATHS ${DIRECTX_LIB_SEARCH_PATHS} DOC "DirectX ${BASE_NAME} library")
if (DIRECTX_${UPCASE_NAME})
get_filename_component (PATH ${DIRECTX_${UPCASE_NAME}} PATH)
list (APPEND DIRECTX_LIBRARY_DIRS ${PATH}) # All the libs should be found in a same place, but just in case
list (APPEND DIRECT3D_LIBRARIES ${NAME})
else ()
set (MISSING_DIRECT3D_LIB TRUE)
endif ()
mark_as_advanced (DIRECTX_${UPCASE_NAME})
endforeach ()
if (NOT MISSING_DIRECT3D_LIB)
if (NOT MINGW)
set (USE_WINSDK_DIRECTX FALSE)
endif ()
set (HAVE_DIRECTX TRUE)
if (URHO3D_D3D11)
set (DirectX_D3D11_FOUND TRUE)
else ()
set (DirectX_D3D9_FOUND TRUE)
set (DirectX_D3D_FOUND TRUE)
endif ()
mark_as_advanced (DIRECTX_${UPCASE_NAME})
endforeach ()
if (NOT MISSING_DIRECT3D_LIB)
if (NOT MINGW)
set (USE_WINSDK_DIRECTX FALSE)
endif ()
set (HAVE_DIRECTX TRUE)
if (URHO3D_D3D11)
set (DirectX_D3D11_FOUND TRUE)
else ()
set (DirectX_D3D9_FOUND TRUE)
set (DirectX_D3D_FOUND TRUE)
endif ()
endif ()
endif ()
@ -149,37 +166,37 @@ endif ()
# Windows SDK can be used on VS2012 and above
if (MSVC_VERSION GREATER 1600 OR MINGW) # MinGW meets both conditional checks intentionally
if (NOT URHO3D_OPENGL)
if (MINGW)
# Search the corresponding DLL for the found d3dcompiler "import library"
set (DIRECT3D_DLL_NAMES ${D3DCOMPILER_LIB_NAME}.dll)
# Module user using older MinGW version could also prepopulate the DIRECT3D_DLL_REDIST_SEARCH_PATHS variable externally when the following search paths do not work, especially when older d3dcompiler_43.dll and d3dcompiler_42.dll is expected to be found elsewhere
if (MINGW)
# Search the corresponding DLL for the found d3dcompiler "import library"
set (DIRECT3D_DLL_NAMES ${D3DCOMPILER_LIB_NAME}.dll)
# Module user using older MinGW version could also prepopulate the DIRECT3D_DLL_REDIST_SEARCH_PATHS variable externally when the following search paths do not work, especially when older d3dcompiler_43.dll and d3dcompiler_42.dll is expected to be found elsewhere
else ()
set (DIRECT3D_DLL_NAMES d3dcompiler_47.dll d3dcompiler_46.dll)
set (DIRECT3D_DLL_REDIST_SEARCH_PATHS)
endif ()
foreach (VERSION 10.0 8.1 8.0)
list (APPEND DIRECT3D_DLL_REDIST_SEARCH_PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v${VERSION};InstallationFolder]/Redist/D3D/${PATH_SUFFIX}")
endforeach()
find_file (DIRECT3D_DLL NAMES ${DIRECT3D_DLL_NAMES} PATHS ${DIRECT3D_DLL_REDIST_SEARCH_PATHS} DOC "Direct3D DLL"
NO_DEFAULT_PATH) # Do not use default paths such as the PATH variable, to potentially avoid using a wrong architecture DLL
if (DIRECT3D_DLL AND NOT MINGW)
set (USE_WINSDK_DIRECTX TRUE)
set (HAVE_DIRECTX TRUE)
if (URHO3D_D3D11)
set (DIRECT3D_LIBRARIES d3dcompiler d3d11 dxgi dxguid)
set (DirectX_D3D11_FOUND TRUE)
else ()
set (DIRECT3D_DLL_NAMES d3dcompiler_47.dll d3dcompiler_46.dll)
set (DIRECT3D_DLL_REDIST_SEARCH_PATHS)
set (DIRECT3D_LIBRARIES d3dcompiler d3d9)
set (DirectX_D3D9_FOUND TRUE)
set (DirectX_D3D_FOUND TRUE)
endif ()
foreach (VERSION 10.0 8.1 8.0)
list (APPEND DIRECT3D_DLL_REDIST_SEARCH_PATHS "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\Microsoft SDKs\\Windows\\v${VERSION};InstallationFolder]/Redist/D3D/${PATH_SUFFIX}")
endforeach()
find_file (DIRECT3D_DLL NAMES ${DIRECT3D_DLL_NAMES} PATHS ${DIRECT3D_DLL_REDIST_SEARCH_PATHS} DOC "Direct3D DLL"
NO_DEFAULT_PATH) # Do not use default paths such as the PATH variable, to potentially avoid using a wrong architecture DLL
if (DIRECT3D_DLL AND NOT MINGW)
set (USE_WINSDK_DIRECTX TRUE)
set (HAVE_DIRECTX TRUE)
if (URHO3D_D3D11)
set (DIRECT3D_LIBRARIES d3dcompiler d3d11 dxgi dxguid)
set (DirectX_D3D11_FOUND TRUE)
else ()
set (DIRECT3D_LIBRARIES d3dcompiler d3d9)
set (DirectX_D3D9_FOUND TRUE)
set (DirectX_D3D_FOUND TRUE)
endif ()
# The headers and libraries are in Windows default search paths
unset (DIRECTX_INCLUDE_DIRS)
unset (DIRECTX_LIBRARY_DIRS)
set (FAIL_MESSAGE "Could NOT find DirectX using Windows SDK search paths")
endif ()
mark_as_advanced (DIRECT3D_DLL)
endif ()
mark_as_advanced (DIRECT3D_DLL)
# The headers and libraries are in default search paths for both Windows SDK and MinGW, so set the search path variables to empty now
set (DIRECTX_INCLUDE_DIRS "") # Need to be very explicit here because these variables are cached on MinGW, this is one way to reset the variables without losing the cached values
set (DIRECTX_LIBRARY_DIRS "")
if (NOT MINGW)
set (FAIL_MESSAGE "Could NOT find DirectX using Windows SDK search paths")
endif ()
endif ()