cmake_minimum_required(VERSION 3.5) project(vgmstream C) enable_language(CXX) # TODO defautl out-of-source-builds not working properly? # (like "cmake .." from ./build subdir creates makefiles on ./, unless using "cmake -S ..") get_directory_property(hasParent PARENT_DIRECTORY) if(hasParent) set(VGM_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR} PARENT_SCOPE) set(VGM_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE) endif() set(VGM_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(VGM_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) set(CMAKE_MODULE_PATH ${VGM_SOURCE_DIR}/cmake;${CMAKE_MODULE_PATH}) include(vgmstream) # Defaults for Windows, otherwise may be Program Files/vgmstream if(WIN32) IF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) SET(CMAKE_INSTALL_PREFIX ${VGM_SOURCE_DIR} CACHE PATH "..." FORCE) ENDIF(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) endif() function(set_mpeg onoff useForce) if(useForce) set(USE_FORCE_ FORCE) endif() set(USE_MPEG ${onoff} CACHE BOOL "Use libmpg123 for support of MPEG (MP1/MP2/MP3)" ${USE_FORCE_}) endfunction() function(set_vorbis onoff useForce) if(useForce) set(USE_FORCE_ FORCE) endif() set(USE_VORBIS ${onoff} CACHE BOOL "Use libvorbis for support of Vorbis" ${USE_FORCE_}) endfunction() function(set_ffmpeg onoff useForce) if(useForce) set(USE_FORCE_ FORCE) endif() set(USE_FFMPEG ${onoff} CACHE BOOL "Use FFmpeg for support of many codecs" ${USE_FORCE_}) endfunction() # Options set_mpeg(ON FALSE) set_vorbis(ON FALSE) set_ffmpeg(ON FALSE) option(USE_MAIATRAC3PLUS "Use MAIATRAC3+ for support of ATRAC3+" OFF) set(MAIATRAC3PLUS_PATH CACHE PATH "Path to MAIATRAC3+") option(USE_G7221 "Use G7221 for support of ITU-T G.722.1 annex C" ON) option(USE_G719 "Use libg719_decode for support ITU-T G.719" ON) if(NOT WIN32) set(G719_PATH CACHE PATH "Path to G.719 decoder") endif() if(WIN32) # May need to see if it is possible to get these to work on non-Windows systems too option(USE_ATRAC9 "Use LibAtrac9 for support of ATRAC9" ON) option(USE_CELT "Use libcelt for support of FSB CELT versions 0.6.1 and 0.11.0" ON) option(USE_SPEEX "Use libspeex for support of SPEEX" ON) endif() # Build choices option(BUILD_CLI "Build vgmstream CLI" ON) if(WIN32) if(MSVC) option(BUILD_FB2K "Build foobar2000 component" ON) set(FB2K_SDK_PATH CACHE PATH "Path to foobar2000 SDK") set(WTL_INCLUDE_PATH CACHE PATH "Path to WTL include directory") set(FB2K_COMPONENT_INSTALL_PREFIX CACHE PATH "Path to foobar2000 component installation directory") endif() option(BUILD_WINAMP "Build Winamp plugin" ON) set(WINAMP_INSTALL_PREFIX CACHE PATH "Path to Winamp installation directory") option(BUILD_XMPLAY "Build XMPlay plugin" ON) set(XMPLAY_INSTALL_PREFIX CACHE PATH "Path to XMPlay installation directory") else() option(BUILD_AUDACIOUS "Build Audacious plugin" ON) endif() # Autodetect some paths if(MSVC AND NOT FB2K_SDK_PATH AND IS_DIRECTORY "${VGM_SOURCE_DIR}/dependencies/foobar/") set(FB2K_SDK_PATH "${VGM_SOURCE_DIR}/dependencies/foobar/" CACHE PATH "..." FORCE) endif() if(MSVC AND NOT WTL_INCLUDE_PATH AND IS_DIRECTORY "${VGM_SOURCE_DIR}/dependencies/wtl/") set(WTL_INCLUDE_PATH "${VGM_SOURCE_DIR}/dependencies/wtl/" CACHE PATH "..." FORCE) endif() # Set autogenerated version if(MSVC) set(VGM_VERSION_GENERATOR version-make.bat) add_custom_command(OUTPUT ${VGM_SOURCE_DIR}/version_auto.h COMMAND "${VGM_SOURCE_DIR}/${VGM_VERSION_GENERATOR}" DEPENDS ${VGM_SOURCE_DIR}/${VGM_VERSION_GENERATOR}) else() # linux uses 'sh' so git-less (src zip) builds can run without chmod -x (script) set(VGM_VERSION_GENERATOR version-make.sh) add_custom_command(OUTPUT ${VGM_SOURCE_DIR}/version_auto.h COMMAND sh "${VGM_SOURCE_DIR}/${VGM_VERSION_GENERATOR}" DEPENDS ${VGM_SOURCE_DIR}/${VGM_VERSION_GENERATOR}) endif() add_custom_target(version_h ALL DEPENDS ${VGM_SOURCE_DIR}/version_auto.h) # FFmpeg detection if(USE_FFMPEG) find_package(FFmpeg) if(NOT FFMPEG_LIBRARIES) set_ffmpeg(OFF TRUE) else() if(${AVCODEC_VERSION} VERSION_LESS 57) set_ffmpeg(OFF TRUE) message("libavcodec version mismatch ${AVCODEC_VERSION} expected >=57") elseif(${AVUTIL_VERSION} VERSION_LESS 55) set_ffmpeg(OFF TRUE) message("libavutil version mismatch ${AVUTIL_VERSION} expected >=55") elseif(${SWRESAMPLE_VERSION} VERSION_LESS 2) set_ffmpeg(OFF TRUE) message("libswresample version mismatch ${SWRESAMPLE_VERSION} expected >=2") endif() endif() endif() if(WIN32) # Enable support for the resource compiler when using MinGW if(MINGW) enable_language(RC) # Not 100% sure this is needed, but in the past, MinGW's command for compiling resources was incorrect set(CMAKE_RC_COMPILE_OBJECT " -O coff -i -o ") endif(MINGW) set(CMAKE_EXECUTABLE_SUFFIX .exe) else() # Find the relevant packages if(USE_MPEG) find_package(MPG123) if(NOT MPG123_FOUND) set_mpeg(OFF TRUE) endif() endif() if(USE_VORBIS) find_package(VorbisFile) if(NOT VORBISFILE_FOUND) set_vorbis(OFF TRUE) endif() endif() # If building the CLI, we need to include AO as well if(BUILD_CLI) find_package(AO) if(AO_FOUND) set(USE_V123 ON) else (AO_FOUND) #TODO: add proper separate option set(USE_V123 OFF) endif() endif() find_package(PkgConfig REQUIRED) # Only build JSON dumping capabilities on Linux pkg_check_modules(JANSSON jansson>=2.3) if (JANSSON_FOUND) set(USE_JANSSON ON) set(JANSSON_PKG libjansson) include_directories(${JANSSON_INCLUDE_DIRS}) link_directories(${JANSSON_LIBRARY_DIRS}) else (JANSSON_FOUND) set(USE_JANSSON OFF) endif (JANSSON_FOUND) # If building Audacious, we need to make sure we can find its pkg-config module as well as GTK's if(BUILD_AUDACIOUS) pkg_search_module(AUDACIOUS REQUIRED audacious>=3.6) pkg_get_variable(AUDACIOUS_PLUGIN_DIR audacious plugin_dir) pkg_search_module(GTK REQUIRED gtk+-3.0 gtk+-2.0) endif() endif() # Set compiler flags if(CMAKE_CXX_COMPILER_ID MATCHES Clang OR CMAKE_CXX_COMPILER_ID MATCHES GNU) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") if(CMAKE_CXX_COMPILER_ID MATCHES Clang) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-parentheses-equality -Wno-header-guard -Wno-unused-function -Wno-shift-negative-value -Wno-deprecated-register") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-parentheses-equality -Wno-header-guard -Wno-unused-function -Wno-shift-negative-value -Wno-deprecated-register") elseif() if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 5.9) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-misleading-indentation") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-misleading-indentation") endif() if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 4.0) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-attributes") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-attributes") endif() if(CMAKE_CXX_COMPILER_VERSION VERSION_GREATER 2.99) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-function") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-function") endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-format -Wno-sign-compare") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-format -Wno-sign-compare") endif() elseif(MSVC) if(CMAKE_C_FLAGS MATCHES "/W[0-4]") string(REGEX REPLACE "/W[0-4]" "/W3" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") else() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /W3") endif() if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]") string(REGEX REPLACE "/W[0-4]" "/W3" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W3") endif() set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /wd4005 /wd4018 /wd4244 /wd4302 /wd4838") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4005 /wd4018 /wd4244 /wd4302 /wd4838") endif() # Add other projects and subdirectories as needed if(USE_MAIATRAC3PLUS) if(MAIATRAC3PLUS_PATH) add_subdirectory(${MAIATRAC3PLUS_PATH}/MaiAT3PlusDecoder ${VGM_BINARY_DIR}/maitrac3plus) else() message(FATAL_ERROR "Path to MAIATRAC3+ must be set. (Use MAIATRAC3PLUS_PATH)") endif() endif() if(NOT WIN32 AND USE_G719) if(G719_PATH) configure_file( ${VGM_SOURCE_DIR}/ext_libs/libg719_decode/CMakeLists.txt ${G719_PATH}/CMakeLists.txt COPYONLY) add_subdirectory(${G719_PATH}) else() find_package(Git QUIET) if(Git_FOUND) include(FetchContent) FetchContent_Populate(libg719_decode GIT_REPOSITORY https://github.com/kode54/libg719_decode.git SOURCE_DIR ${VGM_SOURCE_DIR}/dependencies/libg719_decode ) configure_file( ${VGM_SOURCE_DIR}/ext_libs/libg719_decode/CMakeLists.txt ${VGM_SOURCE_DIR}/dependencies/libg719_decode/CMakeLists.txt COPYONLY) add_subdirectory(${libg719_decode_SOURCE_DIR}) else() set(USE_G719 OFF) endif() endif() endif() add_subdirectory(src) if(WIN32) add_subdirectory(ext_libs) if(BUILD_WINAMP) if(NOT WINAMP_INSTALL_PREFIX) set(WINAMP_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/winamp) endif() add_subdirectory(winamp) endif() if(BUILD_FB2K) if(NOT FB2K_SDK_PATH) message(FATAL_ERROR "The path to the foobar2000 SDK must be set. (Use FB2K_SDK_PATH)") endif() if(NOT WTL_INCLUDE_PATH) message(FATAL_ERROR "The path to the WTL include directory must be set. (Use WTL_INCLUDE_PATH)") endif() if(NOT FB2K_COMPONENT_INSTALL_PREFIX) set(FB2K_COMPONENT_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/fb2k) endif() include_external_msproject(fb2k_sdk ${FB2K_SDK_PATH}/foobar2000/SDK/foobar2000_SDK.vcxproj) include_external_msproject(fb2k_sdk_helpers ${FB2K_SDK_PATH}/foobar2000/helpers/foobar2000_sdk_helpers.vcxproj) include_external_msproject(fb2k_atl_helpers ${FB2K_SDK_PATH}/foobar2000/ATLHelpers/foobar2000_ATL_helpers.vcxproj) include_external_msproject(fb2k_component_client ${FB2K_SDK_PATH}/foobar2000/foobar2000_component_client/foobar2000_component_client.vcxproj) include_external_msproject(pfc ${FB2K_SDK_PATH}/pfc/pfc.vcxproj) add_subdirectory(fb2k) endif() if(BUILD_XMPLAY) if(NOT XMPLAY_INSTALL_PREFIX) set(XMPLAY_INSTALL_PREFIX ${CMAKE_INSTALL_PREFIX}/xmplay) endif() add_subdirectory(xmplay) endif() else() if(BUILD_AUDACIOUS) add_subdirectory(audacious) endif() endif() if(BUILD_CLI) if(WIN32) add_subdirectory(ext_libs/Getopt) endif() add_subdirectory(cli) endif() # Option Summary message(STATUS " Option Summary") message(STATUS "=================") message(STATUS " MPEG: ${USE_MPEG}") message(STATUS " Vorbis: ${USE_VORBIS}") message(STATUS " FFmpeg: ${USE_FFMPEG}") message(STATUS " MAIATRAC3+: ${USE_MAIATRAC3PLUS}") message(STATUS " G.722.1: ${USE_G7221}") message(STATUS " G.719: ${USE_G719}") if(WIN32) message(STATUS " ATRAC9: ${USE_ATRAC9}") message(STATUS " FSB CELT: ${USE_CELT}") message(STATUS " SPEEX: ${USE_SPEEX}") endif() message(STATUS "") # Build Summary message(STATUS " Building") message(STATUS "=========================") if(WIN32) message(STATUS " CLI: ${BUILD_CLI}") message(STATUS " JSON dumping: ${USE_JANSSON}") message(STATUS "foobar2000 component: ${BUILD_FB2K}") message(STATUS " Winamp plugin: ${BUILD_WINAMP}") message(STATUS " XMPlay plugin: ${BUILD_XMPLAY}") else() message(STATUS " CLI: ${BUILD_CLI}") message(STATUS " vgmstream123: ${USE_V123}") message(STATUS " JSON dumping: ${USE_JANSSON}") message(STATUS "Audacious plugin: ${BUILD_AUDACIOUS}") endif() message(STATUS "") # Install Summary message(STATUS " Install Paths") message(STATUS "=========================") if(WIN32) if(BUILD_CLI) message(STATUS " CLI: ${CMAKE_INSTALL_PREFIX}/bin") endif() if(BUILD_FB2K) message(STATUS "foobar2000 component: ${FB2K_COMPONENT_INSTALL_PREFIX}") endif() if(BUILD_WINAMP) message(STATUS " Winamp plugin: ${WINAMP_INSTALL_PREFIX}") endif() if(BUILD_XMPLAY) message(STATUS " XMPlay plugin: ${XMPLAY_INSTALL_PREFIX}") endif() else() if(BUILD_CLI) message(STATUS "CLI/vgmstream123: ${CMAKE_INSTALL_PREFIX}/bin") endif() if(BUILD_AUDACIOUS) message(STATUS "Audacious plugin: ${AUDACIOUS_PLUGIN_DIR}/Input") endif() endif() message(STATUS "")