basics.cmake 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404
  1. # -----------------------------------------------------------------------------
  2. # Copyright (c) 2014 GarageGames, LLC
  3. #
  4. # Permission is hereby granted, free of charge, to any person obtaining a copy
  5. # of this software and associated documentation files (the "Software"), to
  6. # deal in the Software without restriction, including without limitation the
  7. # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. # sell copies of the Software, and to permit persons to whom the Software is
  9. # furnished to do so, subject to the following conditions:
  10. #
  11. # The above copyright notice and this permission notice shall be included in
  12. # all copies or substantial portions of the Software.
  13. #
  14. # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. # IN THE SOFTWARE.
  21. # -----------------------------------------------------------------------------
  22. project("Torque3DEngine")
  23. if( CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8 )
  24. set( TORQUE_CPU_X64 ON )
  25. elseif( CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 4 )
  26. set( TORQUE_CPU_X32 ON )
  27. endif()
  28. if(NOT TORQUE_TEMPLATE)
  29. set(TORQUE_TEMPLATE "Full" CACHE STRING "the template to use")
  30. endif()
  31. if(NOT TORQUE_APP_DIR)
  32. set(TORQUE_APP_DIR "${CMAKE_SOURCE_DIR}/My Projects/${TORQUE_APP_NAME}")
  33. endif()
  34. if(NOT projectOutDir)
  35. set(projectOutDir "${TORQUE_APP_DIR}/game")
  36. endif()
  37. if(NOT projectSrcDir)
  38. set(projectSrcDir "${TORQUE_APP_DIR}/source")
  39. endif()
  40. set(libDir "${CMAKE_SOURCE_DIR}/Engine/lib")
  41. set(srcDir "${CMAKE_SOURCE_DIR}/Engine/source")
  42. set(cmakeDir "${CMAKE_SOURCE_DIR}/Tools/CMake")
  43. # hide some things
  44. mark_as_advanced(CMAKE_INSTALL_PREFIX)
  45. mark_as_advanced(CMAKE_CONFIGURATION_TYPES)
  46. # output folders
  47. #set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${projectOutDir}/game)
  48. #set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${projectOutDir}/game)
  49. #set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${projectOutDir}/game)
  50. ###############################################################################
  51. ### Source File Handling
  52. ###############################################################################
  53. # finds and adds sources files in a folder
  54. macro(addPath dir)
  55. set(tmp_files "")
  56. set(glob_config GLOB)
  57. if(${ARGC} GREATER 1 AND "${ARGV1}" STREQUAL "REC")
  58. set(glob_config GLOB_RECURSE)
  59. endif()
  60. file(${glob_config} tmp_files
  61. ${dir}/*.cpp
  62. ${dir}/*.c
  63. ${dir}/*.cc
  64. ${dir}/*.h
  65. ${dir}/*.asm)
  66. LIST(APPEND ${PROJECT_NAME}_files "${tmp_files}")
  67. LIST(APPEND ${PROJECT_NAME}_paths "${dir}")
  68. #message(STATUS "addPath ${PROJECT_NAME} : ${tmp_files}")
  69. endmacro()
  70. # adds a file to the sources
  71. macro(addFile filename)
  72. LIST(APPEND ${PROJECT_NAME}_files "${filename}")
  73. #message(STATUS "addFile ${PROJECT_NAME} : ${filename}")
  74. endmacro()
  75. # finds and adds sources files in a folder recursively
  76. macro(addPathRec dir)
  77. addPath("${dir}" "REC")
  78. endmacro()
  79. ###############################################################################
  80. ### Definition Handling
  81. ###############################################################################
  82. macro(__addDef def config)
  83. # two possibilities: a) target already known, so add it directly, or b) target not yet known, so add it to its cache
  84. if(TARGET ${PROJECT_NAME})
  85. #message(STATUS "directly applying defs: ${PROJECT_NAME} with config ${config}: ${def}")
  86. if("${config}" STREQUAL "")
  87. set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "${def}")
  88. else()
  89. set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY COMPILE_DEFINITIONS_${config} "${def}")
  90. endif()
  91. else()
  92. list(APPEND ${PROJECT_NAME}_defs_${config} ${def})
  93. #message(STATUS "added definition to cache: ${PROJECT_NAME}_defs_${config}: ${${PROJECT_NAME}_defs_${config}}")
  94. endif()
  95. endmacro()
  96. # adds a definition: argument 1: Nothing(for all), _DEBUG, _RELEASE, <more build configurations>
  97. macro(addDef def)
  98. set(def_configs "")
  99. if(${ARGC} GREATER 1)
  100. foreach(config "${ARGV1}")
  101. __addDef(${def} ${config})
  102. endforeach()
  103. else()
  104. __addDef(${def} "")
  105. endif()
  106. endmacro()
  107. # this applies cached definitions onto the target
  108. macro(_process_defs)
  109. if(DEFINED ${PROJECT_NAME}_defs_)
  110. set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "${${PROJECT_NAME}_defs_}")
  111. #message(STATUS "applying defs to project ${PROJECT_NAME} on all configs: ${${PROJECT_NAME}_defs_}")
  112. endif()
  113. foreach(def_config ${CMAKE_CONFIGURATION_TYPES})
  114. string(TOUPPER "${def_config}" def_config)
  115. if(DEFINED ${PROJECT_NAME}_defs_${def_config})
  116. set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY COMPILE_DEFINITIONS_${def_config} "${${PROJECT_NAME}_defs_${def_config}}")
  117. #message(STATUS "applying defs to project ${PROJECT_NAME} on config ${def_config}: ${${PROJECT_NAME}_defs_${def_config}}")
  118. endif()
  119. endforeach()
  120. endmacro()
  121. ###############################################################################
  122. ### Source Library Handling
  123. ###############################################################################
  124. macro(addLibSrc libPath)
  125. set(cached_project_name ${PROJECT_NAME})
  126. include(${libPath})
  127. project(${cached_project_name})
  128. endmacro()
  129. ###############################################################################
  130. ### Linked Library Handling
  131. ###############################################################################
  132. macro(addLib libs)
  133. foreach(lib ${libs})
  134. # check if we can build it ourselfs
  135. if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/libraries/${lib}.cmake")
  136. addLibSrc("${CMAKE_CURRENT_SOURCE_DIR}/libraries/${lib}.cmake")
  137. endif()
  138. # then link against it
  139. # two possibilities: a) target already known, so add it directly, or b) target not yet known, so add it to its cache
  140. if(TARGET ${PROJECT_NAME})
  141. target_link_libraries(${PROJECT_NAME} "${lib}")
  142. else()
  143. list(APPEND ${PROJECT_NAME}_libs ${lib})
  144. endif()
  145. endforeach()
  146. endmacro()
  147. # this applies cached definitions onto the target
  148. macro(_process_libs)
  149. if(DEFINED ${PROJECT_NAME}_libs)
  150. target_link_libraries(${PROJECT_NAME} "${${PROJECT_NAME}_libs}")
  151. endif()
  152. endmacro()
  153. ###############################################################################
  154. ### Include Handling
  155. ###############################################################################
  156. macro(addInclude incPath)
  157. if(TARGET ${PROJECT_NAME})
  158. set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY INCLUDE_DIRECTORIES "${incPath}")
  159. else()
  160. list(APPEND ${PROJECT_NAME}_includes ${incPath})
  161. endif()
  162. endmacro()
  163. # this applies cached definitions onto the target
  164. macro(_process_includes)
  165. if(DEFINED ${PROJECT_NAME}_includes)
  166. set_property(TARGET ${PROJECT_NAME} APPEND PROPERTY INCLUDE_DIRECTORIES "${${PROJECT_NAME}_includes}")
  167. endif()
  168. endmacro()
  169. ###############################################################################
  170. macro(_postTargetProcess)
  171. _process_includes()
  172. _process_defs()
  173. _process_libs()
  174. endmacro()
  175. # adds a path to search for libs
  176. macro(addLibPath dir)
  177. link_directories(${dir})
  178. endmacro()
  179. # creates a proper filter for VS
  180. macro(generateFilters relDir)
  181. foreach(f ${${PROJECT_NAME}_files})
  182. # Get the path of the file relative to ${DIRECTORY},
  183. # then alter it (not compulsory)
  184. file(RELATIVE_PATH SRCGR ${relDir} ${f})
  185. set(SRCGR "${PROJECT_NAME}/${SRCGR}")
  186. # Extract the folder, ie remove the filename part
  187. string(REGEX REPLACE "(.*)(/[^/]*)$" "\\1" SRCGR ${SRCGR})
  188. # do not have any ../ dirs
  189. string(REPLACE "../" "" SRCGR ${SRCGR})
  190. # Source_group expects \\ (double antislash), not / (slash)
  191. string(REPLACE / \\ SRCGR ${SRCGR})
  192. #STRING(REPLACE "//" "/" SRCGR ${SRCGR})
  193. #message(STATUS "FILE: ${f} -> ${SRCGR}")
  194. source_group("${SRCGR}" FILES ${f})
  195. endforeach()
  196. endmacro()
  197. # creates a proper filter for VS
  198. macro(generateFiltersSpecial relDir)
  199. foreach(f ${${PROJECT_NAME}_files})
  200. # Get the path of the file relative to ${DIRECTORY},
  201. # then alter it (not compulsory)
  202. file(RELATIVE_PATH SRCGR ${relDir} ${f})
  203. set(SRCGR "torque3d/${SRCGR}")
  204. # Extract the folder, ie remove the filename part
  205. string(REGEX REPLACE "(.*)(/[^/]*)$" "\\1" SRCGR ${SRCGR})
  206. # do not have any ../ dirs
  207. string(REPLACE "../" "" SRCGR ${SRCGR})
  208. IF("${SRCGR}" MATCHES "^torque3d/My Projects/.*$")
  209. string(REPLACE "torque3d/My Projects/${PROJECT_NAME}/" "" SRCGR ${SRCGR})
  210. string(REPLACE "/source" "" SRCGR ${SRCGR})
  211. endif()
  212. # Source_group expects \\ (double antislash), not / (slash)
  213. string(REPLACE / \\ SRCGR ${SRCGR})
  214. #STRING(REPLACE "//" "/" SRCGR ${SRCGR})
  215. IF(EXISTS "${f}" AND NOT IS_DIRECTORY "${f}")
  216. #message(STATUS "FILE: ${f} -> ${SRCGR}")
  217. source_group("${SRCGR}" FILES ${f})
  218. endif()
  219. endforeach()
  220. endmacro()
  221. # macro to add a static library
  222. macro(finishLibrary)
  223. # more paths?
  224. if(${ARGC} GREATER 0)
  225. foreach(dir ${ARGV0})
  226. addPath("${dir}")
  227. endforeach()
  228. endif()
  229. # now inspect the paths we got
  230. set(firstDir "")
  231. foreach(dir ${${PROJECT_NAME}_paths})
  232. if("${firstDir}" STREQUAL "")
  233. set(firstDir "${dir}")
  234. endif()
  235. endforeach()
  236. generateFilters("${firstDir}")
  237. # set per target compile flags
  238. if(TORQUE_CXX_FLAGS_${PROJECT_NAME})
  239. set_source_files_properties(${${PROJECT_NAME}_files} PROPERTIES COMPILE_FLAGS "${TORQUE_CXX_FLAGS_${PROJECT_NAME}}")
  240. else()
  241. set_source_files_properties(${${PROJECT_NAME}_files} PROPERTIES COMPILE_FLAGS "${TORQUE_CXX_FLAGS_LIBS}")
  242. endif()
  243. if(TORQUE_STATIC)
  244. add_library("${PROJECT_NAME}" STATIC ${${PROJECT_NAME}_files})
  245. else()
  246. add_library("${PROJECT_NAME}" SHARED ${${PROJECT_NAME}_files})
  247. endif()
  248. # omg - only use the first folder ... otherwise we get lots of header name collisions
  249. #foreach(dir ${${PROJECT_NAME}_paths})
  250. addInclude("${firstDir}")
  251. #endforeach()
  252. _postTargetProcess()
  253. endmacro()
  254. # macro to add an executable
  255. macro(finishExecutable)
  256. # now inspect the paths we got
  257. set(firstDir "")
  258. foreach(dir ${${PROJECT_NAME}_paths})
  259. if("${firstDir}" STREQUAL "")
  260. set(firstDir "${dir}")
  261. endif()
  262. endforeach()
  263. generateFiltersSpecial("${firstDir}")
  264. # set per target compile flags
  265. if(TORQUE_CXX_FLAGS_${PROJECT_NAME})
  266. set_source_files_properties(${${PROJECT_NAME}_files} PROPERTIES COMPILE_FLAGS "${TORQUE_CXX_FLAGS_${PROJECT_NAME}}")
  267. else()
  268. set_source_files_properties(${${PROJECT_NAME}_files} PROPERTIES COMPILE_FLAGS "${TORQUE_CXX_FLAGS_EXECUTABLES}")
  269. endif()
  270. add_executable("${PROJECT_NAME}" WIN32 ${${PROJECT_NAME}_files})
  271. addInclude("${firstDir}")
  272. _postTargetProcess()
  273. endmacro()
  274. macro(setupVersionNumbers)
  275. set(TORQUE_APP_VERSION_MAJOR 1 CACHE INTEGER "")
  276. set(TORQUE_APP_VERSION_MINOR 0 CACHE INTEGER "")
  277. set(TORQUE_APP_VERSION_PATCH 0 CACHE INTEGER "")
  278. set(TORQUE_APP_VERSION_TWEAK 0 CACHE INTEGER "")
  279. mark_as_advanced(TORQUE_APP_VERSION_TWEAK)
  280. MATH(EXPR TORQUE_APP_VERSION "${TORQUE_APP_VERSION_MAJOR} * 1000 + ${TORQUE_APP_VERSION_MINOR} * 100 + ${TORQUE_APP_VERSION_PATCH} * 10 + ${TORQUE_APP_VERSION_TWEAK}")
  281. set(TORQUE_APP_VERSION_STRING "${TORQUE_APP_VERSION_MAJOR}.${TORQUE_APP_VERSION_MINOR}.${TORQUE_APP_VERSION_PATCH}.${TORQUE_APP_VERSION_TWEAK}")
  282. #message(STATUS "version numbers: ${TORQUE_APP_VERSION} / ${TORQUE_APP_VERSION_STRING}")
  283. endmacro()
  284. macro(setupPackaging)
  285. INCLUDE(CPack)
  286. # only enable zips for now
  287. set(CPACK_BINARY_NSIS OFF CACHE INTERNAL "" FORCE)
  288. set(CPACK_BINARY_ZIP ON CACHE INTERNAL "" FORCE)
  289. set(CPACK_SOURCE_ZIP OFF CACHE INTERNAL "" FORCE)
  290. SET(CPACK_GENERATOR "ZIP")
  291. SET(CPACK_PACKAGE_VENDOR "${PROJECT_NAME}")
  292. SET(CPACK_PACKAGE_DESCRIPTION_SUMMARY "${PROJECT_NAME}")
  293. SET(CPACK_INCLUDE_TOPLEVEL_DIRECTORY 1)
  294. SET(CPACK_OUTPUT_FILE_PREFIX "${TORQUE_APP_DIR}/packages/${PROJECT_NAME}")
  295. SET(CPACK_PACKAGE_INSTALL_DIRECTORY "")
  296. #SET(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/ReadMe.txt")
  297. #SET(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/Copyright.txt")
  298. SET(CPACK_PACKAGE_VERSION_MAJOR "${TORQUE_APP_VERSION_MAJOR}")
  299. SET(CPACK_PACKAGE_VERSION_MINOR "${TORQUE_APP_VERSION_MINOR}")
  300. SET(CPACK_PACKAGE_VERSION_PATCH "${TORQUE_APP_VERSION_PATCH}")
  301. #SET(CPACK_PACKAGE_EXECUTABLES "${PROJECT_NAME}" "${PROJECT_NAME}")
  302. SET(CPACK_SOURCE_PACKAGE_FILE_NAME "${PROJECT_NAME}-${TORQUE_APP_VERSION_STRING}")
  303. #SET(CPACK_SOURCE_STRIP_FILES "")
  304. endmacro()
  305. # always static for now
  306. set(TORQUE_STATIC ON)
  307. #option(TORQUE_STATIC "enables or disable static" OFF)
  308. if(WIN32)
  309. set(TORQUE_CXX_FLAGS_EXECUTABLES "/wd4018 /wd4100 /wd4121 /wd4127 /wd4130 /wd4244 /wd4245 /wd4389 /wd4511 /wd4512 /wd4800 /wd4995 " CACHE TYPE STRING)
  310. mark_as_advanced(TORQUE_CXX_FLAGS_EXECUTABLES)
  311. set(TORQUE_CXX_FLAGS_LIBS "/W0" CACHE TYPE STRING)
  312. mark_as_advanced(TORQUE_CXX_FLAGS_LIBS)
  313. set(TORQUE_CXX_FLAGS_COMMON_DEFAULT "-DUNICODE -D_UNICODE /MP /O2 /Ob2 /Oi /Ot /Oy /GT /Zi /W4 /nologo /GF /EHsc /GS- /Gy- /Qpar- /fp:fast /fp:except- /GR /Zc:wchar_t- /D_CRT_SECURE_NO_WARNINGS" )
  314. if( TORQUE_CPU_X32 )
  315. set(TORQUE_CXX_FLAGS_COMMON_DEFAULT ${TORQUE_CXX_FLAGS_COMMON_DEFAULT}" /arch:SSE2")
  316. endif()
  317. set(TORQUE_CXX_FLAGS_COMMON ${TORQUE_CXX_FLAGS_COMMON_DEFAULT} CACHE TYPE STRING)
  318. mark_as_advanced(TORQUE_CXX_FLAGS_COMMON)
  319. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORQUE_CXX_FLAGS_COMMON}")
  320. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS}")
  321. set(CMAKE_EXE_LINKER_FLAGS "/LARGEADDRESSAWARE")
  322. #set(STATIC_LIBRARY_FLAGS "/OPT:NOREF")
  323. # Force static runtime libraries
  324. if(TORQUE_STATIC)
  325. FOREACH(flag
  326. CMAKE_C_FLAGS_RELEASE
  327. CMAKE_C_FLAGS_RELWITHDEBINFO
  328. CMAKE_C_FLAGS_DEBUG
  329. CMAKE_C_FLAGS_DEBUG_INIT
  330. CMAKE_CXX_FLAGS_RELEASE
  331. CMAKE_CXX_FLAGS_RELWITHDEBINFO
  332. CMAKE_CXX_FLAGS_DEBUG
  333. CMAKE_CXX_FLAGS_DEBUG_INIT)
  334. STRING(REPLACE "/MD" "/MT" "${flag}" "${${flag}}")
  335. SET("${flag}" "${${flag}} /EHsc")
  336. ENDFOREACH()
  337. endif()
  338. else()
  339. # TODO: improve default settings on other platforms
  340. set(TORQUE_CXX_FLAGS_EXECUTABLES "" CACHE TYPE STRING)
  341. mark_as_advanced(TORQUE_CXX_FLAGS_EXECUTABLES)
  342. set(TORQUE_CXX_FLAGS_LIBS "" CACHE TYPE STRING)
  343. mark_as_advanced(TORQUE_CXX_FLAGS_LIBS)
  344. set(TORQUE_CXX_FLAGS_COMMON "" CACHE TYPE STRING)
  345. mark_as_advanced(TORQUE_CXX_FLAGS)
  346. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORQUE_CXX_FLAGS}")
  347. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS}")
  348. endif()
  349. if(UNIX)
  350. SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${projectOutDir}")
  351. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${projectOutDir}")
  352. SET(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG "${projectOutDir}")
  353. set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG "${projectOutDir}")
  354. endif()
  355. # fix the debug/release subfolders on windows
  356. if(MSVC)
  357. FOREACH(CONF ${CMAKE_CONFIGURATION_TYPES})
  358. # Go uppercase (DEBUG, RELEASE...)
  359. STRING(TOUPPER "${CONF}" CONF)
  360. #SET("CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONF}" "${projectOutDir}")
  361. SET("CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONF}" "${projectOutDir}")
  362. ENDFOREACH()
  363. endif()