Kaynağa Gözat

CMake: cleanup, project generation and other improvements

- Use EXCLUDE_FROM_ALL for FuzzyLite and GoogleTest to avoid inclusion of unneded headers and libraries into installers.
- Set minimum CMake version only in main CMakeLists.txt
- Set project name only in main CMakeLists.txt
- Visual Studio: add assign_source_group function to generate proper filesystem tree
- Visual Studio: set PROJECT_LABEL so generated projects have same names binaries on Windows
- Visual Studio: enabled USE_FOLDERS for projects grouping. This also possibly affect other IDEs.
- Added add_subdirectory_with_folder function to make sure 3rd-party libraries are affected by USE_FOLDERS.
Arseniy Shestakov 8 yıl önce
ebeveyn
işleme
193f492b99

+ 5 - 5
AI/BattleAI/CMakeLists.txt

@@ -1,6 +1,3 @@
-project(battleAI)
-cmake_minimum_required(VERSION 2.6)
-
 include_directories(${Boost_INCLUDE_DIRS} ${CMAKE_HOME_DIRECTORY} ${CMAKE_HOME_DIRECTORY}/include ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_HOME_DIRECTORY}/lib)
 
 set(battleAI_SRCS
@@ -28,9 +25,12 @@ set(battleAI_HEADERS
 		ThreatMap.h
 )
 
-if (ANDROID) # android compiles ai libs into main lib directly, so we skip this library and just reuse sources list
+assign_source_group(${battleAI_SRCS} ${battleAI_HEADERS})
+
+if(ANDROID) # android compiles ai libs into main lib directly, so we skip this library and just reuse sources list
 	return()
 endif()
+
 add_library(BattleAI SHARED ${battleAI_SRCS} ${battleAI_HEADERS})
 target_link_libraries(BattleAI vcmi)
 
@@ -39,7 +39,7 @@ vcmi_set_output_dir(BattleAI "AI")
 set_target_properties(BattleAI PROPERTIES ${PCH_PROPERTIES})
 cotire(BattleAI)
 
-if (NOT APPLE) # Already inside vcmiclient bundle
+if(NOT APPLE) # Already inside vcmiclient bundle
 	install(TARGETS BattleAI RUNTIME DESTINATION ${AI_LIB_DIR} LIBRARY DESTINATION ${AI_LIB_DIR})
 endif()
 

+ 9 - 11
AI/CMakeLists.txt

@@ -1,21 +1,19 @@
-project(AI)
-cmake_minimum_required(VERSION 2.8)
-
 option(FORCE_BUNDLED_FL "Force to use FuzzyLite included into VCMI's source tree" OFF)
 
-if (NOT FORCE_BUNDLED_FL)
+if(NOT FORCE_BUNDLED_FL)
 	find_package(FuzzyLite)
 else()
 	set(FL_FOUND FALSE)
 endif()
 
-if (NOT FL_FOUND)
+if(NOT FL_FOUND)
     set(FL_BUILD_BINARY OFF CACHE BOOL "")
     set(FL_BUILD_SHARED OFF CACHE BOOL "")
-    set(FL_BUILD_TESTS OFF CACHE BOOL "")
-    add_subdirectory(FuzzyLite/fuzzylite)
+	set(FL_BUILD_TESTS OFF CACHE BOOL "")
+	add_subdirectory_with_folder("AI" FuzzyLite/fuzzylite EXCLUDE_FROM_ALL)
 endif()
-add_subdirectory(BattleAI)
-add_subdirectory(StupidAI)
-add_subdirectory(EmptyAI)
-add_subdirectory(VCAI)
+
+add_subdirectory_with_folder("AI" BattleAI)
+add_subdirectory_with_folder("AI" StupidAI)
+add_subdirectory_with_folder("AI" EmptyAI)
+add_subdirectory_with_folder("AI" VCAI)

+ 6 - 5
AI/EmptyAI/CMakeLists.txt

@@ -1,6 +1,3 @@
-project(emptyAI)
-cmake_minimum_required(VERSION 2.6)
-
 include_directories(${Boost_INCLUDE_DIRS} ${CMAKE_HOME_DIRECTORY} ${CMAKE_HOME_DIRECTORY}/include ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_HOME_DIRECTORY}/lib)
 
 set(emptyAI_SRCS
@@ -16,11 +13,15 @@ set(emptyAI_HEADERS
 		CEmptyAI.h
 )
 
+assign_source_group(${emptyAI_SRCS} ${emptyAI_HEADERS})
+
 add_library(EmptyAI SHARED ${emptyAI_SRCS} ${emptyAI_HEADERS})
 target_link_libraries(EmptyAI vcmi)
 
 vcmi_set_output_dir(EmptyAI "AI")
 
-if (NOT APPLE) # Already inside vcmiclient bundle
+set_target_properties(EmptyAI PROPERTIES ${PCH_PROPERTIES})
+
+if(NOT APPLE) # Already inside vcmiclient bundle
     install(TARGETS EmptyAI RUNTIME DESTINATION ${AI_LIB_DIR} LIBRARY DESTINATION ${AI_LIB_DIR})
-endif()
+endif(NOT APPLE)

+ 4 - 5
AI/StupidAI/CMakeLists.txt

@@ -1,6 +1,3 @@
-project(stupidAI)
-cmake_minimum_required(VERSION 2.6)
-
 include_directories(${Boost_INCLUDE_DIRS} ${CMAKE_HOME_DIRECTORY} ${CMAKE_HOME_DIRECTORY}/include ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_HOME_DIRECTORY}/lib)
 
 set(stupidAI_SRCS
@@ -16,6 +13,8 @@ set(stupidAI_HEADERS
 		StupidAI.h
 )
 
+assign_source_group(${stupidAI_SRCS} ${stupidAI_HEADERS})
+
 add_library(StupidAI SHARED ${stupidAI_SRCS} ${stupidAI_HEADERS})
 target_link_libraries(StupidAI vcmi)
 
@@ -24,7 +23,7 @@ vcmi_set_output_dir(StupidAI "AI")
 set_target_properties(StupidAI PROPERTIES ${PCH_PROPERTIES})
 cotire(StupidAI)
 
-if (NOT APPLE) # Already inside vcmiclient bundle
-    install(TARGETS StupidAI RUNTIME DESTINATION ${AI_LIB_DIR} LIBRARY DESTINATION ${AI_LIB_DIR})
+if(NOT APPLE) # Already inside vcmiclient bundle
+	install(TARGETS StupidAI RUNTIME DESTINATION ${AI_LIB_DIR} LIBRARY DESTINATION ${AI_LIB_DIR})
 endif()
 

+ 7 - 8
AI/VCAI/CMakeLists.txt

@@ -1,10 +1,7 @@
-project(VCAI)
-cmake_minimum_required(VERSION 2.6)
-
-if (FL_FOUND)
-    include_directories(${FL_INCLUDE_DIRS})
+if(FL_FOUND)
+	include_directories(${FL_INCLUDE_DIRS})
 else()
-    include_directories(${CMAKE_HOME_DIRECTORY}/AI/FuzzyLite/fuzzylite)
+	include_directories(${CMAKE_HOME_DIRECTORY}/AI/FuzzyLite/fuzzylite)
 endif()
 include_directories(${Boost_INCLUDE_DIRS} ${CMAKE_HOME_DIRECTORY} ${CMAKE_HOME_DIRECTORY}/include ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_HOME_DIRECTORY}/lib)
 
@@ -27,7 +24,9 @@ set(VCAI_HEADERS
 		VCAI.h
 )
 
-if (ANDROID) # android compiles ai libs into main lib directly, so we skip this library and just reuse sources list
+assign_source_group(${VCAI_SRCS} ${VCAI_HEADERS})
+
+if(ANDROID) # android compiles ai libs into main lib directly, so we skip this library and just reuse sources list
 	return()
 endif()
 
@@ -43,6 +42,6 @@ vcmi_set_output_dir(VCAI "AI")
 set_target_properties(VCAI PROPERTIES ${PCH_PROPERTIES})
 cotire(VCAI)
 
-if (NOT APPLE) # Already inside vcmiclient bundle
+if(NOT APPLE) # Already inside vcmiclient bundle
 	install(TARGETS VCAI RUNTIME DESTINATION ${AI_LIB_DIR} LIBRARY DESTINATION ${AI_LIB_DIR})
 endif()

+ 74 - 116
CMakeLists.txt

@@ -1,27 +1,19 @@
-project(vcmi)
-cmake_minimum_required(VERSION 2.8.12)
-# TODO:
-# 1) Detection of Qt5 and compilation of launcher, unless explicitly disabled
+project(VCMI)
 
-# where to look for cmake modules
-set(CMAKE_MODULE_PATH ${CMAKE_HOME_DIRECTORY}/cmake_modules)
+if(NOT CMAKE_BUILD_TYPE)
+	set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING
+		"Choose the type of build, options are: Debug Release RelWithDebInfo. Default is RelWithDebInfo."
+		FORCE)
+	set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release RelWithDebInfo)
+endif()
 
+set(CMAKE_MODULE_PATH ${CMAKE_HOME_DIRECTORY}/cmake_modules)
 include(VCMIUtils)
 
-# enable Release mode but only if it was not set
-if (NOT CMAKE_BUILD_TYPE)
-		set(CMAKE_BUILD_TYPE RelWithDebInfo)
-endif()
-
-# VCMI version
 set(VCMI_VERSION_MAJOR 0)
 set(VCMI_VERSION_MINOR 99)
 set(VCMI_VERSION_PATCH 0)
 
-# Allow to pass package name from Travis CI
-set(PACKAGE_NAME_SUFFIX "" CACHE STRING "Suffix for CPack package name")
-set(PACKAGE_FILE_NAME "" CACHE STRING "Override for CPack package filename")
-
 option(ENABLE_ERM "Enable compilation of ERM scripting module" OFF)
 option(ENABLE_LAUNCHER "Enable compilation of launcher" ON)
 option(ENABLE_TEST "Enable compilation of unit tests" ON)
@@ -29,6 +21,23 @@ option(ENABLE_PCH "Enable compilation using precompiled headers" ON)
 # TODO: default to ON when we start distributing macOS binaries
 option(ENABLE_SPARKLE "Enable auto-updating with Sparkle on macOS" OFF)
 
+# Allow to pass package name from Travis CI
+set(PACKAGE_NAME_SUFFIX "" CACHE STRING "Suffix for CPack package name")
+set(PACKAGE_FILE_NAME "" CACHE STRING "Override for CPack package filename")
+
+if(ENABLE_PCH)
+	# Cotire require CMake 2.8.12
+	cmake_minimum_required(VERSION 2.8.12)
+elseif(ENABLE_LAUNCHER)
+	# Some of Qt5 linking policies require 2.8.11
+	cmake_minimum_required(VERSION 2.8.11)
+elseif(ENABLE_TEST)
+	# For whatever reason test requirement is 2.8.7
+	cmake_minimum_required(VERSION 2.8.7)
+else()
+	cmake_minimum_required(VERSION 2.6)
+endif()
+
 ############################################
 #        Documentation section             #
 ############################################
@@ -39,41 +48,7 @@ include(UseDoxygen OPTIONAL)
 #        Building section                  #
 ############################################
 
-if (APPLE)
-	# Default location for thirdparty libs
-	set(CMAKE_INCLUDE_PATH "../include" "${CMAKE_OSX_SYSROOT}/usr/include")
-	set(CMAKE_LIBRARY_PATH "../lib")
-	set(CMAKE_FRAMEWORK_PATH "../Frameworks")
-	set(BOOST_ROOT "../")
-
-	set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin")
-	set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin")
-	set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin")
-
-	set(CMAKE_XCODE_ATTRIBUTE_CONFIGURATION_BUILD_DIR "${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)")
-	set(CMAKE_XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks @executable_path/")
-
-	# Build with clang ang libc++
-	set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
-	set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
-
-  if(ENABLE_SPARKLE)
-    # so that OSX_checkForUpdates knows whether to be a noop
-    add_definitions(-DSPARKLE)
-
-    # On OS X we use Sparkle framework for updates
-    find_path(SPARKLE_INCLUDE_DIR Sparkle.h)
-    find_library(SPARKLE_FRAMEWORK NAMES Sparkle)
-  endif()
-
-	# Xcode 5.0 fix
-	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=256")
-
-	# Link with iconv
-	set(SYSTEM_LIBS ${SYSTEM_LIBS} libiconv.dylib)
-endif()
-
-if (WIN32)
+if(WIN32)
 	add_definitions(-DBOOST_THREAD_USE_LIB)
 	# Windows Vista or newer for FuzzyLite 6 to compile
 	add_definitions(-D_WIN32_WINNT=0x0600)
@@ -90,12 +65,6 @@ if (WIN32)
 			set(SYSTEM_LIBS ${SYSTEM_LIBS} iconv)
 		endif()
 
-		#MinGW: copy runtime to VCMI location
-		get_filename_component(MINGW_BIN_PATH ${CMAKE_CXX_COMPILER} PATH )
-		set(dep_files ${dep_files} "${MINGW_BIN_PATH}/libwinpthread-*.dll")
-		set(dep_files ${dep_files} "${MINGW_BIN_PATH}/libgcc_s_*.dll")
-		set(dep_files ${dep_files} "${MINGW_BIN_PATH}/libstdc++-*.dll")
-
 		#MinGW: use O1 to prevent compiler crash in some cases
 		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O1")
 	endif()
@@ -113,7 +82,41 @@ if (WIN32)
 		add_definitions(-D_SCL_SECURE_NO_WARNINGS)
 		set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj /wd4251")
 	endif()
-endif()
+endif(WIN32)
+
+if(APPLE)
+	# Default location for thirdparty libs
+	set(CMAKE_INCLUDE_PATH "../include" "${CMAKE_OSX_SYSROOT}/usr/include")
+	set(CMAKE_LIBRARY_PATH "../lib")
+	set(CMAKE_FRAMEWORK_PATH "../Frameworks")
+	set(BOOST_ROOT "../")
+
+	set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin")
+	set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin")
+	set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_HOME_DIRECTORY}/bin")
+
+	set(CMAKE_XCODE_ATTRIBUTE_CONFIGURATION_BUILD_DIR "${CMAKE_HOME_DIRECTORY}/bin/$(CONFIGURATION)")
+	set(CMAKE_XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks @executable_path/")
+
+	# Build with clang ang libc++
+	set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LANGUAGE_STANDARD "c++11")
+	set(CMAKE_XCODE_ATTRIBUTE_CLANG_CXX_LIBRARY "libc++")
+
+	if(ENABLE_SPARKLE)
+		# so that OSX_checkForUpdates knows whether to be a noop
+		add_definitions(-DSPARKLE)
+
+		# On OS X we use Sparkle framework for updates
+		find_path(SPARKLE_INCLUDE_DIR Sparkle.h)
+		find_library(SPARKLE_FRAMEWORK NAMES Sparkle)
+	endif()
+
+	# Xcode 5.0 fix
+	set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth=256")
+
+	# Link with iconv
+	set(SYSTEM_LIBS ${SYSTEM_LIBS} libiconv.dylib)
+endif(APPLE)
 
 if(NOT WIN32)
 	INCLUDE(CheckLibraryExists)
@@ -132,7 +135,7 @@ find_package(Boost 1.48.0 COMPONENTS date_time filesystem locale program_options
 find_package(ZLIB REQUIRED)
 find_package(FFmpeg REQUIRED)
 find_package(Minizip)
-if (MINIZIP_FOUND)
+if(MINIZIP_FOUND)
     add_definitions(-DUSE_SYSTEM_MINIZIP)
 endif()
 
@@ -155,9 +158,6 @@ include(cotire)
 if(ENABLE_LAUNCHER)
 	# Widgets finds its own dependencies (QtGui and QtCore).
 	find_package(Qt5Widgets REQUIRED)
-endif()
-
-if (ENABLE_LAUNCHER)
 	find_package(Qt5Network REQUIRED)
 endif()
 
@@ -194,13 +194,13 @@ else()
 	# includes lib path which determines where to install shared libraries (either /lib or /lib64)
 	include(GNUInstallDirs)
 
-	if (NOT BIN_DIR)
+	if(NOT BIN_DIR)
 		set(BIN_DIR "bin" CACHE STRING "Where to install binaries")
 	endif()
-	if (NOT LIB_DIR)
+	if(NOT LIB_DIR)
 		set(LIB_DIR "${CMAKE_INSTALL_LIBDIR}/vcmi" CACHE STRING "Where to install main library")
 	endif()
-	if (NOT DATA_DIR)
+	if(NOT DATA_DIR)
 		set(DATA_DIR "share/vcmi" CACHE STRING "Where to install data files")
 	endif()
 endif()
@@ -223,18 +223,18 @@ SET(PCH_PROPERTIES
 	COTIRE_CXX_PREFIX_HEADER_INIT "StdInc.h"
 )
 
-if (ENABLE_ERM)
-		add_subdirectory(scripting/erm)
+if(ENABLE_ERM)
+	add_subdirectory(scripting/erm)
 endif()
-if (NOT MINIZIP_FOUND)
+if(NOT MINIZIP_FOUND)
 	add_subdirectory(lib/minizip)
 	set(MINIZIP_LIBRARIES minizip)
 endif()
 add_subdirectory(lib)
 add_subdirectory(client)
 add_subdirectory(server)
-add_subdirectory(AI)
-if (ENABLE_LAUNCHER)
+add_subdirectory_with_folder("AI" AI)
+if(ENABLE_LAUNCHER)
 	add_subdirectory(launcher)
 endif()
 if(ENABLE_TEST)
@@ -246,14 +246,14 @@ endif()
 #######################################
 
 # For apple these files will be already inside vcmiclient bundle
-if (NOT APPLE)
+if(NOT APPLE)
 	# copy whole directory but .svn control files
 	install(DIRECTORY config DESTINATION ${DATA_DIR})
 	# copy vcmi mod along with all its content
 	install(DIRECTORY Mods/vcmi DESTINATION ${DATA_DIR}/Mods)
 
 	# that script is useless for Windows
-	if (NOT WIN32)
+	if(NOT WIN32)
 		install(FILES vcmibuilder DESTINATION ${BIN_DIR} PERMISSIONS
 			OWNER_WRITE OWNER_READ OWNER_EXECUTE
 						GROUP_READ GROUP_EXECUTE
@@ -261,49 +261,7 @@ if (NOT APPLE)
 	endif()
 endif()
 
-if(WIN32)
-	file(GLOB dep_files
-		${dep_files}
-		"${CMAKE_FIND_ROOT_PATH}/bin/*.dll")
-
-	#Copy debug versions of libraries if build type is debug. Doesn't work in MSVC!
-	if(CMAKE_BUILD_TYPE MATCHES DEBUG)
-		set(debug_postfix d)
-	endif(CMAKE_BUILD_TYPE MATCHES DEBUG)
-
-	if(ENABLE_LAUNCHER)
-		get_target_property(QtCore_location Qt5::Core LOCATION)
-		get_filename_component(Qtbin_folder ${QtCore_location} PATH)
-		file(GLOB dep_files
-			${dep_files}
-			${Qtbin_folder}/Qt5Core${debug_postfix}.dll
-			${Qtbin_folder}/Qt5Gui${debug_postfix}.dll
-			${Qtbin_folder}/Qt5Widgets${debug_postfix}.dll
-			${Qtbin_folder}/icu*.dll)
-		file(GLOB dep_qwindows
-			${Qtbin_folder}/../plugins/platforms/qwindows${debug_postfix}.dll)
-		if(MSVC)
-			file(GLOB dep_files
-				${dep_files}
-				${Qtbin_folder}/libEGL.dll
-				${Qtbin_folder}/libGLESv2.dll)
-		endif()
-	endif()
-
-	if (ENABLE_LAUNCHER)
-		file(GLOB dep_files
-			${dep_files}
-			${Qtbin_folder}/Qt5Network${debug_postfix}.dll)
-	endif()
-
-	if(MSVC)
-		#install MSVC runtime
-		include(InstallRequiredSystemLibraries)
-		install(FILES ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} DESTINATION ${BIN_DIR})
-	endif()
-	install(FILES ${dep_files} DESTINATION ${BIN_DIR})
-	install(FILES ${dep_qwindows} DESTINATION ${BIN_DIR}/platforms)
-elseif(NOT APPLE)
+if(NOT WIN32 AND NOT APPLE)
 	#install icons and desktop file on Linux
 	#FIXME: move to client makefile?
 	install(FILES "${CMAKE_SOURCE_DIR}/client/icons/vcmiclient.64x64.png"   DESTINATION share/icons/hicolor/64x64/apps RENAME vcmiclient.png)
@@ -311,7 +269,7 @@ elseif(NOT APPLE)
 	install(FILES "${CMAKE_SOURCE_DIR}/client/icons/vcmiclient.32x32.png"   DESTINATION share/icons/hicolor/32x32/apps RENAME vcmiclient.png)
 	install(FILES "${CMAKE_SOURCE_DIR}/client/icons/vcmiclient.256x256.png" DESTINATION share/icons/hicolor/256x256/apps RENAME vcmiclient.png)
 	install(FILES "${CMAKE_SOURCE_DIR}/client/icons/vcmiclient.desktop"     DESTINATION share/applications)
-	if (ENABLE_LAUNCHER) #FIXME: move to launcher makefile?
+	if(ENABLE_LAUNCHER) #FIXME: move to launcher makefile?
 		install(FILES "${CMAKE_SOURCE_DIR}/launcher/vcmilauncher.desktop"     DESTINATION share/applications)
 	endif()
 endif()

+ 17 - 24
client/CMakeLists.txt

@@ -1,6 +1,3 @@
-project(vcmiclient)
-cmake_minimum_required(VERSION 2.6)
-
 include_directories(${CMAKE_HOME_DIRECTORY} ${CMAKE_HOME_DIRECTORY}/include ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_HOME_DIRECTORY}/lib)
 include_directories(${SDL_INCLUDE_DIR} ${SDLIMAGE_INCLUDE_DIR} ${SDLMIXER_INCLUDE_DIR} ${SDLTTF_INCLUDE_DIR})
 include_directories(${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR} ${FFMPEG_INCLUDE_DIRS})
@@ -116,30 +113,23 @@ set(client_HEADERS
 		SDLRWwrapper.h
 )
 
+assign_source_group(${client_SRCS} ${client_HEADERS} VCMI_client.rc)
+
 if(ANDROID) # android needs client/server to be libraries, not executables, so we can't reuse the build part of this script
 	return()
 endif()
 
-if(MSVC)
-	# workaround ffmpeg linking problems
-	set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
-	set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
-	set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} /SAFESEH:NO")
-endif()
-
 if(APPLE)
 	# OS X specific source files
 	set(client_SRCS ${client_SRCS} SDLMain.m Autoupdate.mm Info.plist vcmi.icns ../osx/vcmi_dsa_public.pem)
 
-  if(ENABLE_SPARKLE)
-    # OS X specific includes
-    include_directories(${SPARKLE_INCLUDE_DIR})
+	if(ENABLE_SPARKLE)
+		# OS X specific includes
+		include_directories(${SPARKLE_INCLUDE_DIR})
 
-    # OS X specific libraries
-    target_link_libraries(vcmiclient ${SPARKLE_FRAMEWORK})
-  endif()
-
-	add_executable(vcmiclient MACOSX_BUNDLE ${client_SRCS} ${client_HEADERS})
+		# OS X specific libraries
+		target_link_libraries(vcmiclient ${SPARKLE_FRAMEWORK})
+	endif()
 
 	# Because server and AI libs would be copies to bundle they need to be built before client
 	add_dependencies(vcmiclient vcmiserver VCAI EmptyAI StupidAI BattleAI minizip)
@@ -189,16 +179,19 @@ if(APPLE)
 	endif()
 
 	add_custom_command(TARGET vcmiclient POST_BUILD COMMAND ${MakeVCMIBundle})
-elseif(WIN32)
-	add_executable(vcmiclient ${client_SRCS} ${client_HEADERS} VCMI_client.rc)
-else()
-	add_executable(vcmiclient ${client_SRCS} ${client_HEADERS})
-endif()
+endif(APPLE)
 
 if(WIN32)
-	set_target_properties(vcmiclient PROPERTIES OUTPUT_NAME VCMI_client)
+	set(client_ICON VCMI_client.rc)
+	set_target_properties(vcmiclient
+		PROPERTIES
+			OUTPUT_NAME "VCMI_client"
+			PROJECT_LABEL "VCMI_client"
+	)
 endif()
 
+add_executable(vcmiclient WIN32 MACOSX_BUNDLE ${client_SRCS} ${client_HEADERS} ${client_ICON})
+
 target_link_libraries(vcmiclient vcmi ${Boost_LIBRARIES} ${SDL_LIBRARY} ${SDLIMAGE_LIBRARY} ${SDLMIXER_LIBRARY} ${SDLTTF_LIBRARY} ${ZLIB_LIBRARIES} ${FFMPEG_LIBRARIES} ${SYSTEM_LIBS})
 
 vcmi_set_output_dir(vcmiclient "")

+ 35 - 0
cmake_modules/VCMIUtils.cmake

@@ -16,3 +16,38 @@ macro(vcmi_set_output_dir name dir)
 	set_target_properties(${name} PROPERTIES LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/${dir})
 	set_target_properties(${name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/${dir})
 endmacro()
+
+#######################################
+#    Better Visual Studio solution    #
+#######################################
+
+function(assign_source_group)
+	foreach(_source IN ITEMS ${ARGN})
+		if(IS_ABSOLUTE "${_source}")
+			file(RELATIVE_PATH _source_rel "${CMAKE_CURRENT_SOURCE_DIR}" "${_source}")
+		else()
+			set(_source_rel "${_source}")
+		endif()
+		get_filename_component(_source_path "${_source_rel}" PATH)
+		string(REPLACE "/" "\\" _source_path_msvc "${_source_path}")
+		source_group("${_source_path_msvc}" FILES "${_source}")
+	endforeach()
+endfunction(assign_source_group)
+
+#######################################
+#    Setting folders for 3rd-party    #
+#######################################
+
+set_property(GLOBAL PROPERTY USE_FOLDERS TRUE)
+define_property(
+	TARGET
+	PROPERTY FOLDER
+	INHERITED
+	BRIEF_DOCS "Set the folder name."
+	FULL_DOCS  "Use to organize targets in an IDE."
+)
+
+function(add_subdirectory_with_folder _folder_name _folder)
+	add_subdirectory(${_folder} ${ARGN})
+	set_property(DIRECTORY "${_folder}" PROPERTY FOLDER "${_folder_name}")
+endfunction()

+ 67 - 55
launcher/CMakeLists.txt

@@ -1,64 +1,65 @@
-project(vcmilauncher)
-cmake_minimum_required(VERSION 2.8.7)
-
+# Detailed information about CMake compatibility available on Qt website
+# https://doc.qt.io/qt-5/cmake-manual.html
 include_directories(${CMAKE_HOME_DIRECTORY} ${CMAKE_HOME_DIRECTORY}/include ${CMAKE_CURRENT_SOURCE_DIR})
 include_directories(${ZLIB_INCLUDE_DIR} ${Boost_INCLUDE_DIRS} ${Qt5Widgets_INCLUDE_DIRS} ${Qt5Network_INCLUDE_DIRS})
 include_directories(${SDL_INCLUDE_DIR})
 
 set(launcher_modmanager_SRCS
-    modManager/cdownloadmanager_moc.cpp
-    modManager/cmodlist.cpp
-    modManager/cmodlistmodel_moc.cpp
-    modManager/cmodlistview_moc.cpp
-    modManager/cmodmanager.cpp
-    modManager/imageviewer_moc.cpp
+		modManager/cdownloadmanager_moc.cpp
+		modManager/cmodlist.cpp
+		modManager/cmodlistmodel_moc.cpp
+		modManager/cmodlistview_moc.cpp
+		modManager/cmodmanager.cpp
+		modManager/imageviewer_moc.cpp
 )
 
 set(launcher_modmanager_HEADERS
-	modManager/cdownloadmanager_moc.h
-	modManager/cmodlist.h
-	modManager/cmodlistmodel_moc.h
-	modManager/cmodlistview_moc.h
-	modManager/cmodmanager.h
-	modManager/imageviewer_moc.h
+		modManager/cdownloadmanager_moc.h
+		modManager/cmodlist.h
+		modManager/cmodlistmodel_moc.h
+		modManager/cmodlistview_moc.h
+		modManager/cmodmanager.h
+		modManager/imageviewer_moc.h
 )
 
 set(launcher_settingsview_SRCS
-    settingsView/csettingsview_moc.cpp
+		settingsView/csettingsview_moc.cpp
 )
 
 set(launcher_settingsview_HEADERS
-	settingsView/csettingsview_moc.h
+		settingsView/csettingsview_moc.h
 )
 
 set(launcher_SRCS
-    StdInc.cpp
-    ${launcher_modmanager_SRCS}
-    ${launcher_settingsview_SRCS}
-    main.cpp
-    mainwindow_moc.cpp
-    launcherdirs.cpp
-    jsonutils.cpp
-    sdldisplayquery.cpp
+		StdInc.cpp
+		${launcher_modmanager_SRCS}
+		${launcher_settingsview_SRCS}
+		main.cpp
+		mainwindow_moc.cpp
+		launcherdirs.cpp
+		jsonutils.cpp
+		sdldisplayquery.cpp
 )
 
 set(launcher_HEADERS
-    StdInc.h
-    ${launcher_modmanager_HEADERS}
-    ${launcher_settingsview_HEADERS}
-    mainwindow_moc.h
-    launcherdirs.h
-    jsonutils.h
-    sdldisplayquery.h
+		StdInc.h
+		${launcher_modmanager_HEADERS}
+		${launcher_settingsview_HEADERS}
+		mainwindow_moc.h
+		launcherdirs.h
+		jsonutils.h
+		sdldisplayquery.h
 )
 
 set(launcher_FORMS
-    modManager/cmodlistview_moc.ui
-    modManager/imageviewer_moc.ui
-    settingsView/csettingsview_moc.ui
-    mainwindow_moc.ui
+		modManager/cmodlistview_moc.ui
+		modManager/imageviewer_moc.ui
+		settingsView/csettingsview_moc.ui
+		mainwindow_moc.ui
 )
 
+assign_source_group(${launcher_SRCS} ${launcher_HEADERS} VCMI_launcher.rc)
+
 # Tell CMake to run moc when necessary:
 set(CMAKE_AUTOMOC ON)
 
@@ -66,40 +67,51 @@ set(CMAKE_AUTOMOC ON)
 # to always look for includes there:
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 
-# We need add -DQT_WIDGETS_LIB when using QtWidgets in Qt 5.
-add_definitions(${Qt5Widgets_DEFINITIONS})
-add_definitions(${Qt5Network_DEFINITIONS})
+#### We need add -DQT_WIDGETS_LIB when using QtWidgets in Qt 5.
+###add_definitions(${Qt5Widgets_DEFINITIONS})
+###add_definitions(${Qt5Network_DEFINITIONS})
 
-# Executables fail to build with Qt 5 in the default configuration
-# without -fPIE. We add that here.
-set(CMAKE_CXX_FLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS} ${CMAKE_CXX_FLAGS}")
+if("${CMAKE_VERSION}" VERSION_LESS 2.8.12)
+	# Executables fail to build with Qt 5 in the default configuration
+	# without -fPIE. We add that here.
+	set(CMAKE_CXX_FLAGS "${Qt5Widgets_EXECUTABLE_COMPILE_FLAGS} ${CMAKE_CXX_FLAGS}")
+endif()
 
 qt5_wrap_ui(launcher_UI_HEADERS ${launcher_FORMS})
 
 if(WIN32)
-	add_executable(vcmilauncher WIN32 ${launcher_SRCS} ${launcher_HEADERS} ${launcher_UI_HEADERS} VCMI_launcher.rc)
-	set_target_properties(vcmilauncher PROPERTIES OUTPUT_NAME VCMI_launcher)
-else()
-	add_executable(vcmilauncher ${launcher_SRCS} ${launcher_HEADERS} ${launcher_UI_HEADERS})
+	set(launcher_ICON VCMI_launcher.rc)
 endif()
 
-if(MSVC)
-	# Fix _WinMain@16 linking error
-	target_link_libraries(vcmilauncher vcmi ${Qt5Core_QTMAIN_LIBRARIES} ${Qt5Widgets_LIBRARIES} ${Qt5Network_LIBRARIES} ${SDL_LIBRARY})
-else()
-	# The Qt5Widgets_LIBRARIES variable also includes QtGui and QtCore
-	target_link_libraries(vcmilauncher vcmi ${Qt5Widgets_LIBRARIES} ${Qt5Network_LIBRARIES} ${SDL_LIBRARY})
+add_executable(vcmilauncher WIN32 ${launcher_SRCS} ${launcher_HEADERS} ${launcher_UI_HEADERS} ${launcher_ICON})
+
+if(WIN32)
+	set_target_properties(vcmilauncher
+		PROPERTIES
+			OUTPUT_NAME "VCMI_launcher"
+			PROJECT_LABEL "VCMI_launcher"
+	)
+
+	# FIXME: Can't to get CMP0020 working with Vcpkg and CMake 3.8.2
+	# So far I tried:
+	# - cmake_minimum_required set to 2.8.11 globally and in this file
+	# - cmake_policy in all possible places
+	# - used NO_POLICY_SCOPE to make sure no other parts reset policies
+	# Still nothing worked, warning kept appearing and WinMain didn't link automatically
+	target_link_libraries(vcmilauncher Qt5::WinMain)
 endif()
 
+target_link_libraries(vcmilauncher vcmi Qt5::Widgets Qt5::Network ${SDL_LIBRARY})
+
 vcmi_set_output_dir(vcmilauncher "")
 
 # temporary(?) disabled - generation of PCH takes too much time since cotire is trying to collect all Qt headers
 #set_target_properties(vcmilauncher PROPERTIES ${PCH_PROPERTIES})
 #cotire(vcmilauncher)
 
-if (NOT APPLE) # Already inside bundle
+if(NOT APPLE) # Already inside bundle
 	install(TARGETS vcmilauncher DESTINATION ${BIN_DIR})
-	# copy whole directory but .svn control files
-	install(DIRECTORY icons DESTINATION ${DATA_DIR}/launcher PATTERN ".svn" EXCLUDE)
+	# copy whole directory
+	install(DIRECTORY icons DESTINATION ${DATA_DIR}/launcher)
 endif()
 

+ 12 - 7
lib/CMakeLists.txt

@@ -1,6 +1,3 @@
-project(libvcmi)
-cmake_minimum_required(VERSION 2.6)
-
 include_directories(${CMAKE_HOME_DIRECTORY} ${CMAKE_HOME_DIRECTORY}/include ${CMAKE_CURRENT_SOURCE_DIRECTORY} ${CMAKE_HOME_DIRECTORY}/lib)
 include_directories(${Boost_INCLUDE_DIRS} ${SDL_INCLUDE_DIR} ${ZLIB_INCLUDE_DIR})
 
@@ -288,16 +285,24 @@ set(lib_HEADERS
 		VCMI_Lib.h
 )
 
+assign_source_group(${lib_SRCS} ${lib_HEADERS})
+
 add_library(vcmi SHARED ${lib_SRCS} ${lib_HEADERS})
-set_target_properties(vcmi PROPERTIES XCODE_ATTRIBUTE_LD_DYLIB_INSTALL_NAME "@rpath/libvcmi.dylib")
+if(APPLE)
+	set_target_properties(vcmi PROPERTIES XCODE_ATTRIBUTE_LD_DYLIB_INSTALL_NAME "@rpath/libvcmi.dylib")
+endif()
 set_target_properties(vcmi PROPERTIES COMPILE_DEFINITIONS "VCMI_DLL=1")
 target_link_libraries(vcmi ${MINIZIP_LIBRARIES} ${Boost_LIBRARIES} ${SDL_LIBRARY} ${ZLIB_LIBRARIES} ${SYSTEM_LIBS})
 
 if(WIN32)
-	set_target_properties(vcmi PROPERTIES OUTPUT_NAME VCMI_lib)
+	set_target_properties(vcmi
+		PROPERTIES
+			OUTPUT_NAME "VCMI_lib"
+			PROJECT_LABEL "VCMI_lib"
+	)
 endif()
 
-if (ANDROID)
+if(ANDROID)
 	return()
 endif()
 
@@ -306,6 +311,6 @@ vcmi_set_output_dir(vcmi "")
 set_target_properties(vcmi PROPERTIES ${PCH_PROPERTIES})
 cotire(vcmi)
 
-if (NOT APPLE) # Already inside vcmiclient bundle
+if(NOT APPLE) # Already inside vcmiclient bundle
 	install(TARGETS vcmi RUNTIME DESTINATION ${LIB_DIR} LIBRARY DESTINATION ${LIB_DIR})
 endif()

+ 0 - 1
lib/minizip/CMakeLists.txt

@@ -1,5 +1,4 @@
 project(minizip)
-cmake_minimum_required(VERSION 2.6)
 
 include_directories(${ZLIB_INCLUDE_DIR})
 

+ 0 - 3
scripting/erm/CMakeLists.txt

@@ -1,6 +1,3 @@
-project(vcmiERM)
-cmake_minimum_required(VERSION 2.6)
-
 include_directories(${CMAKE_HOME_DIRECTORY} ${CMAKE_HOME_DIRECTORY}/include ${CMAKE_CURRENT_SOURCE_DIRECTORY})
 
 set(lib_SRCS

+ 9 - 5
server/CMakeLists.txt

@@ -1,6 +1,3 @@
-project(vcmiserver)
-cmake_minimum_required(VERSION 2.6)
-
 include_directories(${CMAKE_HOME_DIRECTORY} ${CMAKE_HOME_DIRECTORY}/include ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_HOME_DIRECTORY}/lib)
 include_directories(${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR})
 
@@ -20,6 +17,9 @@ set(server_HEADERS
 		CQuery.h
 		CVCMIServer.h
 )
+
+assign_source_group(${server_SRCS} ${server_HEADERS})
+
 if(ANDROID) # android needs client/server to be libraries, not executables, so we can't reuse the build part of this script
 	return()
 endif()
@@ -29,7 +29,11 @@ add_executable(vcmiserver ${server_SRCS} ${server_HEADERS})
 target_link_libraries(vcmiserver vcmi ${Boost_LIBRARIES} ${SYSTEM_LIBS})
 
 if(WIN32)
-	set_target_properties(vcmiserver PROPERTIES OUTPUT_NAME VCMI_server)
+	set_target_properties(vcmiserver
+		PROPERTIES
+			OUTPUT_NAME "VCMI_server"
+			PROJECT_LABEL "VCMI_server"
+	)
 endif()
 
 vcmi_set_output_dir(vcmiserver "")
@@ -38,6 +42,6 @@ set_target_properties(vcmiserver PROPERTIES ${PCH_PROPERTIES})
 set_target_properties(vcmiserver PROPERTIES XCODE_ATTRIBUTE_LD_RUNPATH_SEARCH_PATHS "@executable_path/../Frameworks @executable_path/")
 cotire(vcmiserver)
 
-if (NOT APPLE) # Already inside vcmiclient bundle
+if(NOT APPLE) # Already inside vcmiclient bundle
 	install(TARGETS vcmiserver DESTINATION ${BIN_DIR})
 endif()

+ 10 - 11
test/CMakeLists.txt

@@ -1,16 +1,12 @@
-cmake_minimum_required(VERSION 2.8.7)
-
-project(test)
-
 enable_testing()
 
 set(googleTest_Dir ${CMAKE_CURRENT_SOURCE_DIR}/googletest)
-if (EXISTS ${googleTest_Dir})
+if(EXISTS ${googleTest_Dir})
     SET(GTestSrc ${googleTest_Dir}/googletest)
     SET(GMockSrc ${googleTest_Dir}/googlemock)
-else ()
-    message( FATAL_ERROR "No googletest src dir found!")
-endif ()
+else()
+	message(FATAL_ERROR "No googletest src dir found!")
+endif()
 include_directories(${GTestSrc} ${GTestSrc}/include ${GMockSrc} ${GMockSrc}/include)
 include_directories(${CMAKE_HOME_DIRECTORY} ${CMAKE_HOME_DIRECTORY}/include ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_HOME_DIRECTORY}/test)
 include_directories(${Boost_INCLUDE_DIRS} ${ZLIB_INCLUDE_DIR})
@@ -36,10 +32,13 @@ set(test_HEADERS
  		map/MapComparer.h
 )
 
+assign_source_group(${test_SRCS} ${test_HEADERS})
+
 set(mock_HEADERS
     mock/mock_UnitHealthInfo.h
 )
-add_subdirectory(googletest)
+
+add_subdirectory(googletest EXCLUDE_FROM_ALL)
 
 add_executable(vcmitest ${test_SRCS} ${test_HEADERS} ${mock_HEADERS} ${GTestSrc}/src/gtest-all.cc ${GMockSrc}/src/gmock-all.cc)
 target_link_libraries(vcmitest vcmi ${RT_LIB} ${DL_LIB})
@@ -62,7 +61,7 @@ set(vcmitest_FILES
 )
 
 foreach(file ${vcmitest_FILES})
-		add_custom_command(TARGET vcmitestFiles POST_BUILD
-				COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/${file}" ${CMAKE_CURRENT_BINARY_DIR}
+	add_custom_command(TARGET vcmitestFiles POST_BUILD
+		COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_SOURCE_DIR}/${file}" ${CMAKE_CURRENT_BINARY_DIR}
 	)
 endforeach()