# Copyright (C) 2002-2025 UFO: Alien Invasion. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # # See the GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cmake_minimum_required(VERSION 3.13) project(ufotestall DESCRIPTION "Unittest suite for UFO:AI.") find_package(CURL) find_package(JPEG) find_package(X11) set(OpenGL_GL_PREFERENCE "LEGACY") find_package(OpenGL) find_package(PNG) find_package(SDL "2" EXACT) find_package(ZLIB) find_package(Intl) find_package(OGG) find_package(Lua 5.3) find_package(SDL_mixer "2" EXACT) find_package(SDL_ttf "2" EXACT) find_package(VORBIS) find_package(MXML "3") find_package(GTest) set(UFOTESTALL_SOURCES ../client/battlescape/cl_actor.cpp ../client/battlescape/cl_battlescape.cpp ../client/battlescape/cl_camera.cpp ../client/battlescape/cl_hud.cpp ../client/battlescape/cl_hud_callbacks.cpp ../client/battlescape/cl_localentity.cpp ../client/battlescape/cl_parse.cpp ../client/battlescape/cl_particle.cpp ../client/battlescape/cl_radar.cpp ../client/battlescape/cl_spawn.cpp ../client/battlescape/cl_ugv.cpp ../client/battlescape/cl_view.cpp ../client/battlescape/events/e_main.cpp ../client/battlescape/events/e_parse.cpp ../client/battlescape/events/e_server.cpp ../client/battlescape/events/event/actor/e_event_actoradd.cpp ../client/battlescape/events/event/actor/e_event_actorappear.cpp ../client/battlescape/events/event/actor/e_event_actorclientaction.cpp ../client/battlescape/events/event/actor/e_event_actordie.cpp ../client/battlescape/events/event/actor/e_event_actorendshot.cpp ../client/battlescape/events/event/actor/e_event_actormove.cpp ../client/battlescape/events/event/actor/e_event_actorreactionfireabortshot.cpp ../client/battlescape/events/event/actor/e_event_actorreactionfireaddtarget.cpp ../client/battlescape/events/event/actor/e_event_actorreactionfirechange.cpp ../client/battlescape/events/event/actor/e_event_actorreactionfireremovetarget.cpp ../client/battlescape/events/event/actor/e_event_actorreactionfiretargetupdate.cpp ../client/battlescape/events/event/actor/e_event_actorreservationchange.cpp ../client/battlescape/events/event/actor/e_event_actorresetclientaction.cpp ../client/battlescape/events/event/actor/e_event_actorrevitalised.cpp ../client/battlescape/events/event/actor/e_event_actorshoot.cpp ../client/battlescape/events/event/actor/e_event_actorshoothidden.cpp ../client/battlescape/events/event/actor/e_event_actorstartshoot.cpp ../client/battlescape/events/event/actor/e_event_actorstatechange.cpp ../client/battlescape/events/event/actor/e_event_actorstats.cpp ../client/battlescape/events/event/actor/e_event_actorthrow.cpp ../client/battlescape/events/event/actor/e_event_actorturn.cpp ../client/battlescape/events/event/actor/e_event_actorwound.cpp ../client/battlescape/events/event/inventory/e_event_invadd.cpp ../client/battlescape/events/event/inventory/e_event_invammo.cpp ../client/battlescape/events/event/inventory/e_event_invdel.cpp ../client/battlescape/events/event/inventory/e_event_invreload.cpp ../client/battlescape/events/event/player/e_event_centerview.cpp ../client/battlescape/events/event/player/e_event_doendround.cpp ../client/battlescape/events/event/player/e_event_endroundannounce.cpp ../client/battlescape/events/event/player/e_event_reset.cpp ../client/battlescape/events/event/player/e_event_results.cpp ../client/battlescape/events/event/player/e_event_startgame.cpp ../client/battlescape/events/event/world/e_event_addbrushmodel.cpp ../client/battlescape/events/event/world/e_event_addedict.cpp ../client/battlescape/events/event/world/e_event_cameraappear.cpp ../client/battlescape/events/event/world/e_event_doorclose.cpp ../client/battlescape/events/event/world/e_event_dooropen.cpp ../client/battlescape/events/event/world/e_event_entappear.cpp ../client/battlescape/events/event/world/e_event_entdestroy.cpp ../client/battlescape/events/event/world/e_event_entperish.cpp ../client/battlescape/events/event/world/e_event_explode.cpp ../client/battlescape/events/event/world/e_event_particleappear.cpp ../client/battlescape/events/event/world/e_event_particlespawn.cpp ../client/battlescape/events/event/world/e_event_sound.cpp ../client/cgame/campaign/aliencargo.cpp ../client/cgame/campaign/itemcargo.cpp ../client/cgame/campaign/aliencontainment.cpp ../client/cgame/campaign/cl_game_campaign.cpp ../client/cgame/campaign/cp_aircraft.cpp ../client/cgame/campaign/cp_aircraft_callbacks.cpp ../client/cgame/campaign/cp_airfight.cpp ../client/cgame/campaign/cp_alien_interest.cpp ../client/cgame/campaign/cp_alienbase.cpp ../client/cgame/campaign/cp_aliencont.cpp ../client/cgame/campaign/cp_aliencont_callbacks.cpp ../client/cgame/campaign/cp_auto_mission.cpp ../client/cgame/campaign/cp_base.cpp ../client/cgame/campaign/cp_base_callbacks.cpp ../client/cgame/campaign/cp_basedefence_callbacks.cpp ../client/cgame/campaign/cp_building.cpp ../client/cgame/campaign/cp_campaign.cpp ../client/cgame/campaign/cp_capacity.cpp ../client/cgame/campaign/cp_cgame_callbacks.cpp ../client/cgame/campaign/cp_character.cpp ../client/cgame/campaign/cp_component.cpp ../client/cgame/campaign/cp_employee.cpp ../client/cgame/campaign/cp_employee_callbacks.cpp ../client/cgame/campaign/cp_event.cpp ../client/cgame/campaign/cp_event_callbacks.cpp ../client/cgame/campaign/cp_fightequip_callbacks.cpp ../client/cgame/campaign/cp_geoscape.cpp ../client/cgame/campaign/cp_hospital.cpp ../client/cgame/campaign/cp_hospital_callbacks.cpp ../client/cgame/campaign/cp_installation.cpp ../client/cgame/campaign/cp_installation_callbacks.cpp ../client/cgame/campaign/cp_mapfightequip.cpp ../client/cgame/campaign/cp_market.cpp ../client/cgame/campaign/cp_market_callbacks.cpp ../client/cgame/campaign/cp_messageoptions.cpp ../client/cgame/campaign/cp_messageoptions_callbacks.cpp ../client/cgame/campaign/cp_messages.cpp ../client/cgame/campaign/cp_mission_callbacks.cpp ../client/cgame/campaign/cp_mission_triggers.cpp ../client/cgame/campaign/cp_missions.cpp ../client/cgame/campaign/cp_nation.cpp ../client/cgame/campaign/cp_overlay.cpp ../client/cgame/campaign/cp_parse.cpp ../client/cgame/campaign/cp_popup.cpp ../client/cgame/campaign/cp_produce.cpp ../client/cgame/campaign/cp_produce_callbacks.cpp ../client/cgame/campaign/cp_radar.cpp ../client/cgame/campaign/cp_rank.cpp ../client/cgame/campaign/cp_research.cpp ../client/cgame/campaign/cp_research_callbacks.cpp ../client/cgame/campaign/cp_save.cpp ../client/cgame/campaign/cp_save_callbacks.cpp ../client/cgame/campaign/cp_statistics.cpp ../client/cgame/campaign/cp_team.cpp ../client/cgame/campaign/cp_team_callbacks.cpp ../client/cgame/campaign/cp_time.cpp ../client/cgame/campaign/cp_transfer.cpp ../client/cgame/campaign/cp_transfer_callbacks.cpp ../client/cgame/campaign/cp_ufo.cpp ../client/cgame/campaign/cp_ufo_callbacks.cpp ../client/cgame/campaign/cp_ufopedia.cpp ../client/cgame/campaign/cp_uforecovery.cpp ../client/cgame/campaign/cp_uforecovery_callbacks.cpp ../client/cgame/campaign/cp_xvi.cpp ../client/cgame/campaign/missions/cp_mission_baseattack.cpp ../client/cgame/campaign/missions/cp_mission_buildbase.cpp ../client/cgame/campaign/missions/cp_mission_harvest.cpp ../client/cgame/campaign/missions/cp_mission_intercept.cpp ../client/cgame/campaign/missions/cp_mission_recon.cpp ../client/cgame/campaign/missions/cp_mission_rescue.cpp ../client/cgame/campaign/missions/cp_mission_supply.cpp ../client/cgame/campaign/missions/cp_mission_terror.cpp ../client/cgame/campaign/missions/cp_mission_ufocarrier.cpp ../client/cgame/campaign/missions/cp_mission_xvi.cpp ../client/cgame/cl_game.cpp ../client/cgame/cl_game_team.cpp ../client/cgame/cl_map_callbacks.cpp ../client/cgame/multiplayer/cl_game_multiplayer.cpp ../client/cgame/multiplayer/mp_callbacks.cpp ../client/cgame/multiplayer/mp_serverlist.cpp ../client/cgame/skirmish/cl_game_skirmish.cpp ../client/cinematic/cl_cinematic.cpp ../client/cinematic/cl_cinematic_ogm.cpp ../client/cinematic/cl_cinematic_roq.cpp ../client/cinematic/cl_sequence.cpp ../client/cl_console.cpp ../client/cl_http.cpp ../client/cl_inventory.cpp ../client/cl_inventory_callbacks.cpp ../client/cl_irc.cpp ../client/cl_language.cpp ../client/cl_main.cpp ../client/cl_menu.cpp ../client/cl_screen.cpp ../client/cl_team.cpp ../client/cl_tip.cpp ../client/cl_tutorials.cpp ../client/cl_video.cpp ../client/input/cl_input.cpp ../client/input/cl_joystick.cpp ../client/input/cl_keys.cpp ../client/renderer/r_array.cpp ../client/renderer/r_bsp.cpp ../client/renderer/r_corona.cpp ../client/renderer/r_draw.cpp ../client/renderer/r_entity.cpp ../client/renderer/r_flare.cpp ../client/renderer/r_font.cpp ../client/renderer/r_framebuffer.cpp ../client/renderer/r_geoscape.cpp ../client/renderer/r_grass.cpp ../client/renderer/r_image.cpp ../client/renderer/r_light.cpp ../client/renderer/r_lightmap.cpp ../client/renderer/r_main.cpp ../client/renderer/r_material.cpp ../client/renderer/r_matrix.cpp ../client/renderer/r_mesh.cpp ../client/renderer/r_mesh_anim.cpp ../client/renderer/r_misc.cpp ../client/renderer/r_model.cpp ../client/renderer/r_model_alias.cpp ../client/renderer/r_model_brush.cpp ../client/renderer/r_model_md2.cpp ../client/renderer/r_model_md3.cpp ../client/renderer/r_model_obj.cpp ../client/renderer/r_particle.cpp ../client/renderer/r_program.cpp ../client/renderer/r_sdl.cpp ../client/renderer/r_sphere.cpp ../client/renderer/r_state.cpp ../client/renderer/r_surface.cpp ../client/renderer/r_thread.cpp ../client/renderer/r_weather.cpp ../client/sound/s_main.cpp ../client/sound/s_mix.cpp ../client/sound/s_mumble.cpp ../client/sound/s_music.cpp ../client/sound/s_sample.cpp ../client/ui/node/ui_node_abstractnode.cpp ../client/ui/node/ui_node_abstractoption.cpp ../client/ui/node/ui_node_abstractscrollable.cpp ../client/ui/node/ui_node_abstractscrollbar.cpp ../client/ui/node/ui_node_abstractvalue.cpp ../client/ui/node/ui_node_bar.cpp ../client/ui/node/ui_node_base.cpp ../client/ui/node/ui_node_baseinventory.cpp ../client/ui/node/ui_node_battlescape.cpp ../client/ui/node/ui_node_button.cpp ../client/ui/node/ui_node_checkbox.cpp ../client/ui/node/ui_node_container.cpp ../client/ui/node/ui_node_controls.cpp ../client/ui/node/ui_node_data.cpp ../client/ui/node/ui_node_editor.cpp ../client/ui/node/ui_node_geoscape.cpp ../client/ui/node/ui_node_image.cpp ../client/ui/node/ui_node_item.cpp ../client/ui/node/ui_node_linechart.cpp ../client/ui/node/ui_node_material_editor.cpp ../client/ui/node/ui_node_messagelist.cpp ../client/ui/node/ui_node_model.cpp ../client/ui/node/ui_node_option.cpp ../client/ui/node/ui_node_optionlist.cpp ../client/ui/node/ui_node_optiontree.cpp ../client/ui/node/ui_node_panel.cpp ../client/ui/node/ui_node_radar.cpp ../client/ui/node/ui_node_radiobutton.cpp ../client/ui/node/ui_node_rows.cpp ../client/ui/node/ui_node_selectbox.cpp ../client/ui/node/ui_node_sequence.cpp ../client/ui/node/ui_node_special.cpp ../client/ui/node/ui_node_spinner.cpp ../client/ui/node/ui_node_string.cpp ../client/ui/node/ui_node_tab.cpp ../client/ui/node/ui_node_tbar.cpp ../client/ui/node/ui_node_text.cpp ../client/ui/node/ui_node_text2.cpp ../client/ui/node/ui_node_textentry.cpp ../client/ui/node/ui_node_textlist.cpp ../client/ui/node/ui_node_texture.cpp ../client/ui/node/ui_node_timer.cpp ../client/ui/node/ui_node_video.cpp ../client/ui/node/ui_node_vscrollbar.cpp ../client/ui/node/ui_node_window.cpp ../client/ui/node/ui_node_zone.cpp ../client/ui/swig/ui_lua_shared.cpp ../client/ui/ui_actions.cpp ../client/ui/ui_behaviour.cpp ../client/ui/ui_components.cpp ../client/ui/ui_data.cpp ../client/ui/ui_dragndrop.cpp ../client/ui/ui_draw.cpp ../client/ui/ui_expression.cpp ../client/ui/ui_font.cpp ../client/ui/ui_input.cpp ../client/ui/ui_lua.cpp ../client/ui/ui_main.cpp ../client/ui/ui_node.cpp ../client/ui/ui_nodes.cpp ../client/ui/ui_parse.cpp ../client/ui/ui_popup.cpp ../client/ui/ui_render.cpp ../client/ui/ui_sound.cpp ../client/ui/ui_sprite.cpp ../client/ui/ui_timer.cpp ../client/ui/ui_tooltip.cpp ../client/ui/ui_windows.cpp ../client/web/web_cgame.cpp ../client/web/web_main.cpp ../client/cl_lua.cpp ../client/DateTime.cpp ../common/binaryexpressionparser.cpp ../common/bsp.cpp ../common/cmd.cpp ../common/cmodel.cpp ../common/common.cpp ../common/cvar.cpp ../common/dbuffer.cpp ../common/files.cpp ../common/grid.cpp ../common/hashtable.cpp ../common/http.cpp ../common/ioapi.cpp ../common/list.cpp ../common/md4.cpp ../common/md5.cpp ../common/mem.cpp ../common/msg.cpp ../common/net.cpp ../common/netpack.cpp ../common/pqueue.cpp ../common/routing.cpp ../common/scripts.cpp ../common/scripts_lua.cpp ../common/sha1.cpp ../common/sha2.cpp ../common/tracing.cpp ../common/unzip.cpp ../common/xml.cpp ../game/chr_shared.cpp ../game/g_actor.cpp ../game/g_ai.cpp ../game/g_ai_lua.cpp ../game/g_camera.cpp ../game/g_client.cpp ../game/g_cmds.cpp ../game/g_combat.cpp ../game/g_edicts.cpp ../game/g_events.cpp ../game/g_func.cpp ../game/g_health.cpp ../game/g_inventory.cpp ../game/g_main.cpp ../game/g_match.cpp ../game/g_mission.cpp ../game/g_morale.cpp ../game/g_move.cpp ../game/g_reaction.cpp ../game/g_round.cpp ../game/g_spawn.cpp ../game/g_stats.cpp ../game/g_svcmds.cpp ../game/g_trigger.cpp ../game/g_utils.cpp ../game/g_vis.cpp ../game/inv_shared.cpp ../game/inventory.cpp ../game/q_shared.cpp ../server/sv_ccmds.cpp ../server/sv_game.cpp ../server/sv_init.cpp ../server/sv_log.cpp ../server/sv_main.cpp ../server/sv_mapcycle.cpp ../server/sv_rma.cpp ../server/sv_send.cpp ../server/sv_user.cpp ../server/sv_world.cpp ../shared/aabb.cpp ../shared/bfd.cpp ../shared/byte.cpp ../shared/entitiesdef.cpp ../shared/images.cpp ../shared/infostring.cpp ../shared/mathlib.cpp ../shared/mathlib_extra.cpp ../shared/parse.cpp ../shared/shared.cpp ../shared/stringhunk.cpp ../shared/utf8.cpp test_all.cpp test_campaign.cpp test_character.cpp test_dbuffer.cpp test_events.cpp test_game.cpp test_generic.cpp test_inventory.cpp test_mapdef.cpp test_parser.cpp test_particles.cpp test_renderer.cpp test_rma.cpp test_routing.cpp test_scripts.cpp test_shared.cpp test_ui.cpp test_ui_level2.cpp test_webapi.cpp ../libs/mumble/libmumblelink.c ) # platform specific sources if(WIN32) LIST(APPEND UFOTESTALL_SOURCES ../ports/windows/win_backtrace.cpp ../ports/windows/win_console.cpp ../ports/windows/win_shared.cpp ) elseif(UNIX) LIST(APPEND UFOTESTALL_SOURCES ../ports/unix/unix_console.cpp ../ports/unix/unix_files.cpp ../ports/unix/unix_shared.cpp ../ports/unix/unix_main.cpp ) elseif(SOLARIS) LIST(APPEND UFOTESTALL_SOURCES ../ports/unix/unix_console.cpp ../ports/unix/unix_files.cpp ../ports/unix/unix_shared.cpp ../ports/unix/unix_main.cpp ) elseif(APPLE) LIST(APPEND UFOTESTALL_SOURCES ../ports/unix/unix_console.cpp ../ports/unix/unix_files.cpp ../ports/unix/unix_shared.cpp ../ports/unix/unix_main.cpp ) endif() # ufotestall is executable add_executable(${PROJECT_NAME} EXCLUDE_FROM_ALL ${UFOTESTALL_SOURCES}) add_dependencies(${PROJECT_NAME} "game") # For generic no-config case (e.g. with mingw, gcc, ...) set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) # For multi-config builds like msvc foreach(OUTPUTCONFIG ${CMAKE_CONFIGURATION_TYPES}) string(TOUPPER ${OUTPUTCONFIG} OUTPUTCONFIG) set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY_${OUTPUTCONFIG} ${CMAKE_BINARY_DIR}) endforeach() target_compile_definitions(${PROJECT_NAME} PRIVATE -DCOMPILE_UFO) target_compile_definitions(${PROJECT_NAME} PRIVATE -DCOMPILE_UNITTESTS) target_compile_definitions(${PROJECT_NAME} PRIVATE -DHARD_LINKED_GAME) target_compile_definitions(${PROJECT_NAME} PRIVATE -DHARD_LINKED_CGAME) target_include_directories(${PROJECT_NAME} PRIVATE ../libs/mumble PRIVATE ${LUA_INCLUDE_DIR} PRIVATE ${SDL_INCLUDE_DIR} PRIVATE ${SDLMIXER_INCLUDE_DIR} PRIVATE ${SDLTTF_INCLUDE_DIR} PRIVATE ${CURL_INCLUDE_DIRS} PRIVATE ${VORBIS_INCLUDE_DIR} PRIVATE ${OGG_INCLUDE_DIR} PRIVATE ${JPEG_INCLUDE_DIRS} PRIVATE ${PNG_INCLUDE_DIRS} PRIVATE ${Intl_INCLUDE_DIRS} PRIVATE ${ZLIB_INCLUDE_DIRS} PRIVATE ${X11_INCLUDE_DIR} PRIVATE ${MXML_INCLUDE_DIR} PRIVATE ${GTEST_INCLUDE_DIRS} ) if(MINGW) target_link_libraries(${PROJECT_NAME} mingw32 ) endif() target_link_libraries(${PROJECT_NAME} ${LUA_LIBRARY} ${SDL_LIBRARY_MAIN} ${SDL_LIBRARY} ${SDL_MIXER_LIBRARIES} ${SDL_TTF_LIBRARIES} ${CURL_LIBRARIES} ${VORBIS_LIBRARY} ${OGG_LIBRARIES} ${JPEG_LIBRARIES} ${PNG_LIBRARIES} ${ZLIB_LIBRARIES} ${X11_LIBRARIES} ${MXML_LIBRARY} ${GTEST_LIBRARIES} ) if(WIN32) target_link_libraries(${PROJECT_NAME} opengl32 imm32 ${Intl_LIBRARIES} version winmm Ws2_32 ) elseif(APPLE) target_link_libraries(${PROJECT_NAME} ${Intl_LIBRARIES} ) elseif(UNIX) target_link_libraries(${PROJECT_NAME} GL ) if(NOT CMAKE_SYSTEM_NAME MATCHES "OpenBSD") target_link_libraries(${PROJECT_NAME} rt ) endif() endif()