From c83e146d11345fa303a5fa35840ce6acc504fb6e Mon Sep 17 00:00:00 2001 From: Christoph Neidahl Date: Tue, 1 Feb 2022 21:50:25 +0100 Subject: [PATCH] Improve devendoring & other CMake stuff (#21) * Improve devendoring * Add warning flags for own C++ code For https://github.com/tildearrow/furnace/pull/12#issuecomment-1017330467. * Document new CMake options * pkg-config stuff * Warnings stuff for MSVC yay * Use more specific linking vars & functions * Fix Linux icon location * DEPENDENCIES_LEGACY_LDFLAGS for JACK too --- .github/workflows/build.yml | 5 + CMakeLists.txt | 281 +++++++++++++++++++++++++++--------- README.md | 17 +++ src/audio/sdl.h | 4 - 4 files changed, 231 insertions(+), 76 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 49184c6e4..4dce04678 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -75,10 +75,14 @@ jobs: - name: Configure run: | + export USE_WAE=ON export CMAKE_EXTRA_ARGS=() if [ '${{ runner.os }}' == 'Windows' ]; then if [ '${{ matrix.config.compiler }}' == 'mingw' ]; then CMAKE_EXTRA_ARGS+=('-G' 'MSYS Makefiles') + elif [ '${{ matrix.config.compiler }}' == 'msvc' ]; then + # We don't want all the MSVC warnings to cause errors yet + export USE_WAE=OFF fi fi @@ -86,6 +90,7 @@ jobs: -B ${PWD}/build \ -DCMAKE_INSTALL_PREFIX=${PWD}/target \ -DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }} \ + -DWARNINGS_ARE_ERRORS=${USE_WAE} \ "${CMAKE_EXTRA_ARGS[@]}" - name: Build diff --git a/CMakeLists.txt b/CMakeLists.txt index d9ed384c0..9d27dc901 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,73 +13,170 @@ set(CMAKE_PROJECT_VERSION_MINOR 5) set(CMAKE_PROJECT_VERSION_PATCH 1) if (ANDROID) - set(BUILD_GUI OFF) + set(BUILD_GUI_DEFAULT OFF) else() - set(BUILD_GUI ON) + set(BUILD_GUI_DEFAULT ON) endif() -option(DEVENDOR_LIBRARIES "Use local versions of dependencies instead of the ones provided by submodules" OFF) +find_package(PkgConfig) +if (PKG_CONFIG_FOUND) + pkg_check_modules(JACK jack) + set(WITH_JACK_DEFAULT ${JACK_FOUND}) +else() + set(WITH_JACK_DEFAULT OFF) +endif() -if (NOT DEVENDOR_LIBRARIES) +option(BUILD_GUI "Build the tracker (disable to build only a headless player)" ${BUILD_GUI_DEFAULT}) +option(WITH_JACK "Whether to build with JACK support. Auto-detects if JACK is available" ${WITH_JACK_DEFAULT}) +option(SYSTEM_FMT "Use a system-installed version of fmt instead of the vendored one" OFF) +option(SYSTEM_LIBSNDFILE "Use a system-installed version of libsndfile instead of the vendored one" OFF) +option(SYSTEM_ZLIB "Use a system-installed version of zlib instead of the vendored one" OFF) +option(SYSTEM_SDL2 "Use a system-installed version of SDL2 instead of the vendored one" OFF) +option(WARNINGS_ARE_ERRORS "Whether warnings in furnace's C++ code should be treated as errors" OFF) + +set(DEPENDENCIES_INCLUDE_DIRS "") +set(DEPENDENCIES_DEFINES "") +set(DEPENDENCIES_COMPILE_OPTIONS "") +set(DEPENDENCIES_LIBRARIES "") +set(DEPENDENCIES_LIBRARY_DIRS "") +set(DEPENDENCIES_LINK_OPTIONS "") +set(DEPENDENCIES_LEGACY_LDFLAGS "") + +find_package(Threads REQUIRED) +list(APPEND DEPENDENCIES_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) + +if (SYSTEM_FMT) + if (PKG_CONFIG_FOUND) + pkg_check_modules(FMT fmt) + if (FMT_FOUND) + list(APPEND DEPENDENCIES_INCLUDE_DIRS ${FMT_INCLUDE_DIRS}) + list(APPEND DEPENDENCIES_COMPILE_OPTIONS ${FMT_CFLAGS_OTHER}) + list(APPEND DEPENDENCIES_LIBRARIES ${FMT_LIBRARIES}) + list(APPEND DEPENDENCIES_LIBRARY_DIRS ${FMT_LIBRARY_DIRS}) + list(APPEND DEPENDENCIES_LINK_OPTIONS ${FMT_LDFLAGS_OTHER}) + list(APPEND DEPENDENCIES_LEGACY_LDFLAGS ${FMT_LDFLAGS}) + endif() + endif() + if (NOT FMT_FOUND) + find_package(fmt REQUIRED) + list(APPEND DEPENDENCIES_LIBRARIES fmt::fmt) + endif() + message(STATUS "Using system-installed fmt") +else() add_subdirectory(extern/fmt EXCLUDE_FROM_ALL) + list(APPEND DEPENDENCIES_INCLUDE_DIRS extern/fmt/include) + list(APPEND DEPENDENCIES_LIBRARIES fmt) + message(STATUS "Using vendored fmt") endif() -if (NOT DEVENDOR_LIBRARIES) +if (SYSTEM_LIBSNDFILE) + find_package(PkgConfig REQUIRED) + pkg_check_modules(LIBSNDFILE REQUIRED sndfile) + list(APPEND DEPENDENCIES_INCLUDE_DIRS ${LIBSNDFILE_INCLUDE_DIRS}) + list(APPEND DEPENDENCIES_COMPILE_OPTIONS ${LIBSNDFILE_CFLAGS_OTHER}) + list(APPEND DEPENDENCIES_LIBRARIES ${LIBSNDFILE_LIBRARIES}) + list(APPEND DEPENDENCIES_LIBRARY_DIRS ${LIBSNDFILE_LIBRARY_DIRS}) + list(APPEND DEPENDENCIES_LINK_OPTIONS ${LIBSNDFILE_LDFLAGS_OTHER}) + list(APPEND DEPENDENCIES_LEGACY_LDFLAGS ${LIBSNDFILE_LDFLAGS}) + message(STATUS "Using system-installed libsndfile") +else() set(BUILD_TESTING OFF CACHE BOOL "aaaaaa" FORCE) set(BUILD_PROGRAMS OFF CACHE BOOL "aaa" FORCE) set(BUILD_EXAMPLES OFF CACHE BOOL "a" FORCE) set(ENABLE_EXTERNAL_LIBS OFF CACHE BOOL "come on" FORCE) set(ENABLE_MPEG OFF CACHE BOOL "come on" FORCE) add_subdirectory(extern/libsndfile EXCLUDE_FROM_ALL) + list(APPEND DEPENDENCIES_LIBRARIES sndfile) + message(STATUS "Using vendored libsndfile") +endif() + +if (SYSTEM_ZLIB) + find_package(PkgConfig REQUIRED) + pkg_check_modules(ZLIB REQUIRED zlib) + list(APPEND DEPENDENCIES_INCLUDE_DIRS ${ZLIB_INCLUDE_DIRS}) + list(APPEND DEPENDENCIES_COMPILE_OPTIONS ${ZLIB_CFLAGS_OTHER}) + list(APPEND DEPENDENCIES_LIBRARIES ${ZLIB_LIBRARIES}) + list(APPEND DEPENDENCIES_LIBRARY_DIRS ${ZLIB_LIBRARY_DIRS}) + list(APPEND DEPENDENCIES_LINK_OPTIONS ${ZLIB_LDFLAGS_OTHER}) + list(APPEND DEPENDENCIES_LEGACY_LDFLAGS ${ZLIB_LDFLAGS}) + message(STATUS "Using system-installed zlib") +else() + set(BUILD_TESTING OFF CACHE BOOL "aaaaaa" FORCE) + set(BUILD_PROGRAMS OFF CACHE BOOL "aaa" FORCE) + set(BUILD_EXAMPLES OFF CACHE BOOL "a" FORCE) + set(ENABLE_EXTERNAL_LIBS OFF CACHE BOOL "come on" FORCE) + set(ENABLE_MPEG OFF CACHE BOOL "come on" FORCE) add_subdirectory(extern/zlib EXCLUDE_FROM_ALL) - - include_directories(extern/zlib ${CMAKE_CURRENT_BINARY_DIR}/extern/zlib) -else() - find_library(HAVE_Z z) + list(APPEND DEPENDENCIES_INCLUDE_DIRS extern/zlib ${CMAKE_CURRENT_BINARY_DIR}/extern/zlib) + list(APPEND DEPENDENCIES_LIBRARIES zlibstatic) + message(STATUS "Using vendored zlib") endif() -if (DEVENDOR_LIBRARIES) - find_package(SDL) - if (SDL_FOUND) - set(HAVE_SDL2 ${SDL_LIBRARY}) - include_directories(extern/imgui extern/IconFontCppHeaders extern/imgui/backends extern/igfd ${SDL_INCLUDE_DIR}) - else() - find_package(SDL2 REQUIRED) - set(HAVE_SDL2 ${SDL2_LIBRARIES}) - include_directories(extern/imgui extern/IconFontCppHeaders extern/imgui/backends extern/igfd ${SDL2_INCLUDE_DIRS}) +if (SYSTEM_SDL2) + if (PKG_CONFIG_FOUND) + pkg_check_modules(SDL sdl>=2.0.18) + if (SDL_FOUND) + list(APPEND DEPENDENCIES_INCLUDE_DIRS ${SDL_INCLUDE_DIRS}) + list(APPEND DEPENDENCIES_COMPILE_OPTIONS ${SDL_CFLAGS_OTHER}) + list(APPEND DEPENDENCIES_LIBRARIES ${SDL_LIBRARIES}) + list(APPEND DEPENDENCIES_LIBRARY_DIRS ${SDL_LIBRARY_DIRS}) + list(APPEND DEPENDENCIES_LINK_OPTIONS ${SDL_LDFLAGS_OTHER}) + list(APPEND DEPENDENCIES_LEGACY_LDFLAGS ${SDL_LDFLAGS}) + endif() endif() - find_library(HAVE_JACK jack) -else() - if (WIN32) - set(SDL_SHARED OFF) - set(SDL_STATIC ON) - add_subdirectory(extern/SDL EXCLUDE_FROM_ALL) - set(HAVE_SDL2 SDL2-static) - set(HAVE_Z zlibstatic) - include_directories(extern/SDL/include extern/imgui extern/IconFontCppHeaders extern/imgui/backends extern/igfd extern/fmt/include) - else() - if (BUILD_GUI) - set(SDL_SHARED ON) - add_subdirectory(extern/SDL EXCLUDE_FROM_ALL) - include_directories(extern/SDL/include extern/imgui extern/IconFontCppHeaders extern/imgui/backends extern/igfd extern/fmt/include) - set(HAVE_SDL2 SDL2-static) + if (NOT SDL_FOUND) + find_package(SDL 2.0.18) + if (SDL_FOUND) + list(APPEND DEPENDENCIES_INCLUDE_DIRS ${SDL_INCLUDE_DIR}) + list(APPEND DEPENDENCIES_LIBRARIES ${SDL_LIBRARY}) else() - find_library(HAVE_SDL2 SDL2) + if (PKG_CONFIG_FOUND) + pkg_check_modules(SDL2 sdl2>=2.0.18) + if (SDL2_FOUND) + list(APPEND DEPENDENCIES_INCLUDE_DIRS ${SDL2_INCLUDE_DIRS}) + list(APPEND DEPENDENCIES_COMPILE_OPTIONS ${SDL2_CFLAGS_OTHER}) + list(APPEND DEPENDENCIES_LIBRARIES ${SDL2_LIBRARIES}) + list(APPEND DEPENDENCIES_LIBRARY_DIRS ${SDL2_LIBRARY_DIRS}) + list(APPEND DEPENDENCIES_LINK_OPTIONS ${SDL2_LDFLAGS_OTHER}) + list(APPEND DEPENDENCIES_LEGACY_LDFLAGS ${SDL2_LDFLAGS}) + endif() + endif() + if (NOT SDL2_FOUND) + find_package(SDL2 2.0.18 REQUIRED) + list(APPEND DEPENDENCIES_INCLUDE_DIRS ${SDL2_INCLUDE_DIR}) + list(APPEND DEPENDENCIES_LIBRARIES ${SDL2_LIBRARY}) + endif() endif() - if (NOT APPLE) - find_library(HAVE_JACK jack) - endif() - find_library(HAVE_SNDFILE sndfile) - set(HAVE_Z zlibstatic) endif() + message(STATUS "Using system-installed SDL2") +else() + set(SDL_SHARED OFF) + set(SDL_STATIC ON) + add_subdirectory(extern/SDL EXCLUDE_FROM_ALL) + list(APPEND DEPENDENCIES_INCLUDE_DIRS extern/SDL/include) + list(APPEND DEPENDENCIES_LIBRARIES SDL2-static) + message(STATUS "Using vendored SDL2") endif() -set(AUDIO_SOURCES src/audio/abstract.cpp) -if (HAVE_SDL2) - list(APPEND AUDIO_SOURCES src/audio/sdl.cpp) -endif() -if (HAVE_JACK) +set(AUDIO_SOURCES +src/audio/abstract.cpp +src/audio/sdl.cpp +) + +if(WITH_JACK) + find_package(PkgConfig REQUIRED) + pkg_check_modules(JACK REQUIRED jack) list(APPEND AUDIO_SOURCES src/audio/jack.cpp) + list(APPEND DEPENDENCIES_INCLUDE_DIRS ${JACK_INCLUDE_DIRS}) + list(APPEND DEPENDENCIES_DEFINES HAVE_JACK) + list(APPEND DEPENDENCIES_COMPILE_OPTIONS ${JACK_CFLAGS_OTHER}) + list(APPEND DEPENDENCIES_LIBRARIES ${JACK_LIBRARIES}) + list(APPEND DEPENDENCIES_LIBRARY_DIRS ${JACK_LIBRARY_DIRS}) + list(APPEND DEPENDENCIES_LINK_OPTIONS ${JACK_LDFLAGS_OTHER}) + list(APPEND DEPENDENCIES_LEGACY_LDFLAGS ${JACK_LDFLAGS}) + message(STATUS "Building with JACK support") +else() + message(STATUS "Building without JACK support") endif() set(ENGINE_SOURCES @@ -152,7 +249,14 @@ src/engine/platform/ay8930.cpp src/engine/platform/tia.cpp src/engine/platform/saa.cpp src/engine/platform/amiga.cpp -src/engine/platform/dummy.cpp) +src/engine/platform/dummy.cpp +) + +if (WIN32) + list(APPEND ENGINE_SOURCES src/utfutils.cpp) + list(APPEND ENGINE_SOURCES src/engine/winStuff.cpp) + list(APPEND ENGINE_SOURCES res/furnace.rc) +endif() set(GUI_SOURCES extern/imgui/imgui.cpp @@ -176,46 +280,79 @@ src/gui/font_unifont.cpp src/gui/font_icon.cpp src/gui/fonts.cpp src/gui/debug.cpp -src/gui/gui.cpp) +src/gui/gui.cpp +) if (NOT WIN32 AND NOT APPLE) list(APPEND GUI_SOURCES src/gui/icon.c) endif() -if (WIN32) - list(APPEND ENGINE_SOURCES src/engine/winStuff.cpp) - list(APPEND ENGINE_SOURCES res/furnace.rc) -endif() - set(USED_SOURCES ${ENGINE_SOURCES} ${AUDIO_SOURCES} src/main.cpp) if (BUILD_GUI) list(APPEND USED_SOURCES ${GUI_SOURCES}) - if (MSVC) - add_executable(furnace WIN32 ${USED_SOURCES}) - else() - add_executable(furnace ${USED_SOURCES}) + list(APPEND DEPENDENCIES_INCLUDE_DIRS + extern/imgui + extern/imgui/backends + extern/IconFontCppHeaders + extern/igfd + ) + list(APPEND DEPENDENCIES_DEFINES HAVE_GUI) + message(STATUS "Building GUI") +else() + message(STATUS "Building headless") +endif() + +if (WIN32) + list(APPEND DEPENDENCIES_LIBRARIES shlwapi) + #if (NOT MSVC) + # list(APPEND DEPENDENCIES_LIBRARIES -static) + #endif() +endif() + +if (NOT MSVC) + set(WARNING_FLAGS -Wall -Wextra -Wno-unused-parameter) + if (WARNINGS_ARE_ERRORS) + list(APPEND WARNING_FLAGS -Werror) endif() - target_compile_definitions(furnace PUBLIC HAVE_GUI) +else() + # /wd4100 == -Wno-unused-parameter + set(WARNING_FLAGS /W4 /wd4100 /D_CRT_SECURE_NO_WARNINGS) + if (WARNINGS_ARE_ERRORS) + list(APPEND WARNING_FLAGS /WX) + endif() +endif() +# Nicer but cannot be narrowed down to just C++ +# target_compile_options(furnace PRIVATE ${WARNING_FLAGS}) +string(REPLACE ";" " " WARNING_FLAGS_STRING "${WARNING_FLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${WARNING_FLAGS_STRING}") +if (WARNINGS_ARE_ERRORS) + message(WARNING + "Treating all warnings in furnace's C++ code as errors! " + "Please report any errors you encounter on the bug tracker." + ) +endif() + +if (MSVC) + add_executable(furnace WIN32 ${USED_SOURCES}) else() add_executable(furnace ${USED_SOURCES}) endif() -if (DEVENDOR_LIBRARIES) - target_compile_definitions(furnace PUBLIC DEVENDOR_LIBRARIES) -endif() - -target_link_libraries(furnace ${HAVE_SDL2} ${HAVE_Z} sndfile fmt) - -if (HAVE_JACK) - target_link_libraries(furnace ${HAVE_JACK}) - target_compile_definitions(furnace PUBLIC HAVE_JACK) -endif() - -if (WIN32) - target_link_libraries(furnace shlwapi) - if (NOT MSVC) - target_link_libraries(furnace -static) +target_include_directories(furnace SYSTEM PRIVATE ${DEPENDENCIES_INCLUDE_DIRS}) +target_compile_definitions(furnace PRIVATE ${DEPENDENCIES_DEFINES}) +target_compile_options(furnace PRIVATE ${DEPENDENCIES_COMPILE_OPTIONS}) +target_link_libraries(furnace PRIVATE ${DEPENDENCIES_LIBRARIES}) +if (PKG_CONFIG_FOUND AND (SYSTEM_FMT OR SYSTEM_LIBSNDFILE OR SYSTEM_ZLIB OR SYSTEM_SDL2 OR WITH_JACK)) + if ("${CMAKE_VERSION}" VERSION_LESS "3.13") + message(WARNING + "CMake version is <3.13, using old pkg-config LDFLAGS. " + "You may encounter linking problems with these!" + ) + target_link_libraries(furnace PRIVATE ${DEPENDENCIES_LEGACY_LDFLAGS}) + else() + target_link_directories(furnace PRIVATE ${DEPENDENCIES_LIBRARY_DIRS}) + target_link_options(furnace PRIVATE ${DEPENDENCIES_LINK_OPTIONS}) endif() endif() @@ -228,7 +365,7 @@ if (NOT WIN32 AND NOT APPLE) install(DIRECTORY papers DESTINATION ${CMAKE_INSTALL_DOCDIR}) install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DATADIR}/licenses) install(DIRECTORY demos DESTINATION ${CMAKE_INSTALL_DATADIR}/furnace) - install(FILES res/logo.png RENAME furnace.png DESTINATION ${CMAKE_INSTALL_DATADIR}/pixmaps) + install(FILES res/logo.png RENAME furnace.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/1024x1024/apps) endif() set(CPACK_PACKAGE_NAME "Furnace") diff --git a/README.md b/README.md index 731741220..1edc53d56 100644 --- a/README.md +++ b/README.md @@ -98,6 +98,23 @@ cmake .. make ``` +### CMake options + +To add an option from the command-line: `-D=` +Example: `cmake -DBUILD_GUI=OFF -DWARNINGS_ARE_ERRORS=ON ..` + +Available options: + +| Name | Default | Description | +| :--: | :-----: | ----------- | +| `BUILD_GUI` | `ON` if not building for Android, otherwise `OFF` | Build the tracker (disable to build only a headless player) | +| `WITH_JACK` | `ON` if system-installed JACK detected, otherwise `OFF` | Whether to build with JACK support. Auto-detects if JACK is available | +| `SYSTEM_FMT` | `OFF` | Use a system-installed version of fmt instead of the vendored one | +| `SYSTEM_LIBSNDFILE` | `OFF` | Use a system-installed version of libsndfile instead of the vendored one | +| `SYSTEM_ZLIB` | `OFF` | Use a system-installed version of zlib instead of the vendored one | +| `SYSTEM_SDL2` | `OFF` | Use a system-installed version of SDL2 instead of the vendored one | +| `WARNINGS_ARE_ERRORS` | `OFF` (but consider enabling this & reporting any errors that arise from it!) | Whether warnings in furnace's C++ code should be treated as errors | + ## usage ``` diff --git a/src/audio/sdl.h b/src/audio/sdl.h index 6b2968552..f8f106414 100644 --- a/src/audio/sdl.h +++ b/src/audio/sdl.h @@ -1,9 +1,5 @@ #include "taAudio.h" -#if (defined(_WIN32) || defined(HAVE_GUI)) && !defined(DEVENDOR_LIBRARIES) #include -#else -#include -#endif class TAAudioSDL: public TAAudio { SDL_AudioSpec ac, ar;