cmake_minimum_required(VERSION 3.12) option(NO_FEATURE_REPORT "Disable feature report function" OFF) option(NO_LFS_ALIAS "disable alias wrappers for largefile bitness (mpg123_seek_32 or mpg123_seek_64 in addition to mpg123_seek, or the other way around; It is a mess, do not play with this!)" OFF) set(HAVE_FPU ON) include_directories("${CMAKE_CURRENT_BINARY_DIR}" "${MPG123_SOURCE_DIR}/src/libmpg123/") include(../../cmake/CheckCPUArch.cmake) if(HAVE_STDLIB_H) set(INCLUDE_STDLIB_H "#include ") else() set(INCLUDE_STDLIB_H "/* #include is not available on this system */") endif() if(HAVE_SYS_TYPES_H) set(INCLUDE_SYS_TYPE_H "#include ") else() set(INCLUDE_SYS_TYPE_H "/* #include is not available on this system */") endif() check_cpu_arch_x86(ARCH_IS_X86) check_cpu_arch_x64(ARCH_IS_X64) check_cpu_arch_arm32(ARCH_IS_ARM32) check_cpu_arch_arm64(ARCH_IS_ARM64) # PPC with AltiVec is missing. But probably obsolete enough for CMake users. if(ARCH_IS_X64) set(MACHINE amd64) elseif(ARCH_IS_X86) set(MACHINE x86) elseif(ARCH_IS_ARM64) set(MACHINE arm64) elseif(ARCH_IS_ARM32) set(MACHINE arm32) else() message(WARNING "Unknown processor. Using generic optimizations.") set(MACHINE generic) endif() message(STATUS "Detected machine: ${MACHINE}") configure_file("${MPG123_SOURCE_DIR}/src/libmpg123/mpg123.h.in" mpg123.h) set(TARGET lib${PROJECT_NAME}) add_library(${TARGET} "${MPG123_SOURCE_DIR}/src/libmpg123/parse.c" "${MPG123_SOURCE_DIR}/src/libmpg123/frame.c" "${MPG123_SOURCE_DIR}/src/libmpg123/format.c" "${MPG123_SOURCE_DIR}/src/libmpg123/dct64.c" "${MPG123_SOURCE_DIR}/src/libmpg123/equalizer.c" "${MPG123_SOURCE_DIR}/src/libmpg123/id3.c" "${MPG123_SOURCE_DIR}/src/libmpg123/optimize.c" "${MPG123_SOURCE_DIR}/src/libmpg123/readers.c" "${MPG123_SOURCE_DIR}/src/libmpg123/tabinit.c" "${MPG123_SOURCE_DIR}/src/libmpg123/libmpg123.c" "${MPG123_SOURCE_DIR}/src/libmpg123/index.c" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$>:icy.c>" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$>:icy2utf8.c>" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$>:layer1.c>" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$,$>>:layer2.c>" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$>:layer3.c>" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$>:lfs_alias.c>" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$>:ntom.c>" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$>:synth_8bit.c>" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$>:synth.c>" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$,$>>:synth_s32.c>" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$,$>>:synth_real.c>" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$>:stringbuf.c>" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$>:feature.c>" "${MPG123_SOURCE_DIR}/src/libmpg123/$<$:lfs_wrap.c>" "${MPG123_SOURCE_DIR}/src/compat/compat.c" "${MPG123_SOURCE_DIR}/src/compat/compat_str.c" ) if(MACHINE STREQUAL "amd64") if(HAVE_FPU) set(PLATFORM_DEFINITIONS OPT_MULTI OPT_X86_64 OPT_AVX OPT_GENERIC OPT_GENERIC_DITHER) set(PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/dct36_x86_64.S" "${MPG123_SOURCE_DIR}/src/libmpg123/dct64_x86_64_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_x86_64_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_x86_64_s32.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_x86_64_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_x86_64_s32.S" "${MPG123_SOURCE_DIR}/src/libmpg123/dct36_avx.S" "${MPG123_SOURCE_DIR}/src/libmpg123/dct64_avx_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_avx_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_avx_s32.S" "${MPG123_SOURCE_DIR}/src/libmpg123/getcpuflags_x86_64.S") target_sources(${TARGET} PRIVATE "${MPG123_SOURCE_DIR}/src/libmpg123/dither.c") if(ACCURATE_ROUNDING) list(APPEND PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/synth_x86_64_accurate.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_x86_64_accurate.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_avx_accurate.S") else() list(APPEND PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/dct64_x86_64.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_x86_64.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_x86_64.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_avx.S" "${MPG123_SOURCE_DIR}/src/libmpg123/dct64_avx.S") endif() else() set(PLATFORM_DEFINITIONS OPT_GENERIC) endif() elseif(MACHINE STREQUAL "x86") if(TRUE) set(PLATFORM_DEFINITIONS OPT_I386) target_sources(${TARGET} PRIVATE "${MPG123_SOURCE_DIR}/src/libmpg123/dct64_i386.c") endif() cmake_host_system_information(RESULT HAVE_SSE QUERY HAS_SSE) if(HAVE_SSE) set(PLATFORM_DEFINITIONS OPT_SSE) set(PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/tabinit_mmx.S" "${MPG123_SOURCE_DIR}/src/libmpg123/dct36_sse.S" "${MPG123_SOURCE_DIR}/src/libmpg123/dct64_sse_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_sse_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_sse_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_sse_s32.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_sse_s32.S") if(ACCURATE_ROUNDING) list(APPEND PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/synth_sse_accurate.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_sse_accurate.S") else() list(APPEND PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/dct64_sse.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_sse.S") endif() target_sources(${TARGET} PRIVATE "${MPG123_SOURCE_DIR}/src/libmpg123/dct64_i386.c") endif() elseif(MACHINE STREQUAL "arm64") if(MSVC) set(PLATFORM_DEFINITIONS OPT_GENERIC) message(WARNING "Cannot use platform-specific assembly sources on MSVC") else() set(PLATFORM_DEFINITIONS OPT_MULTI OPT_GENERIC OPT_GENERIC_DITHER OPT_NEON64) set(PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/dct36_neon64.S" "${MPG123_SOURCE_DIR}/src/libmpg123/dct64_neon64_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_neon64_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_neon64_s32.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_neon64_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_neon64_s32.S" "${MPG123_SOURCE_DIR}/src/libmpg123/check_neon.S") if(ACCURATE_ROUNDING) list(APPEND PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/synth_neon64_accurate.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_neon64_accurate.S") else() list(APPEND PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/synth_neon64.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_neon64.S") endif() target_sources(${TARGET} PRIVATE "${MPG123_SOURCE_DIR}/src/libmpg123/dither.c" "${MPG123_SOURCE_DIR}/src/libmpg123/getcpuflags_arm.c") endif() elseif(MACHINE STREQUAL "arm32") if(HAVE_FPU) if(MSVC) set(PLATFORM_DEFINITIONS OPT_GENERIC) message(WARNING "Cannot use platform-specific assembly sources on MSVC") else() set(PLATFORM_DEFINITIONS OPT_MULTI OPT_GENERIC OPT_GENERIC_DITHER OPT_NEON) set(PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/dct36_neon.S" "${MPG123_SOURCE_DIR}/src/libmpg123/dct64_neon_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_neon_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_neon_s32.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_neon_float.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_neon_s32.S" "${MPG123_SOURCE_DIR}/src/libmpg123/check_neon.S") target_sources(${TARGET} PRIVATE "${MPG123_SOURCE_DIR}/src/libmpg123/getcpuflags_arm.c") if(ACCURATE_ROUNDING) list(APPEND PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/synth_neon_accurate.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_neon_accurate.S") else() list(APPEND PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/dct64_neon.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_neon.S" "${MPG123_SOURCE_DIR}/src/libmpg123/synth_stereo_neon.S") endif() target_sources(${TARGET} PRIVATE ${PLATFORM_SOURCES}) target_sources(${TARGET} PRIVATE "${MPG123_SOURCE_DIR}/src/libmpg123/dither.c") endif() else() if(MSVC) set(PLATFORM_DEFINITIONS OPT_GENERIC) message(WARNING "Cannot use platform-specific assembly sources on MSVC") else() set(PLATFORM_DEFINITIONS OPT_ARM) if(ACCURATE_ROUNDING) set(PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/synth_arm_accurate.S") else() set(PLATFORM_SOURCES "${MPG123_SOURCE_DIR}/src/libmpg123/synth_arm.S") endif() target_sources(${TARGET} PRIVATE ${PLATFORM_SOURCES}) endif() endif() elseif(MACHINE STREQUAL "generic") set(PLATFORM_DEFINITIONS OPT_GENERIC) endif() set_target_properties(${TARGET} PROPERTIES OUTPUT_NAME mpg123) target_compile_definitions(${TARGET} PRIVATE ${PLATFORM_DEFINITIONS} $<$:REAL_IS_FLOAT> $<$>:REAL_IS_FIXED>) if(MSVC AND MACHINE MATCHES "x86|amd64") find_program(YASM_ASSEMBLER yasm) if(NOT YASM_ASSEMBLER) message(FATAL_ERROR "Couldn't find yasm assembler. Please set YASM_ASSEMBLER variable") endif() list(TRANSFORM PLATFORM_DEFINITIONS PREPEND /D) foreach(FILE ${PLATFORM_SOURCES}) get_filename_component(FILENAME ${FILE} NAME) add_custom_command( OUTPUT ${FILENAME}.asm COMMAND ${CMAKE_C_COMPILER} /DASMALIGN_BALIGN ${PLATFORM_DEFINITIONS} /I"${MPG123_SOURCE_DIR}/src" /I"${PROJECT_BINARY_DIR}/src" /P /Fi${FILENAME}.asm /Tc "${FILE}" DEPENDS ${FILE} WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") add_custom_command( OUTPUT ${FILENAME}.obj COMMAND ${YASM_ASSEMBLER} -a x86 -m ${MACHINE} -p gas -r raw -f win32 -g null -o ${FILENAME}.obj ${FILENAME}.asm DEPENDS ${FILENAME}.asm WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}") target_sources(${TARGET} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/${FILENAME}.obj") endforeach() else() target_sources(${TARGET} PRIVATE ${PLATFORM_SOURCES}) endif() target_link_libraries(${TARGET} PRIVATE $<$:m> $<$:shlwapi>) target_include_directories(${TARGET} INTERFACE "$" "$") if(INSTALL_PROGRAMS) install(TARGETS ${TARGET} EXPORT targets ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}/" LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}/" RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}/") install(FILES "${CMAKE_CURRENT_BINARY_DIR}/mpg123.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") install(FILES "${MPG123_SOURCE_DIR}/src/libmpg123/fmt123.h" DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}") endif()