#### libvgm #### cmake_minimum_required(VERSION 3.1) if(POLICY CMP0042) cmake_policy(SET CMP0042 NEW) endif() if(POLICY CMP0048) cmake_policy(SET CMP0048 NEW) endif() if(POLICY CMP0074) cmake_policy(SET CMP0074 NEW) endif() project(libvgmMain VERSION 0.1 LANGUAGES C CXX) set(CMAKE_CXX_STANDARD 14) list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/libs/cmake_modules/") include(GNUInstallDirs) include(CheckIncludeFile) include("${PROJECT_SOURCE_DIR}/cmake/utils.cmake") set(LIBVGM_NAME "libvgm") # for use in subdirectories set(LIBVGM_VERSION ${PROJECT_VERSION}) # for use in subdirectories set(LIBVGM_SOURCE_DIR ${PROJECT_SOURCE_DIR}) # for use in subdirectories set(LIBVGM_INSTALL_INCLUDE_DIR "${CMAKE_INSTALL_INCLUDEDIR}/vgm") set(LIBVGM_INSTALL_TARGETS) # will be filled in by sub-projects set(LIBVGM_DEPS) # will be filled in by sub-projects set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") # Chip Player JS preferred settings if(${CMAKE_SYSTEM_NAME} MATCHES "Emscripten") set(USE_FLAGS "-s USE_ZLIB=1") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${USE_FLAGS}") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${USE_FLAGS}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${USE_FLAGS}") endif() cmake_policy(SET CMP0077 NEW) set(AUDIODRV_WAVEWRITE OFF CACHE BOOL "Enable WaveWriter audio driver.") set(BUILD_LIBAUDIO OFF CACHE BOOL "Build libaudio.") set(BUILD_PLAYER OFF CACHE BOOL "Build player application.") set(BUILD_VGM2WAV OFF CACHE BOOL "Build vgm2wav.") set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." FORCE) set(EMSCRIPTEN ON CACHE BOOL "If true, we are targeting Emscripten output.") set(EMSCRIPTEN_FORCE_COMPILERS ON CACHE BOOL "Force C/C++ compiler") set(EMSCRIPTEN_GENERATE_BITCODE_STATIC_LIBRARIES OFF CACHE BOOL "Generate LLVM bitcode static libraries") set(LIBRARY_TYPE STATIC CACHE STRING "Build static or shared library.") set(LINK_STATIC_LIBS OFF) set(SANITIZE_ADDRESS OFF CACHE BOOL "Enable AddressSanitizer for sanitized targets.") set(SANITIZE_LINK_STATIC OFF CACHE BOOL "Try to link static against sanitizers.") set(SANITIZE_MEMORY OFF CACHE BOOL "Enable MemorySanitizer for sanitized targets.") set(SANITIZE_THREAD OFF CACHE BOOL "Enable ThreadSanitizer for sanitized targets.") set(SANITIZE_UNDEFINED OFF CACHE BOOL "Enable UndefinedBehaviorSanitizer for sanitized targets.") set(SNDEMU_32X_PWM_ALL ON CACHE BOOL "Sound Device PWM: all cores") set(SNDEMU_AY8910_ALL ON CACHE BOOL "Sound Device AY8910: all cores") set(SNDEMU_AY8910_EMU OFF CACHE BOOL "Sound Device AY8910: EMU2149 core") set(SNDEMU_AY8910_MAME OFF CACHE BOOL "Sound Device AY8910: MAME core") set(SNDEMU_C140_ALL ON CACHE BOOL "Sound Device C140: all cores") set(SNDEMU_C219_ALL ON CACHE BOOL "Sound Device C219: all cores") set(SNDEMU_C352_ALL ON CACHE BOOL "Sound Device C352: all cores") set(SNDEMU_C6280_ALL OFF CACHE BOOL "Sound Device HuC6280: all cores") set(SNDEMU_C6280_MAME ON CACHE BOOL "Sound Device HuC6280: MAME core") set(SNDEMU_C6280_OOTAKE OFF CACHE BOOL "Sound Device HuC6280: Ootake core") set(SNDEMU_ES5503_ALL ON CACHE BOOL "Sound Device ES5503: all cores") set(SNDEMU_ES5506_ALL ON CACHE BOOL "Sound Device ES5505/ES5506: all cores") set(SNDEMU_GA20_ALL ON CACHE BOOL "Sound Device Irem GA20: all cores") set(SNDEMU_GAMEBOY_ALL ON CACHE BOOL "Sound Device GameBoy DMG: all cores") set(SNDEMU_K051649_ALL ON CACHE BOOL "Sound Device K051649: all cores") set(SNDEMU_K053260_ALL ON CACHE BOOL "Sound Device K053260: all cores") set(SNDEMU_K054539_ALL ON CACHE BOOL "Sound Device K054539: all cores") set(SNDEMU_MIKEY_ALL ON CACHE BOOL "Sound Device Mikey: all cores") set(SNDEMU_NESAPU_ALL OFF CACHE BOOL "Sound Device NES APU: all cores") set(SNDEMU_NESAPU_FDS OFF CACHE BOOL "Sound Device NES APU: NSFPlay FDS core") set(SNDEMU_NESAPU_MAME OFF CACHE BOOL "Sound Device NES APU: MAME core") set(SNDEMU_NESAPU_NSFPLAY ON CACHE BOOL "Sound Device NES APU: NSFPlay core") set(SNDEMU_OKIM6258_ALL ON CACHE BOOL "Sound Device OKI MSM6258: all cores") set(SNDEMU_OKIM6295_ALL ON CACHE BOOL "Sound Device OKI MSM6295: all cores") set(SNDEMU_POKEY_ALL ON CACHE BOOL "Sound Device POKEY: all cores") set(SNDEMU_QSOUND_ALL OFF CACHE BOOL "Sound Device QSound: all cores") set(SNDEMU_QSOUND_CTR OFF CACHE BOOL "Sound Device QSound: superctr core") set(SNDEMU_QSOUND_MAME ON CACHE BOOL "Sound Device QSound: MAME core") set(SNDEMU_RF5C68_ALL ON CACHE BOOL "Sound Device RF5C68: all cores") set(SNDEMU_RF5C68_GENS OFF CACHE BOOL "Sound Device RF5C68: Gens core") set(SNDEMU_RF5C68_MAME OFF CACHE BOOL "Sound Device RF5C68: MAME core") set(SNDEMU_SAA1099_ALL OFF CACHE BOOL "Sound Device SAA1099: all cores") set(SNDEMU_SAA1099_MAME ON CACHE BOOL "Sound Device SAA1099: MAME core") set(SNDEMU_SAA1099_VB OFF CACHE BOOL "Sound Device SAA1099: Valley Bell core") set(SNDEMU_SCSP_ALL ON CACHE BOOL "Sound Device SCSP: all cores") set(SNDEMU_SEGAPCM_ALL ON CACHE BOOL "Sound Device SegaPCM: all cores") set(SNDEMU_SN76496_ALL OFF CACHE BOOL "Sound Device SN76496: all cores") set(SNDEMU_SN76496_MAME ON CACHE BOOL "Sound Device SN76496: MAME core") set(SNDEMU_SN76496_MAXIM OFF CACHE BOOL "Sound Device SN76496: Maxim core") set(SNDEMU_UPD7759_ALL ON CACHE BOOL "Sound Device uPD7759: all cores") set(SNDEMU_VBOY_VSU_ALL ON CACHE BOOL "Sound Device VirtualBoy VSU: all cores") set(SNDEMU_WSWAN_ALL ON CACHE BOOL "Sound Device WonderSwan: all cores") set(SNDEMU_X1_010_ALL ON CACHE BOOL "Sound Device X1-010: all cores") set(SNDEMU_Y8950_ALL ON CACHE BOOL "Sound Device Y8950: all cores") set(SNDEMU_YM2151_ALL OFF CACHE BOOL "Sound Device YM2151: all cores") set(SNDEMU_YM2151_MAME ON CACHE BOOL "Sound Device YM2151: MAME core") set(SNDEMU_YM2151_NUKED OFF CACHE BOOL "Sound Device YM2151: Nuked OPM core") set(SNDEMU_YM2203_ALL ON CACHE BOOL "Sound Device YM2203: all cores (Note: requires AY8910)") set(SNDEMU_YM2413_ALL OFF CACHE BOOL "Sound Device YM2413: all cores") set(SNDEMU_YM2413_EMU ON CACHE BOOL "Sound Device YM2413: EMU2413 core") set(SNDEMU_YM2413_MAME OFF CACHE BOOL "Sound Device YM2413: MAME core") set(SNDEMU_YM2413_NUKED OFF CACHE BOOL "Sound Device YM2413: Nuked OPLL core") set(SNDEMU_YM2608_ALL ON CACHE BOOL "Sound Device YM2608: all cores (Note: requires AY8910)") set(SNDEMU_YM2610_ALL ON CACHE BOOL "Sound Device YM2610: all cores (Note: requires AY8910)") set(SNDEMU_YM2612_ALL OFF CACHE BOOL "Sound Device YM2612: all cores") set(SNDEMU_YM2612_GENS OFF CACHE BOOL "Sound Device YM2612: Gens core") set(SNDEMU_YM2612_GPGX ON CACHE BOOL "Sound Device YM2612: MAME/Genesis Plus GX core") set(SNDEMU_YM2612_NUKED OFF CACHE BOOL "Sound Device YM2612: Nuked OPN2 core") set(SNDEMU_YM3526_ALL ON CACHE BOOL "Sound Device YM3526: all cores") set(SNDEMU_YM3812_ADLIBEMU OFF CACHE BOOL "Sound Device YM3812: AdLibEmu core") set(SNDEMU_YM3812_ALL OFF CACHE BOOL "Sound Device YM3812: all cores") set(SNDEMU_YM3812_MAME ON CACHE BOOL "Sound Device YM3812: MAME core") set(SNDEMU_YM3812_NUKED OFF CACHE BOOL "Sound Device YM3812: Nuked OPL3 core") set(SNDEMU_YMF262_ADLIBEMU OFF CACHE BOOL "Sound Device YMF262: AdLibEmu core") set(SNDEMU_YMF262_ALL OFF CACHE BOOL "Sound Device YMF262: all cores") set(SNDEMU_YMF262_MAME ON CACHE BOOL "Sound Device YMF262: MAME core") set(SNDEMU_YMF262_NUKED OFF CACHE BOOL "Sound Device YMF262: Nuked OPL3 core") set(SNDEMU_YMF271_ALL ON CACHE BOOL "Sound Device YMF271: all cores") set(SNDEMU_YMF278B_ALL ON CACHE BOOL "Sound Device YMF278B: all cores (Note: requires YMF262)") set(SNDEMU_YMW258_ALL ON CACHE BOOL "Sound Device YMW258: all cores") set(SNDEMU_YMZ280B_ALL ON CACHE BOOL "Sound Device YMZ280B: all cores") set(SNDEMU__ALL OFF CACHE BOOL "build all sound devices (overrides other selections)") set(SNDEMU__PRESET_IBM_PC OFF CACHE BOOL "Sound Dev. Preset: IBM PC (Tandy/CMS/Sound Blaster)") set(SNDEMU__PRESET_MSX OFF CACHE BOOL "Sound Dev. Preset: MSX (with extensions)") set(SNDEMU__PRESET_NES OFF CACHE BOOL "Sound Dev. Preset: NES/Famicom (with extensions)") set(SNDEMU__PRESET_S98 OFF CACHE BOOL "Sound Dev. Preset: S98 logs") set(SNDEMU__PRESET_SMD OFF CACHE BOOL "Sound Dev. Preset: Sega MegaDrive (with CD/32X)") set(SNDEMU__PRESET_SMS OFF CACHE BOOL "Sound Dev. Preset: Sega Master System/Game Gear") set(USE_SANITIZERS ON CACHE BOOL "use sanitizers") set(UTIL_CHARCNV_ICONV ON CACHE BOOL "Charset Conversion: iconv") set(UTIL_CHARCNV_WINAPI OFF CACHE BOOL "Charset Conversion: WinAPI") set(UTIL_CHARSET_CONV ON CACHE BOOL "build charset conversion functions") set(UTIL_LOADERS ON CACHE BOOL "build data (file/memory) loaders, requires zlib") set(UTIL_THREADING OFF CACHE BOOL "build threading utilities (thread/mutex/signal)") if ("${CMAKE_VERSION}" VERSION_LESS "3.20") include(TestBigEndian) test_big_endian(ARCH_BIG_ENDIAN) if (ARCH_BIG_ENDIAN) set(CMAKE_C_BYTE_ORDER "BIG_ENDIAN") else() set(CMAKE_C_BYTE_ORDER "LITTLE_ENDIAN") endif() endif() # add defines for Little/Big Endian if ("${CMAKE_C_BYTE_ORDER}" STREQUAL "BIG_ENDIAN") add_definitions("-D VGM_BIG_ENDIAN") else() add_definitions("-D VGM_LITTLE_ENDIAN") endif() check_include_file("stdint.h" HAVE_STDINT) if(HAVE_STDINT) add_definitions("-D HAVE_STDINT_H") endif() if(MSVC) set(CMAKE_DEBUG_POSTFIX "d") if(MSVC_VERSION LESS 1400) set(MSVC_POSTFIX "VC6") # there are a few limitations for MSVC versions before 2005 elseif(CMAKE_CL_64) set(MSVC_POSTFIX "Win64") else() set(MSVC_POSTFIX "Win32") endif() set(CMAKE_RELEASE_POSTFIX "_${MSVC_POSTFIX}${CMAKE_RELEASE_POSTFIX}") set(CMAKE_DEBUG_POSTFIX "_${MSVC_POSTFIX}${CMAKE_DEBUG_POSTFIX}") set(CMAKE_MINSIZEREL_POSTFIX "_${MSVC_POSTFIX}${CMAKE_MINSIZEREL_POSTFIX}") set(CMAKE_RELWITHDEBINFO_POSTFIX "_${MSVC_POSTFIX}${CMAKE_RELWITHDEBINFO_POSTFIX}") set(ZLIB_ROOT "${PROJECT_SOURCE_DIR}/libs" CACHE PATH "ZLib directory") set(Iconv_INCLUDE_DIR "${PROJECT_SOURCE_DIR}/libs/iconv/include" CACHE PATH "directory with iconv headers") set(Iconv_LIBRARY "${PROJECT_SOURCE_DIR}/libs/iconv/lib/libiconv.lib" CACHE FILEPATH "iconv library") if(NOT MSVC_VERSION LESS 1400) # Note: CMake 3.12 and up have add_compile_options() add_definitions("-D _CRT_SECURE_NO_WARNINGS") endif() endif() if(MINGW) option(LINK_STATIC_LIBS "link with static runtime libraries (MinGW only)" ON) if(LINK_STATIC_LIBS) set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) set(CMAKE_CXX_STANDARD_LIBRARIES "-static-libgcc -static-libstdc++ -lwsock32 -lws2_32 ${CMAKE_CXX_STANDARD_LIBRARIES}") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive") endif() else() option(LINK_STATIC_LIBS "link with static runtime libraries (MinGW only)" OFF) endif() if(CMAKE_COMPILER_IS_GNUCC) # assume Windows 2000 and later for GetConsoleWindow API call if(WIN32) add_definitions("-D _WIN32_WINNT=0x500") endif() set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -D_DEBUG") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall") #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wextra") #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpedantic") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wno-unused-parameter -Wno-unused-but-set-variable -Wno-long-long -Wno-unused-value") # silence typical sound core warnings set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wno-unknown-pragmas") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wno-sign-compare") set(CMAKE_C_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -Wno-unused-variable -Wno-unused-const-variable -Wno-unused-function") # additional warnings from http://blog.httrack.com/blog/2014/03/09/what-are-your-gcc-flags/ set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wpointer-arith -Winit-self -Wstrict-aliasing") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wformat -Wformat-security -Wformat-nonliteral") #set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fstack-protector") #set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fstack-protector") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS}") set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} ${CMAKE_C_FLAGS_DEBUG}") set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} ${CMAKE_C_FLAGS_RELEASE}") endif(CMAKE_COMPILER_IS_GNUCC) list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/sanitizers") find_package(Sanitizers) option(BUILD_LIBAUDIO "build audio output library" ON) option(BUILD_LIBEMU "build sound emulation library" ON) option(BUILD_LIBPLAYER "build player library" ON) option(BUILD_TESTS "build test programs" OFF) option(BUILD_PLAYER "build player application" ON) option(BUILD_VGM2WAV "build sample vgm2wav application" ON) set(LIBRARY_TYPE "STATIC" CACHE STRING "library build type (static/shared)") set_property(CACHE LIBRARY_TYPE PROPERTY STRINGS "SHARED;STATIC") option(USE_SANITIZERS "use sanitizers" ON) # --- main library --- add_subdirectory(utils) if(USE_SANITIZERS) add_sanitizers(utils) endif(USE_SANITIZERS) if(BUILD_LIBAUDIO) add_subdirectory(audio) if(USE_SANITIZERS) add_sanitizers(vgm-audio) endif(USE_SANITIZERS) endif() if(BUILD_LIBEMU) add_subdirectory(emu) if(USE_SANITIZERS) add_sanitizers(vgm-emu) endif(USE_SANITIZERS) endif() if(BUILD_LIBPLAYER) add_subdirectory(player) if(USE_SANITIZERS) add_sanitizers(vgm-player) endif(USE_SANITIZERS) endif() # --- additional stuff --- if(BUILD_TESTS) add_executable(audiotest audiotest.c) target_include_directories(audiotest PRIVATE ${LIBVGM_SOURCE_DIR}) target_link_libraries(audiotest PRIVATE vgm-audio) if(USE_SANITIZERS) add_sanitizers(audiotest) endif(USE_SANITIZERS) add_executable(emutest emutest.c) target_include_directories(emutest PRIVATE ${LIBVGM_SOURCE_DIR}) target_link_libraries(emutest PRIVATE vgm-emu) if(USE_SANITIZERS) add_sanitizers(emutest) endif(USE_SANITIZERS) add_executable(audemutest audemutest.c) target_include_directories(audemutest PRIVATE ${LIBVGM_SOURCE_DIR}) target_link_libraries(audemutest PRIVATE vgm-audio vgm-emu) if(USE_SANITIZERS) add_sanitizers(audemutest) endif(USE_SANITIZERS) find_package(ZLIB REQUIRED) add_executable(vgmtest vgmtest.c player/dblk_compr.c) target_include_directories(vgmtest PRIVATE ${LIBVGM_SOURCE_DIR}) target_link_libraries(vgmtest PRIVATE ZLIB::ZLIB vgm-audio vgm-emu) if(USE_SANITIZERS) add_sanitizers(vgmtest) endif(USE_SANITIZERS) install(TARGETS audiotest emutest audemutest vgmtest DESTINATION "${CMAKE_INSTALL_BINDIR}") endif(BUILD_TESTS) if(BUILD_PLAYER) add_executable(player player.cpp player/dblk_compr.c) target_include_directories(player PRIVATE ${LIBVGM_SOURCE_DIR}) target_link_libraries(player PRIVATE vgm-audio vgm-player vgm-utils) if(USE_SANITIZERS) add_sanitizers(player) endif(USE_SANITIZERS) install(TARGETS player DESTINATION "${CMAKE_INSTALL_BINDIR}") endif(BUILD_PLAYER) if(BUILD_VGM2WAV) add_executable(vgm2wav vgm2wav.cpp) target_include_directories(vgm2wav PRIVATE ${LIBVGM_SOURCE_DIR}) target_link_libraries(vgm2wav PRIVATE vgm-player vgm-emu vgm-utils) if(USE_SANITIZERS) add_sanitizers(vgm2wav) endif(USE_SANITIZERS) install(TARGETS vgm2wav DESTINATION "${CMAKE_INSTALL_BINDIR}") endif(BUILD_VGM2WAV) set(COMMON_HEADERS common_def.h stdbool.h stdtype.h ) install(FILES ${COMMON_HEADERS} DESTINATION "${LIBVGM_INSTALL_INCLUDE_DIR}") cmake_cfg_install("${LIBVGM_SOURCE_DIR}/cmake/config.cmake.in" NAME "${LIBVGM_NAME}" VERSION "${LIBVGM_VERSION}" TARGETS "${LIBVGM_INSTALL_TARGETS}" DEPS "${LIBVGM_DEPS}" )