CMakeLists.txt 43 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075
  1. # Find Ogre module.
  2. # Auto-detect common OGRE install locations if the user didn't provide one.
  3. # TODO: Add candidates for other platforms.
  4. if(NOT DEFINED OGRE_ROOT)
  5. set(_OGRE_CANDIDATES
  6. "/usr/lib/x86_64-linux-gnu/OGRE"
  7. "/usr/lib/OGRE"
  8. "/usr/local/lib/OGRE"
  9. "/usr/share/OGRE"
  10. )
  11. foreach(_cand IN LISTS _OGRE_CANDIDATES)
  12. if(EXISTS "${_cand}")
  13. # If the candidate points to an include directory like
  14. # /usr/include/OGRE,set OGRE_ROOT to the system root (two
  15. # directories up) so later searches for modules/libraries find it.
  16. if(_cand MATCHES "/include/OGRE$" OR _cand MATCHES ".*/OGRE$")
  17. get_filename_component(_p "${_cand}" DIRECTORY)
  18. get_filename_component(_p2 "${_p}" DIRECTORY)
  19. set(OGRE_ROOT "${_p2}")
  20. else()
  21. set(OGRE_ROOT "${_cand}")
  22. endif()
  23. message(STATUS "Auto-detected OGRE_ROOT=${OGRE_ROOT}")
  24. break()
  25. endif()
  26. endforeach()
  27. endif()
  28. # Explicitly search for other common libraries if CMake find modules failed.
  29. if(NOT OIS_LIBRARIES)
  30. find_library(_ois_lib NAMES OIS OIS-1.3.0 libOIS-1.3.0 libOIS HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  31. if(_ois_lib)
  32. set(OIS_LIBRARIES ${_ois_lib})
  33. message(STATUS "Found OIS library: ${_ois_lib}")
  34. endif()
  35. endif()
  36. # Option: control whether deterministic filesystem fallbacks are allowed.
  37. # When ON (default), CMake will try SONAME/`/usr/lib` fallbacks and inject
  38. # generic `-lboost_*` flags as a last resort to improve out-of-tree builds on
  39. # systems without proper dev packages. Set to OFF to require proper find_package
  40. # results or user-supplied hints (preferred for packaging/CI).
  41. option(USE_DETERMINISTIC_FALLBACKS "Enable deterministic filesystem fallbacks for library detection (SONAME and /usr/lib path appends). Toggle off to require proper dev packages or OGRE_ROOT." ON)
  42. if(NOT TinyXML_LIBRARIES)
  43. find_library(_tinyxml_lib NAMES tinyxml libtinyxml TinyXML TiXml libtinyxml2 tinyxml2 libtinyxml2 HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  44. if(_tinyxml_lib)
  45. set(TinyXML_LIBRARIES ${_tinyxml_lib})
  46. message(STATUS "Found TinyXML library: ${_tinyxml_lib}")
  47. endif()
  48. endif()
  49. if(NOT OPENAL_LIBRARY)
  50. find_library(_openal_lib NAMES openal libopenal OpenAL openal32 libopenal.so.1 HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  51. if(_openal_lib)
  52. set(OPENAL_LIBRARY ${_openal_lib})
  53. message(STATUS "Fallback: Found OpenAL library: ${_openal_lib}")
  54. endif()
  55. endif()
  56. if(NOT OGGVORBIS_LIBRARIES)
  57. set(_ov)
  58. find_library(_vorbisfile_lib NAMES vorbisfile libvorbisfile libvorbisfile.so vorbisfile.so HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  59. find_library(_vorbis_lib NAMES vorbis libvorbis libvorbis.so vorbis.so HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  60. find_library(_ogg_lib NAMES ogg libogg libogg.so ogg.so HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  61. if(_vorbisfile_lib)
  62. list(APPEND _ov ${_vorbisfile_lib})
  63. endif()
  64. if(_vorbis_lib)
  65. list(APPEND _ov ${_vorbis_lib})
  66. endif()
  67. if(_ogg_lib)
  68. list(APPEND _ov ${_ogg_lib})
  69. endif()
  70. if(_ov)
  71. set(OGGVORBIS_LIBRARIES ${_ov})
  72. message(STATUS "Found Ogg/Vorbis libraries: ${_ov}")
  73. endif()
  74. endif()
  75. # Try to find additional OGRE components if they are present as system libs
  76. foreach(_comp IN ITEMS OgreOverlay OgreBites OgreRTShaderSystem OgreProperty OgrePaging OgreVolume)
  77. find_library(_comp_lib NAMES ${_comp} lib${_comp} ${_comp}.so HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib ${OGRE_ROOT}/lib)
  78. if(_comp_lib)
  79. list(APPEND OGRE_LIBRARIES ${_comp_lib})
  80. message(STATUS "Found OGRE component ${_comp}: ${_comp_lib}")
  81. endif()
  82. endforeach()
  83. # Remove any duplicate entries that may have been appended by fallbacks
  84. list(REMOVE_DUPLICATES OGRE_LIBRARIES)
  85. # Try pkg-config to find OGRE (if available on the system)
  86. find_package(PkgConfig QUIET)
  87. if(PKG_CONFIG_FOUND)
  88. pkg_check_modules(_ogre_pkgs QUIET OGRE)
  89. if(_ogre_pkgs_FOUND)
  90. if(_ogre_pkgs.prefix)
  91. if(NOT DEFINED OGRE_ROOT)
  92. set(OGRE_ROOT "${_ogre_pkgs.prefix}")
  93. endif()
  94. message(STATUS "Found OGRE via pkg-config, OGRE_ROOT=${OGRE_ROOT}")
  95. # If pkg-config gives a prefix, try to set CMake module path.
  96. set(_candidate_cm_path "${_ogre_pkgs.prefix}/CMake")
  97. if(EXISTS "${_candidate_cm_path}")
  98. set(OGRE_CMAKE_MODULE_PATH "${_candidate_cm_path}")
  99. else()
  100. set(_candidate_cm_path "${_ogre_pkgs.prefix}/cmake")
  101. if(EXISTS "${_candidate_cm_path}")
  102. set(OGRE_CMAKE_MODULE_PATH "${_candidate_cm_path}")
  103. endif()
  104. endif()
  105. endif()
  106. # Export include dirs and libraries from pkg-config for later usage
  107. set(OGRE_INCLUDE_DIRS ${_ogre_pkgs_INCLUDE_DIRS})
  108. # Convert pkg-config library flags (e.g. "-L.. -lOgreMain -lOgreBites")
  109. # into a CMake list so target_link_libraries handles them correctly.
  110. string(REPLACE " " ";" _pkg_libs_list "${_ogre_pkgs_LIBRARIES}")
  111. list(APPEND OGRE_LIBRARIES ${_pkg_libs_list})
  112. set(OGRE_PKG_FOUND TRUE)
  113. endif()
  114. endif()
  115. # If OGRE_ROOT is not still yet, try locating Ogre headers or the OgreMain
  116. # library directly
  117. if(NOT DEFINED OGRE_ROOT)
  118. find_path(_ogre_header Ogre.h HINTS /usr/include/OGRE /usr/include /usr/local/include)
  119. if(_ogre_header)
  120. # If header was found in /usr/include/OGRE, set OGRE_ROOT to /usr
  121. get_filename_component(_hdr_dir "${_ogre_header}" DIRECTORY)
  122. if(_hdr_dir MATCHES "/include/OGRE$" OR _hdr_dir MATCHES ".*/OGRE$")
  123. get_filename_component(_p "${_hdr_dir}" DIRECTORY)
  124. get_filename_component(_p2 "${_p}" DIRECTORY)
  125. set(OGRE_ROOT "${_p2}")
  126. else()
  127. # header found in include root; set OGRE_ROOT to parent
  128. get_filename_component(_p "${_hdr_dir}" DIRECTORY)
  129. set(OGRE_ROOT "${_p}")
  130. endif()
  131. message(STATUS "Found Ogre header at ${_ogre_header}; setting OGRE_ROOT=${OGRE_ROOT}")
  132. endif()
  133. endif()
  134. # If OGRE_ROOT is not still yet, try locating Ogre headers or the OgreMain
  135. # library directly
  136. if(NOT DEFINED OGRE_ROOT)
  137. find_library(_ogre_lib OgreMain HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  138. if(_ogre_lib)
  139. get_filename_component(_lib_dir "${_ogre_lib}" DIRECTORY)
  140. # set OGRE_ROOT two levels up if libs are in /usr/lib/x86_64-linux-gnu
  141. get_filename_component(_p "${_lib_dir}" DIRECTORY)
  142. get_filename_component(_p2 "${_p}" DIRECTORY)
  143. set(OGRE_ROOT "${_p2}")
  144. message(STATUS "Found Ogre library ${_ogre_lib}; setting OGRE_ROOT=${OGRE_ROOT}")
  145. endif()
  146. endif()
  147. set(CMAKE_FRAMEWORK_PATH
  148. ${CMAKE_FRAMEWORK_PATH}
  149. ${CMAKE_SOURCE_DIR}/OgreSDK/lib/macosx/Release
  150. ${CMAKE_SOURCE_DIR}/OgreSDK/lib/macosx/Debug
  151. )
  152. set(OGRE_FRAMEWORK_INCLUDES ${CMAKE_SOURCE_DIR}/OgreSDK/include)
  153. find_path(OGRE_CMAKE_MODULE_PATH FindOGRE.cmake
  154. HINTS
  155. "$ENV{OGRE_HOME}/CMake/"
  156. "/usr/lib/x86_64-linux-gnu/OGRE/cmake"
  157. "/usr/lib/x86_64-linux-gnu/OGRE"
  158. "/usr/local/lib/OGRE/cmake"
  159. "/usr/lib/OGRE/cmake"
  160. "/usr/share/OGRE/cmake/modules"
  161. "${CMAKE_CURRENT_SOURCE_DIR}/OgreSDK/CMake"
  162. )
  163. if(NOT OGRE_CMAKE_MODULE_PATH)
  164. # Try additional conventional locations using OGRE_ROOT if set by user or
  165. # auto-detection
  166. if(DEFINED OGRE_ROOT)
  167. find_path(OGRE_CMAKE_MODULE_PATH FindOGRE.cmake HINTS "${OGRE_ROOT}/CMake" "${OGRE_ROOT}/cmake")
  168. endif()
  169. endif()
  170. if(NOT OGRE_CMAKE_MODULE_PATH)
  171. message(WARNING "FindOGRE.cmake not found in expected locations; will try pkg-config or config-mode find_package(OGRE)")
  172. else()
  173. list(APPEND CMAKE_MODULE_PATH "${OGRE_CMAKE_MODULE_PATH}" "${CMAKE_SOURCE_DIR}/CMake")
  174. endif()
  175. # Find Boost module.
  176. if (WIN32)
  177. set(Boost_USE_STATIC_LIBS TRUE)
  178. else()
  179. # Statically linking boost to a dynamic Ogre build doesn't work on Linux
  180. # 64bit.
  181. set(Boost_USE_STATIC_LIBS ${OGRE_STATIC})
  182. endif ()
  183. if (MINGW)
  184. # Ensure OgreBites is linked (provides WindowEventUtilities and related
  185. # symbols).
  186. find_library(_ogrebites_lib OgreBites HINTS ${OGRE_ROOT} /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  187. if(_ogrebites_lib)
  188. # This is probably a bug in CMake: the boost find module tries to look for
  189. # boost libraries with name libboost_*, but CMake already prefixes library
  190. # search names with "lib". This is the workaround.
  191. set(CMAKE_FIND_LIBRARY_PREFIXES ${CMAKE_FIND_LIBRARY_PREFIXES} "")
  192. endif ()
  193. # Components that need linking (NB does not include header-only components like
  194. # bind).
  195. set(OGRE_BOOST_COMPONENTS thread date_time)
  196. find_package(Boost COMPONENTS ${OGRE_BOOST_COMPONENTS} QUIET)
  197. if (NOT Boost_FOUND)
  198. set(Boost_USE_STATIC_LIBS NOT ${Boost_USE_STATIC_LIBS})
  199. find_package(Boost COMPONENTS ${OGRE_BOOST_COMPONENTS} QUIET)
  200. endif()
  201. if(Boost_FOUND AND Boost_VERSION GREATER 104900)
  202. set(OGRE_BOOST_COMPONENTS thread date_time system chrono)
  203. find_package(Boost COMPONENTS ${OGRE_BOOST_COMPONENTS} QUIET)
  204. endif()
  205. # Set up referencing of Boost.
  206. if (NOT APPLE)
  207. add_definitions(-DBOOST_ALL_NO_LIB)
  208. endif()
  209. if (Boost_LIBRARIES STREQUAL "")
  210. message(STATUS "Boost_LIBRARIES is not set yet; will attempt robust fallbacks later")
  211. endif()
  212. #message(STATUS "DEBUG: entering Boost detection; BOOST_COMPONENTS=${BOOST_COMPONENTS} BOOST_LINK_LIBS=${BOOST_LINK_LIBS}")
  213. # Find packages required for V-Gears.
  214. # Prefer pkg-config discovery for OGRE (works with system packages). If
  215. # pkg-config finds OGRE, populate OGRE_INCLUDE_DIRS and OGRE_LIBRARIES and
  216. # skip find_package(OGRE). Otherwise fall back to the existing FindOGRE logic.
  217. find_package(PkgConfig QUIET)
  218. if(NOT DEFINED OGRE_PKG_FOUND)
  219. if(PKG_CONFIG_FOUND)
  220. # pkg-config already attempted above; if OGRE_PKG_FOUND is set, use it.
  221. if(DEFINED _ogre_pkgs_FOUND AND _ogre_pkgs_FOUND)
  222. set(OGRE_PKG_FOUND TRUE)
  223. # OGRE_INCLUDE_DIRS/OGRE_LIBRARIES were set earlier when
  224. # _ogre_pkgs was found.
  225. endif()
  226. endif()
  227. endif()
  228. if(NOT OGRE_PKG_FOUND)
  229. find_package(OGRE REQUIRED QUIET)
  230. else()
  231. message(STATUS "Using OGRE from pkg-config: includes=${OGRE_INCLUDE_DIRS}")
  232. endif()
  233. # If pkg-config was used, try to locate common OGRE component libraries
  234. if(OGRE_PKG_FOUND)
  235. set(_extra_ogre_libs)
  236. foreach(_comp IN ITEMS OgreOverlay OgreBites OgreRTShaderSystem)
  237. find_library(_lib ${_comp} HINTS ${OGRE_ROOT} /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib PATHS ${OGRE_ROOT}/lib)
  238. if(_lib)
  239. list(APPEND _extra_ogre_libs ${_lib})
  240. message(STATUS "Found OGRE component ${_comp}: ${_lib}")
  241. endif()
  242. endforeach()
  243. if(_extra_ogre_libs)
  244. list(APPEND OGRE_LIBRARIES ${_extra_ogre_libs})
  245. endif()
  246. # Display final OGRE libraries that will be linked
  247. message(STATUS "Using OGRE_LIBRARIES: ${OGRE_LIBRARIES}")
  248. endif()
  249. # Find OIS.
  250. find_package(OIS QUIET)
  251. if(NOT OIS_FOUND)
  252. find_library(_ois_lib NAMES OIS libOIS ois HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  253. if(_ois_lib)
  254. set(OIS_LIBRARIES ${_ois_lib})
  255. message(STATUS "Found OIS library: ${_ois_lib}")
  256. else()
  257. message(STATUS "OIS not found by find_package; will attempt to continue and emit clearer diagnostics later.")
  258. endif()
  259. endif()
  260. # Find OpenAL.
  261. find_package(OpenAL QUIET)
  262. if(NOT OPENAL_FOUND AND PKG_CONFIG_FOUND)
  263. pkg_check_modules(_openal_pkgs QUIET openal)
  264. if(_openal_pkgs_FOUND)
  265. list(APPEND OPENAL_LIBRARY ${_openal_pkgs_LIBRARIES})
  266. list(APPEND OPENAL_INCLUDE_DIR ${_openal_pkgs_INCLUDE_DIRS})
  267. message(STATUS "Found OpenAL via pkg-config: ${_openal_pkgs_LIBRARIES}")
  268. endif()
  269. endif()
  270. if(NOT OPENAL_FOUND AND NOT OPENAL_LIBRARY)
  271. find_library(_openal_lib NAMES openal libopenal OpenAL openal32 HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  272. if(_openal_lib)
  273. set(OPENAL_LIBRARY ${_openal_lib})
  274. message(STATUS "Found OpenAL library: ${_openal_lib}")
  275. endif()
  276. endif()
  277. # Find OggVorbis.
  278. find_package(OggVorbis QUIET)
  279. if(NOT OGGVORBIS_FOUND)
  280. find_library(_vorbisfile_lib NAMES vorbisfile libvorbisfile HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  281. find_library(_vorbis_lib NAMES vorbis libvorbis HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  282. find_library(_ogg_lib NAMES ogg libogg HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  283. set(_ovlibs)
  284. if(_vorbisfile_lib)
  285. list(APPEND _ovlibs ${_vorbisfile_lib})
  286. endif()
  287. if(_vorbis_lib)
  288. list(APPEND _ovlibs ${_vorbis_lib})
  289. endif()
  290. if(_ogg_lib)
  291. list(APPEND _ovlibs ${_ogg_lib})
  292. endif()
  293. if(_ovlibs)
  294. set(OGGVORBIS_LIBRARIES ${_ovlibs})
  295. message(STATUS "Found Ogg/Vorbis libraries: ${_ovlibs}")
  296. else()
  297. message(STATUS "Ogg/Vorbis not found by find_package; will attempt to continue and emit clearer diagnostics later.")
  298. endif()
  299. endif()
  300. # If the installer is requested, ensure Qt is available. If Qt is missing,
  301. # disable the installer to avoid compilation failures.
  302. if(BUILD_INSTALLER)
  303. # Optional user-provided hint: allow passing a single path that contains
  304. # the Qt CMake config directories (e.g. '/usr/lib/x86_64-linux-gnu/cmake').
  305. set(QT_DIR_HINT "" CACHE PATH "Optional hint for Qt CMake config directory (parent of Qt5/Qt6)")
  306. if(QT_DIR_HINT)
  307. # If user passed a hint, set Qt5_DIR/Qt6_DIR to assist find_package.
  308. if(EXISTS "${QT_DIR_HINT}/Qt5")
  309. set(Qt5_DIR "${QT_DIR_HINT}/Qt5" CACHE PATH "Qt5 dir from hint" FORCE)
  310. elseif(EXISTS "${QT_DIR_HINT}/Qt5Core")
  311. set(Qt5_DIR "${QT_DIR_HINT}/Qt5Core" CACHE PATH "Qt5 dir from hint" FORCE)
  312. endif()
  313. if(EXISTS "${QT_DIR_HINT}/Qt6")
  314. set(Qt6_DIR "${QT_DIR_HINT}/Qt6" CACHE PATH "Qt6 dir from hint" FORCE)
  315. endif()
  316. endif()
  317. # Try Qt5 first, then fall back to Qt6. Prefer imported targets for linking.
  318. find_package(Qt5 COMPONENTS Core Widgets Gui QUIET)
  319. # Debugging: print detected Qt5 variables/targets when present
  320. if(TARGET Qt5::Core)
  321. message(STATUS "Qt5 imported: target Qt5::Core is available")
  322. endif()
  323. message(STATUS "Qt5Core_FOUND=${Qt5Core_FOUND} Qt5Widgets_FOUND=${Qt5Widgets_FOUND} Qt5Gui_FOUND=${Qt5Gui_FOUND}")
  324. # Some distro setups place Qt config files in nonstandard cmake dirs that
  325. # CMake may not probe. If the normal find_package didn't create imported
  326. # targets or set FOUND variables, probe common Qt config locations and
  327. # retry find_package with explicit hints.
  328. if(NOT (TARGET Qt5::Core OR Qt5Core_FOUND))
  329. set(_qt_candidate_dirs
  330. /usr/lib/x86_64-linux-gnu/cmake/Qt5
  331. /usr/lib/x86_64-linux-gnu/cmake/Qt5Core
  332. /usr/lib/cmake/Qt5
  333. /usr/lib64/cmake/Qt5
  334. /usr/local/lib/cmake/Qt5
  335. $ENV{HOME}/.local/lib/cmake/Qt5
  336. )
  337. foreach(_qd IN LISTS _qt_candidate_dirs)
  338. if(EXISTS "${_qd}/Qt5Config.cmake" OR EXISTS "${_qd}/Qt5CoreConfig.cmake")
  339. message(STATUS "Found Qt5 config file under ${_qd}; retrying find_package(Qt5) with PATHS hint")
  340. set(Qt5_DIR "${_qd}" CACHE PATH "Detected Qt5 dir" FORCE)
  341. find_package(Qt5 COMPONENTS Core Widgets Gui QUIET PATHS "${_qd}")
  342. break()
  343. endif()
  344. endforeach()
  345. endif()
  346. if(TARGET Qt5::Core OR Qt5Core_FOUND)
  347. set(QT_LINK_LIBS Qt5::Core Qt5::Widgets Qt5::Gui)
  348. if(DEFINED Qt5Core_INCLUDE_DIRS)
  349. set(QT_INCLUDE_DIRS ${Qt5Core_INCLUDE_DIRS})
  350. endif()
  351. message(STATUS "Found Qt5; installer will be built using Qt5.")
  352. else()
  353. find_package(Qt6 COMPONENTS Core Widgets Gui QUIET)
  354. if(NOT (TARGET Qt6::Core OR Qt6Core_FOUND))
  355. # Retry probing common Qt6 cmake locations as well
  356. set(_qt6_candidate_dirs
  357. /usr/lib/x86_64-linux-gnu/cmake/Qt6
  358. /usr/lib/cmake/Qt6
  359. /usr/lib64/cmake/Qt6
  360. /usr/local/lib/cmake/Qt6
  361. $ENV{HOME}/.local/lib/cmake/Qt6
  362. )
  363. foreach(_qd IN LISTS _qt6_candidate_dirs)
  364. if(EXISTS "${_qd}/Qt6Config.cmake" OR EXISTS "${_qd}/Qt6CoreConfig.cmake")
  365. message(STATUS "Found Qt6 config file under ${_qd}; retrying find_package(Qt6) with PATHS hint")
  366. set(Qt6_DIR "${_qd}" CACHE PATH "Detected Qt6 dir" FORCE)
  367. find_package(Qt6 COMPONENTS Core Widgets Gui QUIET PATHS "${_qd}")
  368. break()
  369. endif()
  370. endforeach()
  371. endif()
  372. if(TARGET Qt6::Core OR Qt6Core_FOUND)
  373. set(QT_LINK_LIBS Qt6::Core Qt6::Widgets Qt6::Gui)
  374. set(QT_INCLUDE_DIRS)
  375. message(STATUS "Found Qt6; installer will be built using Qt6.")
  376. else()
  377. # Attempt a pragmatic fallback: search for Qt headers/libs in common
  378. # distro include/lib locations and link manually if found. This is
  379. # less featureful than using the Qt CMake config (imported targets),
  380. # but it helps the installer build on systems where Qt dev packages
  381. # are installed but config-mode find_package didn't succeed.
  382. set(_qt_fallback_includes)
  383. set(_qt_fallback_libs)
  384. set(_qt_inc_candidates /usr/include/qt5 /usr/include/x86_64-linux-gnu/qt5 /usr/include)
  385. foreach(_inc IN LISTS _qt_inc_candidates)
  386. if(EXISTS "${_inc}/QtCore/QtGlobal")
  387. list(APPEND _qt_fallback_includes ${_inc})
  388. message(STATUS "Pragmatic Qt fallback: found headers under ${_inc}")
  389. break()
  390. endif()
  391. endforeach()
  392. # Try to find Qt5 libraries by SONAME/name
  393. foreach(_libname IN ITEMS Qt5Core Qt5Widgets Qt5Gui)
  394. find_library(_qtl NAMES ${_libname} ${_libname}.so lib${_libname}.so HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  395. if(_qtl)
  396. list(APPEND _qt_fallback_libs ${_qtl})
  397. message(STATUS "Pragmatic Qt fallback: found ${_libname}: ${_qtl}")
  398. endif()
  399. endforeach()
  400. if(_qt_fallback_libs AND _qt_fallback_includes)
  401. set(QT_LINK_LIBS ${_qt_fallback_libs})
  402. set(QT_INCLUDE_DIRS ${_qt_fallback_includes})
  403. message(STATUS "Using pragmatic Qt fallback (manual include/libs). Installer will be built.")
  404. else()
  405. # As a last resort, and only when deterministic fallbacks are
  406. # enabled, inject generic Qt5 linker flags and common include
  407. # paths so the installer can still be built on Debian/Ubuntu-like
  408. # systems where the config-mode package lookup didn't succeed.
  409. if(USE_DETERMINISTIC_FALLBACKS)
  410. message(STATUS "Pragmatic Qt fallback failed; using generic Qt -l flags and include paths as last resort")
  411. set(QT_LINK_LIBS -lQt5Core -lQt5Widgets -lQt5Gui)
  412. set(QT_INCLUDE_DIRS /usr/include/qt5 /usr/include/x86_64-linux-gnu/qt5)
  413. else()
  414. message(WARNING "BUILD_INSTALLER requested but Qt5/Qt6 not found and pragmatic fallback failed. Disabling installer build. Install Qt dev packages or set BUILD_INSTALLER=OFF.")
  415. set(BUILD_INSTALLER OFF CACHE BOOL "Build the V-Gears-Installer" FORCE)
  416. endif()
  417. endif()
  418. endif()
  419. endif()
  420. endif()
  421. # Find TinyXML
  422. find_package(TinyXML QUIET)
  423. if(NOT TinyXML_FOUND)
  424. find_library(_tinyxml_lib NAMES tinyxml libtinyxml TiXml TiXmlDocument HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib)
  425. if(_tinyxml_lib)
  426. set(TinyXML_LIBRARIES ${_tinyxml_lib})
  427. message(STATUS "Found TinyXML library: ${_tinyxml_lib}")
  428. else()
  429. message(STATUS "TinyXML not found by find_package; will attempt to continue and emit clearer diagnostics later.")
  430. endif()
  431. endif()
  432. # Find Boost module with common components and fall back to robust per-component search
  433. set(BOOST_COMPONENTS program_options filesystem thread system chrono)
  434. # First try to pick up modern imported targets (Boost::component)
  435. set(BOOST_LINK_LIBS)
  436. foreach(_comp IN LISTS BOOST_COMPONENTS)
  437. if(TARGET Boost::${_comp})
  438. list(APPEND BOOST_LINK_LIBS Boost::${_comp})
  439. endif()
  440. endforeach()
  441. # Next try the classic find_package that populates Boost_LIBRARIES
  442. if(NOT BOOST_LINK_LIBS)
  443. find_package(Boost COMPONENTS ${BOOST_COMPONENTS} QUIET)
  444. if(NOT Boost_FOUND)
  445. # Try toggling static preference once
  446. set(Boost_USE_STATIC_LIBS NOT ${Boost_USE_STATIC_LIBS})
  447. find_package(Boost COMPONENTS ${BOOST_COMPONENTS} QUIET)
  448. endif()
  449. if(Boost_FOUND AND Boost_LIBRARIES)
  450. list(APPEND BOOST_LINK_LIBS ${Boost_LIBRARIES})
  451. message(STATUS "Found Boost (find_package): ${Boost_VERSION}; libraries: ${Boost_LIBRARIES}")
  452. endif()
  453. endif()
  454. # Final fallback: search for per-component shared objects in common lib dirs
  455. if(NOT BOOST_LINK_LIBS)
  456. foreach(_comp IN LISTS BOOST_COMPONENTS)
  457. # Look for any versioned libboost_${comp}*.so* file
  458. file(GLOB _found_libs
  459. /usr/lib*/libboost_${_comp}*.so*
  460. /usr/local/lib*/libboost_${_comp}*.so*
  461. )
  462. if(_found_libs)
  463. # Prefer the first (usually the SONAME symlink), but append all found to be safe
  464. list(APPEND BOOST_LINK_LIBS ${_found_libs})
  465. message(STATUS "Found boost ${_comp}: ${_found_libs}")
  466. else()
  467. message(STATUS "Not found: boost ${_comp} not found in standard lib dirs")
  468. endif()
  469. endforeach()
  470. if(NOT BOOST_LINK_LIBS)
  471. message(STATUS "No Boost libs found; linking will fail. Install libboost-*-dev packages.")
  472. endif()
  473. endif()
  474. # Try a direct SONAME-style find_library pass for each component (preferred:
  475. # yields absolute paths like /usr/lib/x86_64-linux-gnu/libboost_program_options.so.1.83.0).
  476. if(NOT BOOST_LINK_LIBS)
  477. foreach(_comp IN LISTS BOOST_COMPONENTS)
  478. # try common SONAME/filename variants so find_library returns full paths
  479. find_library(_boost_soname
  480. NAMES libboost_${_comp}.so libboost_${_comp} boost_${_comp} boost_${_comp}.so
  481. HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib
  482. PATH_SUFFIXES . lib lib64
  483. )
  484. if(_boost_soname)
  485. list(APPEND BOOST_LINK_LIBS ${_boost_soname})
  486. message(STATUS "Found Boost SONAME for ${_comp}: ${_boost_soname}")
  487. endif()
  488. endforeach()
  489. if(NOT BOOST_LINK_LIBS)
  490. message(STATUS "SONAME pass did not find Boost libs; falling back to -l flags next.")
  491. endif()
  492. endif()
  493. # If previous attempts didn't produce usable lib paths, fall back to linker flags
  494. # using common Boost library names so the system linker searches standard paths.
  495. if(NOT BOOST_LINK_LIBS)
  496. if(USE_DETERMINISTIC_FALLBACKS)
  497. find_library(_boost_system_lib
  498. NAMES boost_system libboost_system
  499. HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib
  500. PATH_SUFFIXES . lib lib64
  501. )
  502. set(_generic_boost_flags -lboost_program_options -lboost_filesystem -lboost_thread -lboost_chrono)
  503. if(_boost_system_lib)
  504. list(APPEND _generic_boost_flags ${_boost_system_lib})
  505. else()
  506. message(STATUS "Boost.System library not found; omitting boost_system from generic Boost flags.")
  507. endif()
  508. set(BOOST_LINK_LIBS ${_generic_boost_flags})
  509. message(STATUS "Using generic Boost flags: ${BOOST_LINK_LIBS}")
  510. else()
  511. message(WARNING "Boost libraries not found and USE_DETERMINISTIC_FALLBACKS is OFF. Install libboost-*-dev packages or provide Boost hints (Boost_DIR/Boost_INCLUDE_DIR).")
  512. endif()
  513. endif()
  514. # Deduplicate and export a stable list for later linking
  515. list(REMOVE_DUPLICATES BOOST_LINK_LIBS)
  516. message(STATUS "Final BOOST_LINK_LIBS: ${BOOST_LINK_LIBS}")
  517. # Root source dir for V-Gears sources (used for include paths).
  518. if(NOT DEFINED VGEARS_SOURCE_DIR)
  519. set(VGEARS_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
  520. endif()
  521. # Ensure OgreBites (WindowEventUtilities) is explicitly found and linked when
  522. # available.
  523. if(NOT OGRE_LIBRARIES)
  524. set(OGRE_LIBRARIES)
  525. endif()
  526. find_library(_ogrebites_lib NAMES OgreBites libOgreBites OgreBites.so HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib ${OGRE_ROOT}/lib)
  527. if(_ogrebites_lib)
  528. list(FIND OGRE_LIBRARIES ${_ogrebites_lib} _idx)
  529. if(_idx EQUAL -1)
  530. list(APPEND OGRE_LIBRARIES ${_ogrebites_lib})
  531. message(STATUS "Explicitly found OgreBites: ${_ogrebites_lib}")
  532. endif()
  533. else()
  534. message(STATUS "OgreBites not found by explicit search; OgreBites symbols may be unresolved.")
  535. endif()
  536. # As a last-resort deterministic fallback, append the system path if the file
  537. # exists.
  538. if(NOT OGRE_LIBRARIES MATCHES ".*OgreBites.*")
  539. if(USE_DETERMINISTIC_FALLBACKS)
  540. if(EXISTS "/usr/lib/x86_64-linux-gnu/libOgreBites.so")
  541. list(APPEND OGRE_LIBRARIES "/usr/lib/x86_64-linux-gnu/libOgreBites.so")
  542. message(STATUS "Appended deterministic OgreBites path: /usr/lib/x86_64-linux-gnu/libOgreBites.so")
  543. endif()
  544. else()
  545. message(WARNING "OgreBites not found and USE_DETERMINISTIC_FALLBACKS is OFF. Set OGRE_ROOT or install OGRE dev packages.")
  546. endif()
  547. endif()
  548. # Source files for libvgears and v-gears.
  549. set(VGEARS_SOURCE_FILES
  550. main.cpp
  551. FF7Character.cpp
  552. FF7Common.cpp
  553. VGearsGameState.cpp
  554. common/File.cpp
  555. common/FileSystem.cpp
  556. common/FinalFantasy7/FF7NameLookup.cpp
  557. common/LzsFile.cpp
  558. common/TypeDefine.cpp
  559. common/VGearsApplication.cpp
  560. common/VGearsManualObject.cpp
  561. common/VGearsResource.cpp
  562. common/VGearsStringUtil.cpp
  563. core/AudioManager.cpp
  564. core/Background2DAnimation.cpp
  565. core/Background2D.cpp
  566. core/ScreenFade.cpp
  567. core/MovieCameraFrame.cpp
  568. core/MoviePlayer.cpp
  569. core/MovieState.cpp
  570. core/ScreenFadeState.cpp
  571. core/BattleManager.cpp
  572. core/CameraManager.cpp
  573. core/ConfigCmd.cpp
  574. core/ConfigCmdHandler.cpp
  575. core/ConfigFile.cpp
  576. core/ConfigVar.cpp
  577. core/ConfigVarHandler.cpp
  578. core/Console.cpp
  579. core/DebugDraw.cpp
  580. core/DialogsManager.cpp
  581. core/Enemy.cpp
  582. core/EntityCollision.cpp
  583. core/Entity.cpp
  584. core/EntityDirection.cpp
  585. core/EntityManager.cpp
  586. core/EntityModel.cpp
  587. core/EntityPoint.cpp
  588. core/EntityTrigger.cpp
  589. core/GameFrameListener.cpp
  590. core/InputManager.cpp
  591. core/Manager.cpp
  592. core/particles/Particle.cpp
  593. core/particles/ParticleEmitter.cpp
  594. core/particles/ParticleEmitterDictionary.cpp
  595. core/particles/ParticleEmitterTranslator.cpp
  596. core/particles/ParticleRenderer.cpp
  597. core/particles/ParticleRendererTranslator.cpp
  598. core/particles/ParticleSystem.cpp
  599. core/particles/ParticleSystemFactory.cpp
  600. core/particles/ParticleSystemManager.cpp
  601. core/particles/ParticleSystemTranslator.cpp
  602. core/particles/ParticleSystemTranslatorManager.cpp
  603. core/particles/ParticleTechnique.cpp
  604. core/particles/ParticleTechniqueTranslator.cpp
  605. core/particles/ParticleVisual.cpp
  606. core/particles/emitters/PointEmitter.cpp
  607. core/particles/emitters/PointEmitterFactory.cpp
  608. core/particles/renderer/ParticleEntityRenderer.cpp
  609. core/particles/renderer/ParticleEntityRendererDictionary.cpp
  610. core/Savemap.cpp
  611. core/SavemapHandler.cpp
  612. core/ScriptManager.cpp
  613. core/TextHandler.cpp
  614. core/Timer.cpp
  615. core/UiAnimation.cpp
  616. core/UiFont.cpp
  617. core/UiManager.cpp
  618. core/UiSprite.cpp
  619. core/UiTextArea.cpp
  620. core/UiWidget.cpp
  621. core/Utilites.cpp
  622. core/Walkmesh.cpp
  623. core/WorldMapManager.cpp
  624. core/XmlAttackFile.cpp
  625. core/XmlBackground2DFile.cpp
  626. core/XmlBattleCharactersFile.cpp
  627. core/XmlBattleScenesFile.cpp
  628. core/XmlEnemyFile.cpp
  629. core/XmlFile.cpp
  630. core/XmlFontFile.cpp
  631. core/XmlFontsFile.cpp
  632. core/XmlFormationFile.cpp
  633. core/XmlMapFile.cpp
  634. core/XmlMapsFile.cpp
  635. core/XmlMusicsFile.cpp
  636. core/XmlPrototypesFile.cpp
  637. core/XmlScreenFile.cpp
  638. core/XmlScreensFile.cpp
  639. core/XmlScriptsFile.cpp
  640. core/XmlSoundsFile.cpp
  641. core/XmlTextFile.cpp
  642. core/XmlTextsFile.cpp
  643. core/XmlWalkmeshFile.cpp
  644. core/XmlWorldMapFile.cpp
  645. data/VGearsAFile.cpp
  646. data/VGearsAFileManager.cpp
  647. data/VGearsAFileSerializer.cpp
  648. data/VGearsBackgroundFile.cpp
  649. data/VGearsBackgroundFileManager.cpp
  650. data/VGearsBackgroundFileSerializer.cpp
  651. data/VGearsBackgroundTextureLoader.cpp
  652. data/VGearsCameraMatrixFile.cpp
  653. data/VGearsCameraMatrixFileManager.cpp
  654. data/VGearsCameraMatrixFileSerializer.cpp
  655. data/VGearsFLevelBackground2DLoader.cpp
  656. data/VGearsFLevelFile.cpp
  657. data/VGearsFLevelFileManager.cpp
  658. data/VGearsFLevelFileSerializer.cpp
  659. data/VGearsFLevelTextureLoader.cpp
  660. data/VGearsHRCFile.cpp
  661. data/VGearsHRCFileManager.cpp
  662. data/VGearsHRCFileSerializer.cpp
  663. data/VGearsHRCMeshLoader.cpp
  664. data/VGearsHRCSkeletonLoader.cpp
  665. data/VGearsLGPArchive.cpp
  666. data/VGearsLGPArchiveFactory.cpp
  667. data/VGearsLGPArchiveSerializer.cpp
  668. data/VGearsLZSDataStream.cpp
  669. data/VGearsLZSFLevelFile.cpp
  670. data/VGearsLZSFLevelFileManager.cpp
  671. data/VGearsMapListFile.cpp
  672. data/VGearsPaletteFile.cpp
  673. data/VGearsPaletteFileManager.cpp
  674. data/VGearsPaletteFileSerializer.cpp
  675. data/VGearsPFile.cpp
  676. data/VGearsPFileManager.cpp
  677. data/VGearsPFileSerializer.cpp
  678. data/VGearsRSDFile.cpp
  679. data/VGearsRSDFileManager.cpp
  680. data/VGearsRSDFileSerializer.cpp
  681. data/VGearsSerializer.cpp
  682. data/VGearsTexCodec.cpp
  683. data/VGearsTexFile.cpp
  684. data/VGearsTriggersFile.cpp
  685. data/VGearsXMLSerializer.cpp
  686. data/FinalFantasy7/FF7ModelListFile.cpp
  687. data/FinalFantasy7/FF7ModelListFileManager.cpp
  688. data/FinalFantasy7/FF7ModelListFileSerializer.cpp
  689. data/worldmap/WorldmapFile.cpp
  690. data/worldmap/WorldmapFileManager.cpp
  691. data/worldmap/WorldmapFileSerializer.cpp
  692. data/worldmap/TxzFile.cpp
  693. data/worldmap/TxzFileManager.cpp
  694. data/worldmap/TxzFileSerializer.cpp
  695. map/VGearsBackground2DFile.cpp
  696. map/VGearsBackground2DFileManager.cpp
  697. map/VGearsBackground2DFileXMLSerializer.cpp
  698. map/VGearsMapFile.cpp
  699. map/VGearsMapFileManager.cpp
  700. map/VGearsMapFileXMLSerializer.cpp
  701. map/VGearsWalkmeshFile.cpp
  702. map/VGearsWalkmeshFileManager.cpp
  703. map/VGearsWalkmeshFileXMLSerializer.cpp
  704. map/FinalFantasy7/FF7WalkmeshFileSerializer.cpp
  705. modules/worldmap/WorldmapModule.cpp
  706. #viewer/ViewerModule.cpp
  707. )
  708. endif()
  709. # Compiler options.
  710. if(APPLE) # Apple specific options
  711. set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -m32")
  712. set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -m32")
  713. set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -m32")
  714. endif()
  715. if(WIN32) # Check usage and remove if uneccessary
  716. add_definitions(-DWIN32 -D__WIN32__ -D_WINDOWS)
  717. add_definitions(-W -mthreads -fmessage-length=0 -fexceptions -fident)
  718. # Linker options
  719. add_definitions(
  720. -Wl,--enable-runtime-pseudo-reloc
  721. -Wl,--enable-auto-image-base
  722. -Wl,--add-stdcall-alias
  723. )
  724. endif()
  725. if (MSVC)
  726. # Build cpp files on all cores, up virtual mem for PCH's as cotire really
  727. # makes the compiler scream.
  728. SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /MP /Zm193")
  729. add_definitions(-D_CRT_SECURE_NO_WARNINGS)
  730. endif()
  731. if (UNIX AND $ENV{COVERAGE}==1) # Coverage options (disables optimization)
  732. SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -O0") # debug, no optimisation
  733. SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} --coverage") # enabling coverage
  734. endif()
  735. # Prefer target-level compile definitions and options below (kept conservative).
  736. # Generate libvgears.
  737. if(NOT VGEARS_SOURCE_FILES)
  738. file(GLOB_RECURSE VGEARS_SOURCE_FILES RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} "*.cpp")
  739. list(LENGTH VGEARS_SOURCE_FILES _vgears_auto_count)
  740. message(STATUS "Auto-collected VGEARS_SOURCE_FILES count: ${_vgears_auto_count}")
  741. endif()
  742. # If installer is disabled, remove installer sources from the collected list
  743. if(NOT BUILD_INSTALLER)
  744. set(_removed_count 0)
  745. foreach(_f IN LISTS VGEARS_SOURCE_FILES)
  746. if(_f MATCHES "installer/")
  747. list(REMOVE_ITEM VGEARS_SOURCE_FILES ${_f})
  748. math(EXPR _removed_count "${_removed_count} + 1")
  749. endif()
  750. endforeach()
  751. if(_removed_count GREATER 0)
  752. message(STATUS "Removed ${_removed_count} installer source(s) because BUILD_INSTALLER=OFF")
  753. endif()
  754. endif()
  755. # Conservative global Qt include probe (ensure headers visible when
  756. # generating libvgears target). Prefer distro qt5 include locations.
  757. set(_qt_global_candidates /usr/include/x86_64-linux-gnu/qt5 /usr/include/qt5 /usr/include)
  758. foreach(_qinc IN LISTS _qt_global_candidates)
  759. if(EXISTS "${_qinc}/QtCore/QtGlobal")
  760. message(STATUS "Global probe: adding Qt include directory ${_qinc}")
  761. include_directories(BEFORE PRIVATE ${_qinc})
  762. break()
  763. endif()
  764. endforeach()
  765. # Ensure UI headers generated by uic are available before compiling
  766. # libvgears. Some build order setups (unity/PCH/cotire) may attempt to
  767. # compile sources that include generated `ui_*.h` before uic runs, so add
  768. # an explicit custom command/target to generate the header.
  769. set(_ui_src "${CMAKE_CURRENT_SOURCE_DIR}/installer/MainWindow.ui")
  770. # Place generated headers under the build tree parallel to the source dir
  771. # CMAKE_CURRENT_BINARY_DIR is <build>/src so append 'installer' (not
  772. # 'src/installer').
  773. set(_ui_out "${CMAKE_CURRENT_BINARY_DIR}/installer/ui_MainWindow.h")
  774. find_program(QT_UIC_EXECUTABLE NAMES uic uic-qt5 PATHS /usr/lib/qt5/bin /usr/bin /usr/local/bin)
  775. if(QT_UIC_EXECUTABLE AND EXISTS "${_ui_src}")
  776. add_custom_command(
  777. OUTPUT "${_ui_out}"
  778. COMMAND ${QT_UIC_EXECUTABLE} -o "${_ui_out}" "${_ui_src}"
  779. DEPENDS "${_ui_src}"
  780. COMMENT "Generating ui_MainWindow.h via uic"
  781. VERBATIM
  782. )
  783. add_custom_target(generate_ui_files DEPENDS "${_ui_out}")
  784. set(_GENERATED_UI_TARGET generate_ui_files)
  785. endif()
  786. # Exclude unit tests under installer/decompiler/test from the main
  787. # library to avoid pulling test-only dependencies (gtest/gmock).
  788. set(_test_removed_count 0)
  789. foreach(_f IN LISTS VGEARS_SOURCE_FILES)
  790. if(_f MATCHES "installer/decompiler/test/")
  791. list(REMOVE_ITEM VGEARS_SOURCE_FILES ${_f})
  792. math(EXPR _test_removed_count "${_test_removed_count} + 1")
  793. endif()
  794. endforeach()
  795. if(_test_removed_count GREATER 0)
  796. message(STATUS "Removed ${_test_removed_count} decompiler test source(s) from libvgears")
  797. endif()
  798. add_library(libvgears STATIC ${VGEARS_SOURCE_FILES})
  799. target_sources(libvgears PRIVATE installer/SfxDump.c)
  800. # Ensure generated ui headers are created before compiling libvgears
  801. if(DEFINED _GENERATED_UI_TARGET)
  802. add_dependencies(libvgears ${_GENERATED_UI_TARGET})
  803. # Generated ui headers live in <build>/src/installer
  804. target_include_directories(libvgears PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/installer")
  805. endif()
  806. # Ensure platform macro for scummsys.h selection on Unix
  807. if(UNIX)
  808. target_compile_definitions(libvgears PRIVATE POSIX)
  809. endif()
  810. if(USE_COTIRE)
  811. cotire(libvgears)
  812. endif()
  813. SET_PROPERTY(TARGET libvgears PROPERTY FOLDER "build/libvgears")
  814. # Attach include directories and compile definitions to `libvgears` target.
  815. target_include_directories(libvgears
  816. PUBLIC
  817. ${VGEARS_SOURCE_DIR}
  818. ${CMAKE_CURRENT_SOURCE_DIR}
  819. ${CMAKE_CURRENT_SOURCE_DIR}/installer
  820. ${CMAKE_CURRENT_BINARY_DIR}/installer
  821. ${Boost_INCLUDE_DIR}
  822. ${OIS_INCLUDE_DIRS}
  823. ${OGRE_INCLUDE_DIRS}
  824. ${OGRE_INCLUDE_DIRS}/Overlay
  825. ${OGRE_INCLUDE_DIRS}/Bites
  826. ${VGEARS_LUAJIT_INCLUDE_DIRS}
  827. ${QT_INCLUDE_DIRS}
  828. )
  829. if(DEFINED _GENERATED_UI_TARGET)
  830. target_include_directories(libvgears BEFORE PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/installer")
  831. endif()
  832. target_link_libraries(libvgears PUBLIC ${VGEARS_LUAJIT_LIBRARIES})
  833. target_compile_definitions(libvgears PUBLIC TIXML_USE_STL)
  834. if(NOT MSVC)
  835. target_compile_options(libvgears PRIVATE -fPIC)
  836. endif()
  837. # If Qt link libraries were detected (imported targets or fallback libs), link
  838. # them to libvgears so imported-target include directories are propagated to
  839. # installer/source compilation. This ensures Qt headers are available when
  840. # compiling installer sources into the static lib.
  841. if(QT_LINK_LIBS)
  842. message(STATUS "Linking libvgears with Qt libraries: ${QT_LINK_LIBS}")
  843. target_link_libraries(libvgears PUBLIC ${QT_LINK_LIBS})
  844. endif()
  845. # If QT_LINK_LIBS were provided but QT_INCLUDE_DIRS ended up empty (for example
  846. # when generic -l flags were injected), try a conservative probe for common Qt
  847. # include locations and attach them to the target so compiler `-I` flags are
  848. # present when building installer sources.
  849. if(QT_LINK_LIBS AND (NOT QT_INCLUDE_DIRS))
  850. set(_qt_probe_candidates /usr/include/qt5 /usr/include/x86_64-linux-gnu/qt5 /usr/include)
  851. foreach(_qi IN LISTS _qt_probe_candidates)
  852. if(EXISTS "${_qi}/QtCore/QtGlobal")
  853. message(STATUS "Detected Qt headers under ${_qi}; setting QT_INCLUDE_DIRS")
  854. set(QT_INCLUDE_DIRS ${_qi} CACHE PATH "Detected Qt include dir" FORCE)
  855. break()
  856. endif()
  857. endforeach()
  858. endif()
  859. if(QT_INCLUDE_DIRS)
  860. message(STATUS "Adding Qt include dirs to libvgears: ${QT_INCLUDE_DIRS}")
  861. target_include_directories(libvgears PUBLIC ${QT_INCLUDE_DIRS})
  862. endif()
  863. # Generate v-gears executable
  864. # Ensure installer sources are not compiled into the main executable; the
  865. # installer is built separately under `src/installer`. Remove any installer
  866. # sources from the source list used for the `v-gears` executable.
  867. foreach(_f IN LISTS VGEARS_SOURCE_FILES)
  868. if(_f MATCHES "^installer/")
  869. list(REMOVE_ITEM VGEARS_SOURCE_FILES ${_f})
  870. endif()
  871. endforeach()
  872. add_executable(v-gears ${VGEARS_SOURCE_FILES})
  873. SET_PROPERTY(TARGET v-gears PROPERTY FOLDER "build/v-gears")
  874. set(CPACK_PACKAGE_EXECUTABLES v-gears "v-gears")
  875. set(CPACK_WIX_PROGRAM_MENU_FOLDER "VGears")
  876. if(APPLE)
  877. target_link_libraries(v-gears "-framework CoreFoundation -framework Cocoa -framework IOKit" ${ois_lib})
  878. endif()
  879. if(WIN32 AND NOT (CMAKE_BUILD_TYPE MATCHES "Debug"))
  880. set_target_properties( v-gears PROPERTIES WIN32_EXECUTABLE ON )
  881. if (MSVC)
  882. set_target_properties(v-gears PROPERTIES LINK_FLAGS "/SUBSYSTEM:CONSOLE")
  883. endif()
  884. endif()
  885. set(VGEARS_LIBRARIES
  886. ${VGEARS_LUAJIT_LIBRARIES}
  887. ${OPENAL_LIBRARY}
  888. ${OGGVORBIS_LIBRARIES}
  889. ${OGRE_LIBRARIES}
  890. )
  891. # Ensure we have something for Boost; if BOOST_LINK_LIBS is empty, inject
  892. # generic `-lboost_*` flags directly so the system linker will attempt to
  893. # resolve them from standard library search paths.
  894. if(NOT BOOST_LINK_LIBS)
  895. if(USE_DETERMINISTIC_FALLBACKS)
  896. find_library(_boost_system_lib
  897. NAMES boost_system libboost_system
  898. HINTS /usr/lib /usr/lib/x86_64-linux-gnu /usr/local/lib
  899. PATH_SUFFIXES . lib lib64
  900. )
  901. set(_generic_boost_flags -lboost_program_options -lboost_filesystem -lboost_thread -lboost_chrono)
  902. if(_boost_system_lib)
  903. list(APPEND _generic_boost_flags -lboost_system)
  904. endif()
  905. set(BOOST_LINK_LIBS ${_generic_boost_flags})
  906. message(STATUS "Injecting generic Boost -l flags into link list: ${_generic_boost_flags}")
  907. else()
  908. message(WARNING "Boost not found and deterministic fallbacks disabled; build may fail. Install libboost-*-dev or provide Boost hints.")
  909. endif()
  910. endif()
  911. # `BOOST_LINK_LIBS` should have been computed earlier (imported targets,
  912. # find_package, or the robust per-component fallback). Append whatever was found
  913. # into the final link list for the executable.
  914. list(APPEND VGEARS_LIBRARIES ${BOOST_LINK_LIBS} ${OIS_LIBRARIES} ${TinyXML_LIBRARIES})
  915. if(QT_LINK_LIBS)
  916. list(APPEND VGEARS_LIBRARIES ${QT_LINK_LIBS})
  917. endif()
  918. message(STATUS "Resolved library variables:")
  919. message(STATUS " OPENAL_LIBRARY=${OPENAL_LIBRARY}")
  920. message(STATUS " OGGVORBIS_LIBRARIES=${OGGVORBIS_LIBRARIES}")
  921. message(STATUS " OGRE_LIBRARIES=${OGRE_LIBRARIES}")
  922. message(STATUS " Boost_LIBRARIES=${Boost_LIBRARIES}")
  923. message(STATUS " OIS_LIBRARIES=${OIS_LIBRARIES}")
  924. message(STATUS " TinyXML_LIBRARIES=${TinyXML_LIBRARIES}")
  925. if(MULTITHREADING)
  926. find_package (Threads REQUIRED) # Find Threads
  927. set(VGEARS_LIBRARIES
  928. ${VGEARS_LIBRARIES}
  929. ${CMAKE_THREAD_LIBS_INIT}
  930. )
  931. endif()
  932. message(STATUS "Final VGEARS_LIBRARIES list: ${VGEARS_LIBRARIES}")
  933. # If OgreBites SONAME exists on the system but wasn't picked up earlier, append
  934. # it directly to the final link list so WindowEventUtilities symbols are
  935. #resolved at link time.
  936. if(USE_DETERMINISTIC_FALLBACKS)
  937. if(EXISTS "/usr/lib/x86_64-linux-gnu/libOgreBites.so")
  938. list(FIND VGEARS_LIBRARIES "/usr/lib/x86_64-linux-gnu/libOgreBites.so" _found_bites)
  939. if(_found_bites EQUAL -1)
  940. list(APPEND VGEARS_LIBRARIES "/usr/lib/x86_64-linux-gnu/libOgreBites.so")
  941. message(STATUS "Appending system OgreBites to VGEARS_LIBRARIES: /usr/lib/x86_64-linux-gnu/libOgreBites.so")
  942. endif()
  943. endif()
  944. else()
  945. # When deterministic fallbacks are disabled, warn if OgreBites is likely
  946. # missing.
  947. if(NOT OGRE_LIBRARIES MATCHES ".*OgreBites.*")
  948. message(WARNING "OgreBites not present in OGRE_LIBRARIES and deterministic fallbacks are disabled. Link errors may occur if OGRE dev packages are not installed.")
  949. endif()
  950. endif()
  951. target_link_libraries(v-gears ${VGEARS_LIBRARIES})
  952. # Attach include dirs/defs/options to executable as well (uses same sources).
  953. target_include_directories(v-gears
  954. PRIVATE
  955. ${VGEARS_SOURCE_DIR}
  956. ${CMAKE_CURRENT_SOURCE_DIR}
  957. ${CMAKE_CURRENT_SOURCE_DIR}/installer
  958. ${CMAKE_CURRENT_BINARY_DIR}/installer
  959. ${Boost_INCLUDE_DIR}
  960. ${OIS_INCLUDE_DIRS}
  961. ${OGRE_INCLUDE_DIRS}
  962. ${OGRE_INCLUDE_DIRS}/Overlay
  963. ${OGRE_INCLUDE_DIRS}/Bites
  964. ${VGEARS_LUAJIT_INCLUDE_DIRS}
  965. ${QT_INCLUDE_DIRS}
  966. )
  967. # If UI files are generated by the uic custom target, make sure the executable
  968. # depends on it and can see the generated headers.
  969. if(DEFINED _GENERATED_UI_TARGET)
  970. add_dependencies(v-gears ${_GENERATED_UI_TARGET})
  971. target_include_directories(v-gears PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/installer")
  972. endif()
  973. # Ensure platform macro for scummsys.h selection on Unix when building the main
  974. # executable as well (same as done for libvgears).
  975. if(UNIX)
  976. target_compile_definitions(v-gears PRIVATE POSIX)
  977. endif()
  978. target_compile_definitions(v-gears PRIVATE TIXML_USE_STL)
  979. if(NOT MSVC)
  980. target_compile_options(v-gears PRIVATE -fPIC)
  981. endif()
  982. # Install v-gears.
  983. # TODO: Fix routes for installation
  984. if(WIN32 OR APPLE)
  985. install(TARGETS v-gears DESTINATION .)
  986. else()
  987. install(TARGETS v-gears RUNTIME DESTINATION ./games)
  988. endif()
  989. # If installer build is enabled, ensure Qt includes/links are available for the
  990. # `installer` subdirectory. Do this before adding the subdirectory so its
  991. # targets inherit the settings.
  992. if(BUILD_INSTALLER)
  993. # If pragmatic detection earlier set `QT_INCLUDE_DIRS`, expose them as
  994. # global include dirs so installer targets find headers.
  995. if(QT_INCLUDE_DIRS)
  996. include_directories(${QT_INCLUDE_DIRS})
  997. else()
  998. # Last-resort add common system Qt include paths.
  999. if(EXISTS "/usr/include/qt5/QtCore/QDir")
  1000. include_directories(/usr/include/qt5 /usr/include/x86_64-linux-gnu/qt5)
  1001. message(STATUS "Added generic Qt include paths: /usr/include/qt5")
  1002. endif()
  1003. endif()
  1004. # Make sure any QT_LINK_LIBS are visible to subdirectories by appending
  1005. # them to the global link list variable used when creating targets.
  1006. if(QT_LINK_LIBS)
  1007. list(APPEND VGEARS_LIBRARIES ${QT_LINK_LIBS})
  1008. endif()
  1009. message(STATUS "Building installer as requested (BUILD_INSTALLER=ON)")
  1010. add_subdirectory(installer)
  1011. endif()