799 lines
30 KiB
CMake
799 lines
30 KiB
CMake
#
|
|
# Singe 3
|
|
# Copyright (C) 2006-2026 Scott Duensing <scott@kangaroopunch.com>
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public Licens
|
|
# as published by the Free Software Foundation; either version 3
|
|
# 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., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
# 02110-1301, USA.
|
|
#
|
|
|
|
|
|
cmake_minimum_required(VERSION 3.22)
|
|
project(singe2 VERSION 3.00 LANGUAGES C CXX)
|
|
|
|
set(CMAKE_C_STANDARD 11)
|
|
set(CMAKE_C_STANDARD_REQUIRED ON)
|
|
|
|
# The copyright end year tracks the build date so nothing has to be hand edited.
|
|
string(TIMESTAMP SINGE_COPYRIGHT_END_YEAR "%Y")
|
|
|
|
|
|
if(NOT DEFINED KANGAROO_OS)
|
|
set(KANGAROO_OS linux)
|
|
endif()
|
|
if(NOT DEFINED KANGAROO_ARCH)
|
|
set(KANGAROO_ARCH x86_64)
|
|
endif()
|
|
|
|
# Where the superbuild installs the third party libraries for this platform. SINGE_TREE lets a
|
|
# second toolchain for the same platform keep its own tree (the zig Linux build beside the gcc one).
|
|
if(NOT DEFINED SINGE_TREE)
|
|
set(SINGE_TREE ${KANGAROO_OS})
|
|
endif()
|
|
set(BUILD_DIR ${CMAKE_SOURCE_DIR}/.builddir/${SINGE_TREE}/${KANGAROO_ARCH})
|
|
set(GENERATED_DIR ${CMAKE_BINARY_DIR}/generated)
|
|
file(MAKE_DIRECTORY ${GENERATED_DIR})
|
|
|
|
# With SINGE_SUPERBUILD on (the presets' default) this configure builds the vendored libraries
|
|
# first and then Singe as a nested project; see cmake/Superbuild.cmake.
|
|
option(SINGE_SUPERBUILD "Build the vendored libraries, then Singe" OFF)
|
|
if(SINGE_SUPERBUILD)
|
|
include(cmake/Superbuild.cmake)
|
|
return()
|
|
endif()
|
|
|
|
|
|
# ===== Host tools needed to generate embedded resources =====
|
|
|
|
find_program(IMAGEMAGICK NAMES magick convert)
|
|
if(NOT IMAGEMAGICK)
|
|
message(FATAL_ERROR "ImageMagick (magick or convert) is required to render the embedded images.")
|
|
endif()
|
|
find_program(FFMPEG_TOOL NAMES ffmpeg)
|
|
if(NOT FFMPEG_TOOL)
|
|
message(FATAL_ERROR "ffmpeg is required to build the menu background video.")
|
|
endif()
|
|
find_program(LUA_TOOL NAMES lua5.4 lua)
|
|
if(NOT LUA_TOOL)
|
|
message(FATAL_ERROR "A Lua interpreter is required to generate the LuaSec option table.")
|
|
endif()
|
|
find_program(ASCIIDOCTOR_PDF NAMES asciidoctor-pdf)
|
|
if(NOT ASCIIDOCTOR_PDF)
|
|
message(FATAL_ERROR "asciidoctor-pdf is required to build the embedded manual (gem install asciidoctor-pdf rouge).")
|
|
endif()
|
|
find_program(ASCIIDOCTOR NAMES asciidoctor)
|
|
|
|
|
|
# ===== Generated sources =====
|
|
|
|
# Version header and Windows resources come from the project() line above.
|
|
configure_file(src/version.h.in ${GENERATED_DIR}/version.h @ONLY)
|
|
configure_file(src/singe.rc.in ${GENERATED_DIR}/singe.rc @ONLY)
|
|
|
|
# LuaSec needs its headers reachable as <luasocket/...>.
|
|
file(GLOB LUASOCKET_HEADERS thirdparty/luasocket/src/*.h)
|
|
file(COPY ${LUASOCKET_HEADERS} DESTINATION ${GENERATED_DIR}/include/luasocket)
|
|
|
|
# LuaSec option table generated from the OpenSSL headers that were built.
|
|
add_custom_command(
|
|
OUTPUT ${GENERATED_DIR}/luasec_options.c
|
|
COMMAND ${CMAKE_COMMAND} -DOUTPUT=${GENERATED_DIR}/luasec_options.c -DCOMMAND=${LUA_TOOL} "-DARGS=${CMAKE_SOURCE_DIR}/thirdparty/luasec/src/options.lua;-g;${BUILD_DIR}/include/openssl/ssl.h" -P ${CMAKE_SOURCE_DIR}/cmake/runToFile.cmake
|
|
DEPENDS thirdparty/luasec/src/options.lua ${BUILD_DIR}/include/openssl/ssl.h cmake/runToFile.cmake
|
|
COMMENT "Generating LuaSec options"
|
|
VERBATIM
|
|
)
|
|
|
|
# Embeds a file as a C array. The symbol name is derived from the file name, as xxd does.
|
|
set(EMBEDDED_HEADERS)
|
|
function(singeEmbed input output prefix)
|
|
get_filename_component(name ${input} NAME)
|
|
string(MAKE_C_IDENTIFIER "${prefix}${name}" symbol)
|
|
get_filename_component(guardName ${output} NAME)
|
|
string(MAKE_C_IDENTIFIER "${guardName}" guard)
|
|
string(TOUPPER "${guard}" guard)
|
|
add_custom_command(
|
|
OUTPUT ${output}
|
|
COMMAND ${CMAKE_COMMAND} -DINPUT=${input} -DOUTPUT=${output} -DGUARD=${guard} -DSYMBOL=${symbol} -DCOPYRIGHT_END_YEAR=${SINGE_COPYRIGHT_END_YEAR} -P ${CMAKE_SOURCE_DIR}/cmake/embed.cmake
|
|
DEPENDS ${input} cmake/embed.cmake
|
|
COMMENT "Embedding ${name}"
|
|
VERBATIM
|
|
)
|
|
set(EMBEDDED_HEADERS ${EMBEDDED_HEADERS} ${output} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# The canvas size of a GIMP image, from the XCF header (ImageMagick only sees the layers, and its
|
|
# flatten crops to the first one).
|
|
function(singeXcfCanvas xcf widthVar heightVar)
|
|
file(READ ${xcf} header LIMIT 22 HEX)
|
|
string(SUBSTRING ${header} 28 8 widthHex)
|
|
string(SUBSTRING ${header} 36 8 heightHex)
|
|
math(EXPR width "0x${widthHex}")
|
|
math(EXPR height "0x${heightHex}")
|
|
set(${widthVar} ${width} PARENT_SCOPE)
|
|
set(${heightVar} ${height} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Renders assets/<source>.xcf as <name>.png the way GIMP would: every layer at its offset onto the
|
|
# image's own canvas, anything outside it clipped.
|
|
function(singeRenderImage name source)
|
|
singeXcfCanvas(${CMAKE_SOURCE_DIR}/assets/${source}.xcf width height)
|
|
add_custom_command(
|
|
OUTPUT ${GENERATED_DIR}/${name}.png
|
|
COMMAND ${IMAGEMAGICK} -background "rgba(0,0,0,0)" -size ${width}x${height} xc:none ${CMAKE_SOURCE_DIR}/assets/${source}.xcf -flatten ${GENERATED_DIR}/${name}.png
|
|
DEPENDS assets/${source}.xcf
|
|
COMMENT "Rendering ${name}.png (${width}x${height})"
|
|
VERBATIM
|
|
)
|
|
endfunction()
|
|
|
|
# Renders a layered image and embeds the PNG.
|
|
function(singeEmbedImage name)
|
|
singeRenderImage(${name} ${name})
|
|
singeEmbed(${GENERATED_DIR}/${name}.png ${GENERATED_DIR}/${name}.h "")
|
|
set(EMBEDDED_HEADERS ${EMBEDDED_HEADERS} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Embeds a Lua module from the third party tree.
|
|
function(singeEmbedLua path prefix)
|
|
get_filename_component(name ${path} NAME_WE)
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/${path} ${GENERATED_DIR}/${prefix}${name}_lua.h "${prefix}")
|
|
set(EMBEDDED_HEADERS ${EMBEDDED_HEADERS} PARENT_SCOPE)
|
|
endfunction()
|
|
|
|
# Images
|
|
singeEmbedImage(font)
|
|
# The icon is drawn large; the window gets a 128 pixel copy and the Windows .ico the usual sizes,
|
|
# both cut from a square, transparent-padded render so a non-square source keeps its proportions.
|
|
set(ICON_SIZE 1024)
|
|
singeRenderImage(iconFull icon)
|
|
add_custom_command(
|
|
OUTPUT ${GENERATED_DIR}/iconSquare.png
|
|
COMMAND ${IMAGEMAGICK} ${GENERATED_DIR}/iconFull.png -background "rgba(0,0,0,0)" -resize "${ICON_SIZE}x${ICON_SIZE}>" -gravity center -extent ${ICON_SIZE}x${ICON_SIZE} ${GENERATED_DIR}/iconSquare.png
|
|
DEPENDS ${GENERATED_DIR}/iconFull.png
|
|
COMMENT "Rendering iconSquare.png"
|
|
VERBATIM
|
|
)
|
|
add_custom_command(
|
|
OUTPUT ${GENERATED_DIR}/icon.png
|
|
COMMAND ${IMAGEMAGICK} ${GENERATED_DIR}/iconSquare.png -resize 128x128 ${GENERATED_DIR}/icon.png
|
|
DEPENDS ${GENERATED_DIR}/iconSquare.png
|
|
COMMENT "Rendering icon.png"
|
|
VERBATIM
|
|
)
|
|
singeEmbed(${GENERATED_DIR}/icon.png ${GENERATED_DIR}/icon.h "")
|
|
singeEmbedImage(kangarooPunchLogo)
|
|
singeEmbedImage(singeLogo)
|
|
|
|
# Windows icon for the resource file.
|
|
add_custom_command(
|
|
OUTPUT ${GENERATED_DIR}/icon.ico
|
|
COMMAND ${IMAGEMAGICK} ${GENERATED_DIR}/iconSquare.png -define icon:auto-resize=256,64,48,32,16 ${GENERATED_DIR}/icon.ico
|
|
DEPENDS ${GENERATED_DIR}/iconSquare.png
|
|
COMMENT "Rendering icon.ico"
|
|
VERBATIM
|
|
)
|
|
|
|
# Support files extracted at first run.
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/assets/Framework.singe ${GENERATED_DIR}/Framework_singe.h "")
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/assets/controls.cfg ${GENERATED_DIR}/controls_cfg.h "")
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/assets/settings.cfg ${GENERATED_DIR}/settings_cfg.h "")
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/assets/Menu.singe ${GENERATED_DIR}/Menu_singe.h "")
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/assets/MenuClassic.singe ${GENERATED_DIR}/MenuClassic_singe.h "")
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/assets/Menu.rml ${GENERATED_DIR}/Menu_rml.h "")
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/assets/menu.rcss ${GENERATED_DIR}/menu_rcss.h "")
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/assets/gui.rcss ${GENERATED_DIR}/gui_rcss.h "")
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/assets/scoreBezel.rml ${GENERATED_DIR}/scoreBezel_rml.h "")
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/assets/scoreBezel.rcss ${GENERATED_DIR}/scoreBezel_rcss.h "")
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/assets/subtitle.rml ${GENERATED_DIR}/subtitle_rml.h "")
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/assets/subtitle.rcss ${GENERATED_DIR}/subtitle_rcss.h "")
|
|
singeEmbed(${CMAKE_SOURCE_DIR}/assets/FreeSansBold.ttf ${GENERATED_DIR}/FreeSansBold_ttf.h "")
|
|
|
|
# Menu background video: two clips cropped to 4:3, scaled to 720x480, keyframed every second so the
|
|
# menu's seeks are instant and the engine's keyframe warning stays quiet, and joined.
|
|
file(WRITE ${GENERATED_DIR}/menuBackground.txt "file ${GENERATED_DIR}/menuBackground1.mkv\nfile ${GENERATED_DIR}/menuBackground2.mkv\n")
|
|
add_custom_command(
|
|
OUTPUT ${GENERATED_DIR}/menuBackground.mkv
|
|
COMMAND ${FFMPEG_TOOL} -y -loglevel error -i "${CMAKE_SOURCE_DIR}/assets/Singe Engine Intro.mpg" -filter:v "crop=ih/3*4:ih,scale=720:480" -c:v libx264 -force_key_frames "expr:gte(t,n_forced)" -c:a aac -f matroska ${GENERATED_DIR}/menuBackground1.mkv
|
|
COMMAND ${FFMPEG_TOOL} -y -loglevel error -i ${CMAKE_SOURCE_DIR}/assets/180503_01_PurpleGrid.mp4 -filter:v "crop=ih/3*4:ih,scale=720:480" -c:v libx264 -force_key_frames "expr:gte(t,n_forced)" -c:a aac -f matroska ${GENERATED_DIR}/menuBackground2.mkv
|
|
COMMAND ${FFMPEG_TOOL} -y -loglevel error -f concat -safe 0 -i ${GENERATED_DIR}/menuBackground.txt -c copy ${GENERATED_DIR}/menuBackground.mkv
|
|
DEPENDS "assets/Singe Engine Intro.mpg" assets/180503_01_PurpleGrid.mp4
|
|
COMMENT "Building menuBackground.mkv"
|
|
VERBATIM
|
|
)
|
|
singeEmbed(${GENERATED_DIR}/menuBackground.mkv ${GENERATED_DIR}/menuBackground_mkv.h "")
|
|
|
|
# Calibration click for the menu's audio delay screen: 20 ms of white noise with a fast fade.
|
|
add_custom_command(
|
|
OUTPUT ${GENERATED_DIR}/click.wav
|
|
COMMAND ${FFMPEG_TOOL} -y -loglevel error -f lavfi -i "anoisesrc=d=0.02:c=white:r=44100:a=0.6" -af "afade=t=out:st=0:d=0.02:curve=exp" -ac 1 -c:a pcm_s16le ${GENERATED_DIR}/click.wav
|
|
COMMENT "Building click.wav"
|
|
VERBATIM
|
|
)
|
|
singeEmbed(${GENERATED_DIR}/click.wav ${GENERATED_DIR}/click_wav.h "")
|
|
|
|
# Manual, rendered from the AsciiDoc source into the top-level build directory beside the binaries
|
|
# (build-docs.sh writes the same files) and shipped inside the binary.
|
|
set(MANUAL_DIR ${CMAKE_SOURCE_DIR}/.builddir)
|
|
add_custom_command(
|
|
OUTPUT ${MANUAL_DIR}/Manual.pdf
|
|
COMMAND ${CMAKE_COMMAND} -E make_directory ${MANUAL_DIR}
|
|
COMMAND ${ASCIIDOCTOR_PDF} -a revnumber=${PROJECT_VERSION} ${CMAKE_SOURCE_DIR}/docs/Manual.adoc -o ${MANUAL_DIR}/Manual.pdf
|
|
DEPENDS docs/Manual.adoc
|
|
COMMENT "Rendering Manual.pdf"
|
|
VERBATIM
|
|
)
|
|
singeEmbed(${MANUAL_DIR}/Manual.pdf ${GENERATED_DIR}/Manual_pdf.h "")
|
|
|
|
# Lua libraries
|
|
singeEmbedLua(thirdparty/luasocket/src/ftp.lua "")
|
|
singeEmbedLua(thirdparty/luasocket/src/headers.lua "")
|
|
singeEmbedLua(thirdparty/luasocket/src/http.lua "")
|
|
singeEmbedLua(thirdparty/luasocket/src/ltn12.lua "")
|
|
singeEmbedLua(thirdparty/luasocket/src/mbox.lua "")
|
|
singeEmbedLua(thirdparty/luasocket/src/mime.lua "")
|
|
singeEmbedLua(thirdparty/luasocket/src/smtp.lua "")
|
|
singeEmbedLua(thirdparty/luasocket/src/socket.lua "")
|
|
singeEmbedLua(thirdparty/luasocket/src/tp.lua "")
|
|
singeEmbedLua(thirdparty/luasocket/src/url.lua "")
|
|
singeEmbedLua(thirdparty/luasec/src/https.lua "")
|
|
singeEmbedLua(thirdparty/luasec/src/ssl.lua "")
|
|
singeEmbedLua(thirdparty/librs232/bindings/lua/rs232.lua "")
|
|
singeEmbedLua(thirdparty/copas/src/copas.lua "")
|
|
singeEmbedLua(thirdparty/copas/src/copas/ftp.lua "copas_")
|
|
singeEmbedLua(thirdparty/copas/src/copas/future.lua "copas_")
|
|
singeEmbedLua(thirdparty/copas/src/copas/http.lua "copas_")
|
|
singeEmbedLua(thirdparty/copas/src/copas/smtp.lua "copas_")
|
|
singeEmbedLua(thirdparty/copas/src/copas/lock.lua "copas_")
|
|
singeEmbedLua(thirdparty/copas/src/copas/queue.lua "copas_")
|
|
singeEmbedLua(thirdparty/copas/src/copas/semaphore.lua "copas_")
|
|
singeEmbedLua(thirdparty/copas/src/copas/timer.lua "copas_")
|
|
singeEmbedLua(thirdparty/binaryheap.lua/src/binaryheap.lua "")
|
|
singeEmbedLua(thirdparty/timerwheel.lua/src/timerwheel/timerwheel.lua "")
|
|
singeEmbedLua(thirdparty/json.lua/json.lua "")
|
|
|
|
# Optional HTML manual for browsing: cmake --build . --target docs
|
|
if(ASCIIDOCTOR)
|
|
add_custom_target(docs
|
|
COMMAND ${ASCIIDOCTOR} -a revnumber=${PROJECT_VERSION} ${CMAKE_SOURCE_DIR}/docs/Manual.adoc -o ${MANUAL_DIR}/Manual.html
|
|
DEPENDS ${MANUAL_DIR}/Manual.pdf
|
|
COMMENT "Rendering Manual.html"
|
|
VERBATIM
|
|
)
|
|
endif()
|
|
|
|
|
|
# ===== Sources =====
|
|
|
|
set(SINGE_SOURCE
|
|
src/common.h
|
|
src/embedded.h
|
|
src/frameFile.c
|
|
src/rotoZoom.c
|
|
src/rotoZoom.h
|
|
src/frameFile.h
|
|
src/main.c
|
|
src/main.h
|
|
src/pack.c
|
|
src/pack.h
|
|
src/particles.c
|
|
src/particles.h
|
|
src/physics.h
|
|
src/navRecast.cpp
|
|
src/physicsJolt.cpp
|
|
src/gui.cpp
|
|
src/gui.h
|
|
src/guiRender.cpp
|
|
src/guiRender.h
|
|
src/hdr.c
|
|
src/ktx2.h
|
|
src/ktx2Basis.cpp
|
|
thirdparty/basis_universal/transcoder/basisu_transcoder.cpp
|
|
src/model.c
|
|
src/model.h
|
|
src/math3d.c
|
|
src/math3d.h
|
|
src/scene.c
|
|
src/scene.h
|
|
src/singe.c
|
|
src/singe.h
|
|
src/stddclmr.h
|
|
src/util.c
|
|
src/util.h
|
|
src/videoPlayer.c
|
|
src/videoPlayer.h
|
|
src/vfs.c
|
|
src/vfs.h
|
|
)
|
|
|
|
# The binding reports this from sqlite3.lversion(); it is the version of thirdparty/lsqlite3/lsqlite3.c.
|
|
set(LSQLITE_VERSION "0.9.7")
|
|
set(SQLITE_SOURCE
|
|
thirdparty/sqlite/sqlite3.c
|
|
thirdparty/sqlite/sqlite3.h
|
|
thirdparty/lsqlite3/lsqlite3.c
|
|
)
|
|
set_source_files_properties(thirdparty/lsqlite3/lsqlite3.c PROPERTIES COMPILE_DEFINITIONS "LSQLITE_VERSION=\"${LSQLITE_VERSION}\"")
|
|
|
|
set(ARG_PARSER_SOURCE
|
|
thirdparty/arg_parser/carg_parser.c
|
|
thirdparty/arg_parser/carg_parser.h
|
|
)
|
|
|
|
file(GLOB LUA_SOURCE thirdparty/lua/src/*.c thirdparty/lua/src/*.h)
|
|
list(FILTER LUA_SOURCE EXCLUDE REGEX "/(lua|luac|onelua)\\.c$")
|
|
|
|
set(LUA_FILESYSTEM_SOURCE
|
|
thirdparty/luafilesystem/src/lfs.c
|
|
thirdparty/luafilesystem/src/lfs.h
|
|
)
|
|
|
|
# The PUC-Rio md5 library, as Hypseus bundles it (its sumhexa is named hexsum), so the games that
|
|
# require("md5") get the same five functions with the same behaviour.
|
|
set(LUA_MD5_SOURCE
|
|
thirdparty/md5/md5.c
|
|
thirdparty/md5/md5.h
|
|
thirdparty/md5/md5lib.c
|
|
)
|
|
|
|
# The rest of the Lua modules Hypseus exposes, so a game written against it finds them here too:
|
|
# LuaBitOp, lrandom, Lua CJSON and LPeg.
|
|
set(LUA_BITOP_SOURCE
|
|
thirdparty/luabitop/lbit.c
|
|
)
|
|
|
|
set(LUA_RANDOM_SOURCE
|
|
thirdparty/lrandom/lrandom.c
|
|
)
|
|
|
|
set(LUA_CJSON_SOURCE
|
|
thirdparty/lua-cjson/fpconv.c
|
|
thirdparty/lua-cjson/fpconv.h
|
|
thirdparty/lua-cjson/lua_cjson.c
|
|
thirdparty/lua-cjson/strbuf.c
|
|
thirdparty/lua-cjson/strbuf.h
|
|
)
|
|
|
|
set(LPEG_SOURCE
|
|
thirdparty/lpeg/lpcap.c
|
|
thirdparty/lpeg/lpcap.h
|
|
thirdparty/lpeg/lpcode.c
|
|
thirdparty/lpeg/lpcode.h
|
|
thirdparty/lpeg/lpcset.c
|
|
thirdparty/lpeg/lpcset.h
|
|
thirdparty/lpeg/lpprint.c
|
|
thirdparty/lpeg/lpprint.h
|
|
thirdparty/lpeg/lptree.c
|
|
thirdparty/lpeg/lptree.h
|
|
thirdparty/lpeg/lptypes.h
|
|
thirdparty/lpeg/lpvm.c
|
|
thirdparty/lpeg/lpvm.h
|
|
)
|
|
|
|
set(LUA_SOCKET_SOURCE
|
|
thirdparty/luasocket/src/auxiliar.c
|
|
thirdparty/luasocket/src/auxiliar.h
|
|
thirdparty/luasocket/src/buffer.c
|
|
thirdparty/luasocket/src/buffer.h
|
|
thirdparty/luasocket/src/compat.c
|
|
thirdparty/luasocket/src/compat.h
|
|
thirdparty/luasocket/src/except.c
|
|
thirdparty/luasocket/src/except.h
|
|
thirdparty/luasocket/src/inet.c
|
|
thirdparty/luasocket/src/inet.h
|
|
thirdparty/luasocket/src/io.c
|
|
thirdparty/luasocket/src/io.h
|
|
thirdparty/luasocket/src/luasocket.c
|
|
thirdparty/luasocket/src/luasocket.h
|
|
thirdparty/luasocket/src/mime.c
|
|
thirdparty/luasocket/src/mime.h
|
|
thirdparty/luasocket/src/options.c
|
|
thirdparty/luasocket/src/options.h
|
|
thirdparty/luasocket/src/select.c
|
|
thirdparty/luasocket/src/select.h
|
|
thirdparty/luasocket/src/socket.h
|
|
thirdparty/luasocket/src/tcp.c
|
|
thirdparty/luasocket/src/tcp.h
|
|
thirdparty/luasocket/src/timeout.c
|
|
thirdparty/luasocket/src/timeout.h
|
|
thirdparty/luasocket/src/udp.c
|
|
thirdparty/luasocket/src/udp.h
|
|
)
|
|
if(WIN32)
|
|
list(APPEND LUA_SOCKET_SOURCE
|
|
thirdparty/luasocket/src/wsocket.c
|
|
thirdparty/luasocket/src/wsocket.h
|
|
)
|
|
else()
|
|
list(APPEND LUA_SOCKET_SOURCE
|
|
thirdparty/luasocket/src/serial.c
|
|
thirdparty/luasocket/src/unix.c
|
|
thirdparty/luasocket/src/unix.h
|
|
thirdparty/luasocket/src/unixdgram.c
|
|
thirdparty/luasocket/src/unixdgram.h
|
|
thirdparty/luasocket/src/unixstream.c
|
|
thirdparty/luasocket/src/unixstream.h
|
|
thirdparty/luasocket/src/usocket.c
|
|
thirdparty/luasocket/src/usocket.h
|
|
)
|
|
endif()
|
|
|
|
set(LUASEC_SOURCE
|
|
${GENERATED_DIR}/luasec_options.c
|
|
thirdparty/luasec/src/compat.h
|
|
thirdparty/luasec/src/config.c
|
|
thirdparty/luasec/src/context.c
|
|
thirdparty/luasec/src/context.h
|
|
thirdparty/luasec/src/ec.c
|
|
thirdparty/luasec/src/ec.h
|
|
thirdparty/luasec/src/options.h
|
|
thirdparty/luasec/src/ssl.c
|
|
thirdparty/luasec/src/ssl.h
|
|
thirdparty/luasec/src/x509.c
|
|
thirdparty/luasec/src/x509.h
|
|
)
|
|
|
|
set(LUA_RS232_SOURCE
|
|
thirdparty/librs232/bindings/lua/luars232.c
|
|
thirdparty/librs232/src/rs232.c
|
|
)
|
|
if(WIN32)
|
|
list(APPEND LUA_RS232_SOURCE thirdparty/librs232/src/rs232_windows.c)
|
|
else()
|
|
list(APPEND LUA_RS232_SOURCE thirdparty/librs232/src/rs232_posix.c)
|
|
endif()
|
|
|
|
set(UTHASH_SOURCE
|
|
thirdparty/uthash/src/uthash.h
|
|
thirdparty/uthash/src/utlist.h
|
|
)
|
|
|
|
set(MANYMOUSE_SOURCE
|
|
thirdparty/manymouse/linux_evdev.c
|
|
thirdparty/manymouse/macosx_hidmanager.c
|
|
thirdparty/manymouse/macosx_hidutilities.c
|
|
thirdparty/manymouse/manymouse.c
|
|
thirdparty/manymouse/manymouse.h
|
|
thirdparty/manymouse/windows_wminput.c
|
|
thirdparty/manymouse/x11_xinput2.c
|
|
)
|
|
|
|
|
|
# ===== Target =====
|
|
|
|
add_executable(${CMAKE_PROJECT_NAME}
|
|
${SINGE_SOURCE}
|
|
${EMBEDDED_HEADERS}
|
|
${GENERATED_DIR}/version.h
|
|
${ARG_PARSER_SOURCE}
|
|
${LUA_SOURCE}
|
|
${LUA_FILESYSTEM_SOURCE}
|
|
${LUA_MD5_SOURCE}
|
|
${LUA_BITOP_SOURCE}
|
|
${LUA_RANDOM_SOURCE}
|
|
${LUA_CJSON_SOURCE}
|
|
${LPEG_SOURCE}
|
|
${SQLITE_SOURCE}
|
|
${LUA_SOCKET_SOURCE}
|
|
${LUASEC_SOURCE}
|
|
${LUA_RS232_SOURCE}
|
|
${UTHASH_SOURCE}
|
|
${MANYMOUSE_SOURCE}
|
|
)
|
|
if(WIN32)
|
|
if(SINGE_ZIG_TARGET)
|
|
# CMake archives every object into objects.a for MinGW links, and zig's linker cannot take a
|
|
# compiled resource from inside an archive; compiled on its own it links as a plain input.
|
|
add_custom_command(
|
|
OUTPUT ${GENERATED_DIR}/singe.res
|
|
COMMAND ${CMAKE_RC_COMPILER} /fo ${GENERATED_DIR}/singe.res ${GENERATED_DIR}/singe.rc
|
|
DEPENDS ${GENERATED_DIR}/singe.rc ${GENERATED_DIR}/icon.ico
|
|
COMMENT "Compiling resources"
|
|
VERBATIM
|
|
)
|
|
add_custom_target(singeResources DEPENDS ${GENERATED_DIR}/singe.res)
|
|
add_dependencies(${CMAKE_PROJECT_NAME} singeResources)
|
|
target_link_options(${CMAKE_PROJECT_NAME} PRIVATE ${GENERATED_DIR}/singe.res)
|
|
else()
|
|
enable_language(RC)
|
|
target_sources(${CMAKE_PROJECT_NAME} PRIVATE ${GENERATED_DIR}/singe.rc ${GENERATED_DIR}/icon.ico)
|
|
endif()
|
|
endif()
|
|
|
|
# Output name matches the release artifact: Singe-v3.00-Linux-x86_64
|
|
string(SUBSTRING ${KANGAROO_OS} 0 1 osInitial)
|
|
string(SUBSTRING ${KANGAROO_OS} 1 -1 osRest)
|
|
string(TOUPPER ${osInitial} osInitial)
|
|
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES OUTPUT_NAME "Singe-v${PROJECT_VERSION}-${osInitial}${osRest}-${KANGAROO_ARCH}")
|
|
|
|
# Warnings apply to our code only; the vendored libraries are not ours to fix.
|
|
set_source_files_properties(${SINGE_SOURCE} PROPERTIES COMPILE_OPTIONS "-Wall;-Wextra")
|
|
# librs232 stamps its build date into the module; clang under zig makes that an error by default.
|
|
set_source_files_properties(thirdparty/librs232/bindings/lua/luars232.c PROPERTIES COMPILE_OPTIONS "-Wno-date-time")
|
|
# The Basis transcoder is warning-heavy third-party C++; it is compiled quietly.
|
|
set_source_files_properties(thirdparty/basis_universal/transcoder/basisu_transcoder.cpp PROPERTIES COMPILE_OPTIONS "-w")
|
|
|
|
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE
|
|
RS232_STATIC
|
|
BASISD_SUPPORT_KTX2=1
|
|
BASISD_SUPPORT_KTX2_ZSTD=1
|
|
BASISD_SUPPORT_PVRTC1=0
|
|
BASISD_SUPPORT_PVRTC2=0
|
|
BASISD_SUPPORT_ATC=0
|
|
BASISD_SUPPORT_FXT1=0
|
|
BASISD_SUPPORT_ETC2_EAC_A8=0
|
|
BASISD_SUPPORT_ETC2_EAC_RG11=0
|
|
SQLITE_DQS=0
|
|
SQLITE_THREADSAFE=1
|
|
SQLITE_DEFAULT_MEMSTATUS=0
|
|
SQLITE_OMIT_SHARED_CACHE
|
|
)
|
|
if(WIN32)
|
|
# _WIN32_WINNT=0x0600 sets the minimum compatible version of Windows to Vista.
|
|
# The function inet_pton() does not exist before then.
|
|
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE
|
|
_WIN32_WINNT=0x0600
|
|
)
|
|
endif()
|
|
|
|
target_compile_options(${CMAKE_PROJECT_NAME} PRIVATE
|
|
-Wno-deprecated-declarations
|
|
)
|
|
|
|
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE
|
|
${CMAKE_BINARY_DIR}
|
|
${GENERATED_DIR}/include
|
|
${BUILD_DIR}
|
|
${BUILD_DIR}/include
|
|
thirdparty/lua/src
|
|
thirdparty/sqlite
|
|
thirdparty/luasec/src
|
|
thirdparty/librs232/include
|
|
thirdparty/basis_universal/transcoder
|
|
)
|
|
|
|
target_link_directories(${CMAKE_PROJECT_NAME} PRIVATE
|
|
${BUILD_DIR}/lib
|
|
)
|
|
|
|
|
|
# ===== Libraries =====
|
|
|
|
# Platform specific system libraries.
|
|
if(KANGAROO_OS STREQUAL "linux")
|
|
if(KANGAROO_ARCH MATCHES "^(aarch64|armhf)$")
|
|
set(SYSTEM_LIBS -ldl)
|
|
# An ARM board decodes video through its V4L2 memory-to-memory device (videoPlayer.c).
|
|
# Nothing here is particular to a Raspberry Pi: any board whose kernel offers one is served.
|
|
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE SINGE_V4L2_DECODE)
|
|
# The stateless decoders are a separate interface again, and FFmpeg builds them only when its
|
|
# own dependencies were met, so the engine follows what FFmpeg actually did.
|
|
if(EXISTS ${BUILD_DIR}/build/ffmpeg/config.h)
|
|
file(READ ${BUILD_DIR}/build/ffmpeg/config.h ffmpegConfig)
|
|
if(ffmpegConfig MATCHES "#define CONFIG_V4L2_REQUEST 1")
|
|
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE SINGE_V4L2_REQUEST_DECODE)
|
|
message(STATUS "FFmpeg carries the V4L2 stateless decoders; enabling them in the player")
|
|
endif()
|
|
endif()
|
|
else()
|
|
# ffmpeg's vdpau hardware context is always compiled in on X11 hosts.
|
|
set(SYSTEM_LIBS -lX11 -lvdpau -ldl -rdynamic) # -rdynamic gives the crash backtrace function names
|
|
endif()
|
|
# Release binaries are stripped; the crash backtrace reads the dynamic symbols -rdynamic exports,
|
|
# which stripping keeps.
|
|
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
|
list(APPEND SYSTEM_LIBS -s)
|
|
endif()
|
|
elseif(KANGAROO_OS STREQUAL "macos")
|
|
set(SYSTEM_LIBS
|
|
-Wl,-framework,CoreVideo
|
|
-Wl,-framework,Cocoa
|
|
-Wl,-framework,IOKit
|
|
-Wl,-framework,ForceFeedback
|
|
-Wl,-framework,Carbon
|
|
-Wl,-framework,CoreAudio
|
|
-Wl,-framework,AudioToolbox
|
|
-Wl,-framework,AVFoundation
|
|
-Wl,-framework,Foundation
|
|
-Wl,-weak_framework,GameController
|
|
-Wl,-weak_framework,Metal
|
|
-Wl,-weak_framework,QuartzCore
|
|
-Wl,-weak_framework,CoreHaptics
|
|
-Wl,-weak_framework,UniformTypeIdentifiers
|
|
-liconv
|
|
-lc++
|
|
)
|
|
if(NOT SINGE_ZIG_TARGET)
|
|
# osxcross builds need clang's runtime library named; zig carries its own.
|
|
if(NOT DEFINED OSXCROSS_TARGET_DIR)
|
|
message(FATAL_ERROR "OSXCROSS_TARGET_DIR must be set for macOS builds without zig.")
|
|
endif()
|
|
list(APPEND SYSTEM_LIBS ${OSXCROSS_TARGET_DIR}/darwin/libclang_rt.osx.a)
|
|
endif()
|
|
elseif(KANGAROO_OS STREQUAL "windows")
|
|
# A GUI-subsystem executable, so no console window opens; zig's linker wants the flag spelled out.
|
|
if(SINGE_ZIG_TARGET)
|
|
set(windowsSubsystem -Wl,--subsystem,windows)
|
|
else()
|
|
set(windowsSubsystem -mwindows)
|
|
endif()
|
|
set(SYSTEM_LIBS
|
|
${windowsSubsystem}
|
|
-static
|
|
-lmingw32
|
|
-latomic
|
|
-lole32
|
|
-luser32
|
|
-lkernel32
|
|
-lgdi32
|
|
-lwinmm
|
|
-limm32
|
|
-loleaut32
|
|
-lversion
|
|
-luuid
|
|
-ladvapi32
|
|
-lsetupapi
|
|
-lshell32
|
|
-ldinput8
|
|
-lws2_32
|
|
-lbcrypt
|
|
-lcrypt32
|
|
)
|
|
if(NOT SINGE_ZIG_TARGET)
|
|
# MinGW's stack protector runtime; zig's compiler-rt carries it itself.
|
|
list(APPEND SYSTEM_LIBS -lssp)
|
|
endif()
|
|
else()
|
|
message(FATAL_ERROR "Unknown KANGAROO_OS: ${KANGAROO_OS}")
|
|
endif()
|
|
|
|
# FFmpeg's hardware decoding backends (VA-API, VDPAU, DRM, V4L2, VideoToolbox) are whatever the
|
|
# superbuild configured; its pkg-config files name the system libraries and frameworks they need, so
|
|
# read them back.
|
|
if(NOT KANGAROO_OS STREQUAL "windows")
|
|
foreach(pc libavutil libavcodec)
|
|
set(pcFile ${BUILD_DIR}/lib/pkgconfig/${pc}.pc)
|
|
if(EXISTS ${pcFile})
|
|
file(STRINGS ${pcFile} pcLibs REGEX "^Libs:")
|
|
string(REGEX REPLACE "^Libs: *" "" pcLibs "${pcLibs}")
|
|
separate_arguments(pcLibs)
|
|
set(framework FALSE)
|
|
foreach(token ${pcLibs})
|
|
if(framework)
|
|
list(APPEND SYSTEM_LIBS -Wl,-framework,${token})
|
|
set(framework FALSE)
|
|
elseif(token STREQUAL "-framework")
|
|
set(framework TRUE)
|
|
elseif(token MATCHES "^-l" AND NOT token MATCHES "^-l(avutil|avcodec|z|m|atomic|pthread|iconv)$")
|
|
list(APPEND SYSTEM_LIBS ${token})
|
|
endif()
|
|
endforeach()
|
|
endif()
|
|
endforeach()
|
|
list(REMOVE_DUPLICATES SYSTEM_LIBS)
|
|
endif()
|
|
|
|
# Static third party libraries built by build-all.sh.
|
|
set(STATIC_LIBS
|
|
${BUILD_DIR}/lib/libavcodec.a
|
|
${BUILD_DIR}/lib/libavdevice.a
|
|
${BUILD_DIR}/lib/libavfilter.a
|
|
${BUILD_DIR}/lib/libavformat.a
|
|
${BUILD_DIR}/lib/libavutil.a
|
|
${BUILD_DIR}/lib/libfreetype.a
|
|
${BUILD_DIR}/lib/libopus.a
|
|
${BUILD_DIR}/lib/libopusfile.a
|
|
${BUILD_DIR}/lib/libogg.a
|
|
${BUILD_DIR}/lib/libSDL3.a
|
|
${BUILD_DIR}/lib/libSDL3_image.a
|
|
${BUILD_DIR}/lib/libSDL3_mixer.a
|
|
${BUILD_DIR}/lib/libSDL3_ttf.a
|
|
${BUILD_DIR}/lib/libswresample.a
|
|
${BUILD_DIR}/lib/libswscale.a
|
|
${BUILD_DIR}/lib/libwavpack.a
|
|
${BUILD_DIR}/lib/libwebp.a
|
|
${BUILD_DIR}/lib/libwebpdemux.a
|
|
${BUILD_DIR}/lib/libwebpmux.a
|
|
${BUILD_DIR}/lib/libsharpyuv.a
|
|
${BUILD_DIR}/lib/libxmp.a
|
|
${BUILD_DIR}/lib/libz.a
|
|
${BUILD_DIR}/lib/libzstd.a
|
|
${BUILD_DIR}/lib/libcrypto.a
|
|
${BUILD_DIR}/lib/libssl.a
|
|
)
|
|
# SDL3_image builds its own jpeg and png decoders where the platform has none (macOS uses ImageIO
|
|
# for jpeg); link whichever archives it produced.
|
|
foreach(imageLib libjpeg.a libpng16.a)
|
|
if(EXISTS ${BUILD_DIR}/lib/${imageLib})
|
|
list(APPEND STATIC_LIBS ${BUILD_DIR}/lib/${imageLib})
|
|
endif()
|
|
endforeach()
|
|
|
|
# The scene shaders: src/shaders/scene.hlsl compiled at build time into a header of SPIR-V, DXIL
|
|
# and MSL blobs by SDL_shadercross, which the superbuild builds for the host (cmake/hostTools.cmake)
|
|
# and names in SINGE_SHADERCROSS; configuring this project alone finds one on the PATH.
|
|
if(NOT SINGE_SHADERCROSS)
|
|
find_program(SINGE_SHADERCROSS shadercross)
|
|
if(NOT SINGE_SHADERCROSS)
|
|
message(FATAL_ERROR "SDL_shadercross is needed to compile the scene shaders; build through the superbuild (cmake --preset ...) or set SINGE_SHADERCROSS.")
|
|
endif()
|
|
endif()
|
|
set(shaderHeader ${CMAKE_BINARY_DIR}/generated/shaders/sceneShaders.h)
|
|
add_custom_command(
|
|
OUTPUT ${shaderHeader}
|
|
COMMAND ${CMAKE_COMMAND} -DSHADERCROSS=${SINGE_SHADERCROSS} -DSOURCE=${CMAKE_SOURCE_DIR}/src/shaders/scene.hlsl -DOUTPUT=${shaderHeader} -P ${CMAKE_SOURCE_DIR}/cmake/shaderHeader.cmake
|
|
DEPENDS ${CMAKE_SOURCE_DIR}/src/shaders/scene.hlsl ${CMAKE_SOURCE_DIR}/src/sceneShared.h ${CMAKE_SOURCE_DIR}/cmake/shaderHeader.cmake
|
|
COMMENT "Compiling the scene shaders"
|
|
)
|
|
target_sources(${CMAKE_PROJECT_NAME} PRIVATE ${shaderHeader})
|
|
# The GUI shaders the same way: src/shaders/gui.hlsl into guiShaders.h for guiRender.cpp. The
|
|
# entry list is a CMake list, so it is quoted as one argument and VERBATIM keeps the semicolons.
|
|
set(guiShaderHeader ${CMAKE_BINARY_DIR}/generated/shaders/guiShaders.h)
|
|
set(guiShaderEntries "guiVertex:vertex;guiFragmentColor:fragment;guiFragmentTexture:fragment;guiFragmentFilter:fragment;guiFragmentBlur:fragment;guiFragmentColorMatrix:fragment;guiFragmentGradient:fragment")
|
|
add_custom_command(
|
|
OUTPUT ${guiShaderHeader}
|
|
COMMAND ${CMAKE_COMMAND} -DSHADERCROSS=${SINGE_SHADERCROSS} -DSOURCE=${CMAKE_SOURCE_DIR}/src/shaders/gui.hlsl -DOUTPUT=${guiShaderHeader} "-DENTRIES=${guiShaderEntries}" -DPREFIX=guiShader -DTYPE=GuiShaderT -P ${CMAKE_SOURCE_DIR}/cmake/shaderHeader.cmake
|
|
DEPENDS ${CMAKE_SOURCE_DIR}/src/shaders/gui.hlsl ${CMAKE_SOURCE_DIR}/cmake/shaderHeader.cmake
|
|
COMMENT "Compiling the GUI shaders"
|
|
VERBATIM
|
|
)
|
|
target_sources(${CMAKE_PROJECT_NAME} PRIVATE ${guiShaderHeader})
|
|
target_include_directories(${CMAKE_PROJECT_NAME} PRIVATE ${CMAKE_BINARY_DIR}/generated)
|
|
|
|
# Rockchip's hardware decoders are reached by name (videoPlayer.c), and only exist when FFmpeg was
|
|
# built against the Rockchip MPP library. Asking FFmpeg itself is what decides it.
|
|
execute_process(COMMAND ${CMAKE_COMMAND} -E echo "" OUTPUT_QUIET)
|
|
if(EXISTS ${BUILD_DIR}/lib/pkgconfig/libavcodec.pc)
|
|
file(READ ${BUILD_DIR}/lib/pkgconfig/libavcodec.pc avcodecPc)
|
|
if(avcodecPc MATCHES "rockchip_mpp")
|
|
target_compile_definitions(${CMAKE_PROJECT_NAME} PRIVATE SINGE_RKMPP_DECODE)
|
|
message(STATUS "FFmpeg carries the rkmpp decoders; enabling them in the player")
|
|
endif()
|
|
endif()
|
|
|
|
# Jolt Physics comes with the compile definitions it was built with (SIMD level, layer bits) through
|
|
# its exported target; the one C++ file in the tree (physicsJolt.cpp) needs them. Its C++ runtime is
|
|
# zig's own libc++, linked statically, or the host's libstdc++ under gcc; macOS already lists -lc++.
|
|
find_package(Jolt CONFIG REQUIRED PATHS ${BUILD_DIR}/lib/cmake/Jolt NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
|
|
# Recast Navigation the same way (navRecast.cpp): Recast bakes, Detour queries, DetourCrowd steers.
|
|
find_package(recastnavigation CONFIG REQUIRED PATHS ${BUILD_DIR}/lib/cmake/recastnavigation NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
|
|
# RmlUi (gui.cpp, and guiRender.cpp, the SDL_GPU render interface forked from RmlUi's Backends).
|
|
# Its package config looks for Freetype::Freetype and Lua::Lua only when they are not already
|
|
# targets, so both are declared here from the superbuild's FreeType and the engine's own Lua.
|
|
add_library(Freetype::Freetype STATIC IMPORTED)
|
|
set_target_properties(Freetype::Freetype PROPERTIES IMPORTED_LOCATION ${BUILD_DIR}/lib/libfreetype.a INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/thirdparty/SDL3_ttf/external/freetype/include)
|
|
add_library(Lua::Lua INTERFACE IMPORTED)
|
|
set_target_properties(Lua::Lua PROPERTIES INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_SOURCE_DIR}/thirdparty/lua/src)
|
|
find_package(RmlUi CONFIG REQUIRED PATHS ${BUILD_DIR}/lib/cmake/RmlUi NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH)
|
|
set_target_properties(${CMAKE_PROJECT_NAME} PROPERTIES CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF)
|
|
# Jolt is built without RTTI, so the file that subclasses its debug renderer must be too, or the
|
|
# subclass's vtable wants type information the library never made.
|
|
set_source_files_properties(src/physicsJolt.cpp PROPERTIES COMPILE_OPTIONS "-fno-rtti")
|
|
if(NOT KANGAROO_OS STREQUAL "macos")
|
|
if(SINGE_ZIG_TARGET)
|
|
list(APPEND SYSTEM_LIBS -lc++)
|
|
else()
|
|
list(APPEND SYSTEM_LIBS -lstdc++)
|
|
endif()
|
|
endif()
|
|
|
|
# System libraries follow the static ones so their symbols resolve for everything above.
|
|
# Apple's linker has no --start-group, so the list is repeated there instead.
|
|
if(KANGAROO_OS STREQUAL "macos")
|
|
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE ${STATIC_LIBS} ${STATIC_LIBS} ${STATIC_LIBS} Jolt::Jolt RecastNavigation::DetourCrowd RecastNavigation::Detour RecastNavigation::Recast RmlUi::Lua RmlUi::Debugger RmlUi::Core ${SYSTEM_LIBS} -pthread -lm)
|
|
else()
|
|
target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE -Wl,--start-group ${STATIC_LIBS} -Wl,--end-group Jolt::Jolt RecastNavigation::DetourCrowd RecastNavigation::Detour RecastNavigation::Recast RmlUi::Lua RmlUi::Debugger RmlUi::Core ${SYSTEM_LIBS} -pthread -lm)
|
|
endif()
|
|
|
|
|
|
install(TARGETS ${CMAKE_PROJECT_NAME})
|