1*600f14f4SXin Li# 3.1 is OK for most parts. However: 2*600f14f4SXin Li# 3.3 is needed in src/libFLAC 3*600f14f4SXin Li# 3.5 is needed in src/libFLAC/ia32 4*600f14f4SXin Li# 3.9 is needed in 'doc' because of doxygen_add_docs() 5*600f14f4SXin Licmake_minimum_required(VERSION 3.5) 6*600f14f4SXin Li 7*600f14f4SXin Liif(NOT (CMAKE_BUILD_TYPE OR CMAKE_CONFIGURATION_TYPES OR DEFINED ENV{CFLAGS} OR DEFINED ENV{CXXFLAGS})) 8*600f14f4SXin Li set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build, options are: None Debug Release RelWithDebInfo") 9*600f14f4SXin Liendif() 10*600f14f4SXin Li 11*600f14f4SXin Liproject(FLAC VERSION 1.4.3) # HOMEPAGE_URL "https://www.xiph.org/flac/") 12*600f14f4SXin Li 13*600f14f4SXin Lilist(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake") 14*600f14f4SXin Li 15*600f14f4SXin Lioption(BUILD_CXXLIBS "Build libFLAC++" ON) 16*600f14f4SXin Lioption(BUILD_PROGRAMS "Build and install programs" ON) 17*600f14f4SXin Lioption(BUILD_EXAMPLES "Build and install examples" ON) 18*600f14f4SXin Lioption(BUILD_TESTING "Build tests" ON) 19*600f14f4SXin Lioption(BUILD_DOCS "Build and install doxygen documents" ON) 20*600f14f4SXin Lioption(WITH_FORTIFY_SOURCE "Enable protection against buffer overflows" ON) 21*600f14f4SXin Lioption(WITH_STACK_PROTECTOR "Enable GNU GCC stack smash protection" ON) 22*600f14f4SXin Lioption(INSTALL_MANPAGES "Install MAN pages" ON) 23*600f14f4SXin Lioption(INSTALL_PKGCONFIG_MODULES "Install PkgConfig modules" ON) 24*600f14f4SXin Lioption(INSTALL_CMAKE_CONFIG_MODULE "Install CMake package-config module" ON) 25*600f14f4SXin Lioption(WITH_OGG "ogg support (default: test for libogg)" ON) 26*600f14f4SXin Lioption(BUILD_SHARED_LIBS "Build shared instead of static libraries" OFF) 27*600f14f4SXin Li 28*600f14f4SXin Liset(VERSION ${PROJECT_VERSION}) 29*600f14f4SXin Li 30*600f14f4SXin Liif(NOT UNIX) 31*600f14f4SXin Li # This is to make sure testing works when building with a DLL 32*600f14f4SXin Li set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/objs) 33*600f14f4SXin Li set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/objs) 34*600f14f4SXin Liendif() 35*600f14f4SXin Li 36*600f14f4SXin Liif(WITH_OGG) 37*600f14f4SXin Li if(IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/ogg") 38*600f14f4SXin Li add_subdirectory("ogg") 39*600f14f4SXin Li set(OGG_FOUND 1 CACHE INTERNAL "ogg has been added as subdirectory") 40*600f14f4SXin Li set_target_properties(ogg PROPERTIES FOLDER Libraries) 41*600f14f4SXin Li if(BUILD_TESTING) 42*600f14f4SXin Li set_target_properties(test_bitwise test_framing PROPERTIES FOLDER Tests) 43*600f14f4SXin Li endif() 44*600f14f4SXin Li else() 45*600f14f4SXin Li if(NOT TARGET Ogg::ogg) 46*600f14f4SXin Li find_package(Ogg REQUIRED) 47*600f14f4SXin Li else() 48*600f14f4SXin Li set(OGG_FOUND 1 CACHE INTERNAL "ogg has already been built") 49*600f14f4SXin Li endif() 50*600f14f4SXin Li set(OGG_PACKAGE "ogg") 51*600f14f4SXin Li endif() 52*600f14f4SXin Liendif() 53*600f14f4SXin Li 54*600f14f4SXin Lifind_program (HAVE_GIT git) 55*600f14f4SXin Li 56*600f14f4SXin Liif(HAVE_GIT) 57*600f14f4SXin Li execute_process( 58*600f14f4SXin Li COMMAND git --git-dir=.git describe --tags --exact-match 59*600f14f4SXin Li WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 60*600f14f4SXin Li OUTPUT_VARIABLE GIT_COMMIT_TAG 61*600f14f4SXin Li OUTPUT_STRIP_TRAILING_WHITESPACE 62*600f14f4SXin Li ERROR_QUIET 63*600f14f4SXin Li ) 64*600f14f4SXin Li execute_process( 65*600f14f4SXin Li COMMAND git --git-dir=.git log -1 --pretty=format:%h 66*600f14f4SXin Li WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 67*600f14f4SXin Li OUTPUT_VARIABLE GIT_COMMIT_HASH 68*600f14f4SXin Li OUTPUT_STRIP_TRAILING_WHITESPACE 69*600f14f4SXin Li ERROR_QUIET 70*600f14f4SXin Li ) 71*600f14f4SXin Li execute_process( 72*600f14f4SXin Li COMMAND git --git-dir=.git log -1 --pretty=format:%cd --date=format:%Y%m%d 73*600f14f4SXin Li WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} 74*600f14f4SXin Li OUTPUT_VARIABLE GIT_COMMIT_DATE 75*600f14f4SXin Li OUTPUT_STRIP_TRAILING_WHITESPACE 76*600f14f4SXin Li ERROR_QUIET 77*600f14f4SXin Li ) 78*600f14f4SXin Liendif() 79*600f14f4SXin Li 80*600f14f4SXin Liif(NOT WIN32) 81*600f14f4SXin Li find_package(Iconv) 82*600f14f4SXin Li set(HAVE_ICONV ${Iconv_FOUND}) 83*600f14f4SXin Liendif() 84*600f14f4SXin Li 85*600f14f4SXin Liif(CMAKE_C_COMPILER_ID MATCHES "GNU|Clang") 86*600f14f4SXin Li set(CMAKE_C_FLAGS "-Wall -Wextra -Wstrict-prototypes -Wmissing-prototypes -Waggregate-return -Wcast-align -Wnested-externs -Wshadow -Wundef -Wmissing-declarations -Winline ${CMAKE_C_FLAGS}") 87*600f14f4SXin Li set(CMAKE_C_FLAGS_RELEASE "-DNDEBUG ${CMAKE_C_FLAGS_RELEASE}") 88*600f14f4SXin Liendif() 89*600f14f4SXin Liif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang") 90*600f14f4SXin Li set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wcast-align -Wshadow -Wwrite-strings -Wctor-dtor-privacy -Wnon-virtual-dtor -Wreorder -Wsign-promo -Wundef ${CMAKE_CXX_FLAGS}") 91*600f14f4SXin Li set(CMAKE_CXX_FLAGS_RELEASE "-DNDEBUG ${CMAKE_CXX_FLAGS_RELEASE}") 92*600f14f4SXin Liendif() 93*600f14f4SXin Liif(MSVC) 94*600f14f4SXin Li set(CMAKE_C_FLAGS_RELEASE "/O2 /Ob2 /Oi /Ot /Oy /DNDEBUG ${CMAKE_C_FLAGS_RELEASE}") 95*600f14f4SXin Liendif() 96*600f14f4SXin Li 97*600f14f4SXin Liinclude(CMakePackageConfigHelpers) 98*600f14f4SXin Liinclude(CheckCCompilerFlag) 99*600f14f4SXin Liinclude(CheckCXXCompilerFlag) 100*600f14f4SXin Liinclude(CheckSymbolExists) 101*600f14f4SXin Liinclude(CheckFunctionExists) 102*600f14f4SXin Liinclude(CheckIncludeFile) 103*600f14f4SXin Liinclude(CheckCSourceCompiles) 104*600f14f4SXin Liinclude(CheckCXXSourceCompiles) 105*600f14f4SXin Liinclude(CheckLibraryExists) 106*600f14f4SXin Liinclude(GNUInstallDirs) 107*600f14f4SXin Liinclude(UseSystemExtensions) 108*600f14f4SXin Liinclude(TestBigEndian) 109*600f14f4SXin Lienable_testing() 110*600f14f4SXin Li 111*600f14f4SXin Licheck_include_file("byteswap.h" HAVE_BYTESWAP_H) 112*600f14f4SXin Licheck_include_file("inttypes.h" HAVE_INTTYPES_H) 113*600f14f4SXin Licheck_include_file("stdint.h" HAVE_STDINT_H) 114*600f14f4SXin Licheck_include_file("stdbool.h" HAVE_STDBOOL_H) 115*600f14f4SXin Licheck_include_file("arm_neon.h" FLAC__HAS_NEONINTRIN) 116*600f14f4SXin Li 117*600f14f4SXin Liif(NOT HAVE_STDINT_H OR NOT HAVE_STDBOOL_H) 118*600f14f4SXin Li message(SEND_ERROR "Header stdint.h and/or stdbool.h not found") 119*600f14f4SXin Liendif() 120*600f14f4SXin Li 121*600f14f4SXin Liif(MSVC) 122*600f14f4SXin Li check_include_file("intrin.h" FLAC__HAS_X86INTRIN) 123*600f14f4SXin Lielse() 124*600f14f4SXin Li check_include_file("x86intrin.h" FLAC__HAS_X86INTRIN) 125*600f14f4SXin Liendif() 126*600f14f4SXin Li 127*600f14f4SXin Licheck_function_exists(fseeko HAVE_FSEEKO) 128*600f14f4SXin Li 129*600f14f4SXin Licheck_c_source_compiles("int main() { return __builtin_bswap16 (0) ; }" HAVE_BSWAP16) 130*600f14f4SXin Licheck_c_source_compiles("int main() { return __builtin_bswap32 (0) ; }" HAVE_BSWAP32) 131*600f14f4SXin Licheck_c_source_compiles(" 132*600f14f4SXin Li #include <langinfo.h> 133*600f14f4SXin Li int main() 134*600f14f4SXin Li { 135*600f14f4SXin Li char* cs = nl_langinfo(CODESET); 136*600f14f4SXin Li return !cs; 137*600f14f4SXin Li }" 138*600f14f4SXin Li HAVE_LANGINFO_CODESET) 139*600f14f4SXin Li 140*600f14f4SXin Litest_big_endian(CPU_IS_BIG_ENDIAN) 141*600f14f4SXin Li 142*600f14f4SXin Licheck_c_compiler_flag(-Werror HAVE_WERROR_FLAG) 143*600f14f4SXin Licheck_c_compiler_flag(-Wdeclaration-after-statement HAVE_DECL_AFTER_STMT_FLAG) 144*600f14f4SXin Licheck_c_compiler_flag(-mstackrealign HAVE_STACKREALIGN_FLAG) 145*600f14f4SXin Licheck_cxx_compiler_flag(-Weffc++ HAVE_WEFFCXX_FLAG) 146*600f14f4SXin Li 147*600f14f4SXin Liif(MINGW AND (WITH_FORTIFY_SOURCE OR WITH_STACK_PROTECTOR)) 148*600f14f4SXin Li check_library_exists("ssp.a" __stack_chk_fail "" HAVE_LIBSSP) 149*600f14f4SXin Li if(NOT HAVE_LIBSSP) 150*600f14f4SXin Li message(WARNING "Could not find libssp in MinGW, stack protection and/or FORTIFY_SOURCE are unavailable") 151*600f14f4SXin Li else() 152*600f14f4SXin Li link_libraries("ssp.a") 153*600f14f4SXin Li endif() 154*600f14f4SXin Lielseif(NOT MSVC) 155*600f14f4SXin Li set(HAVE_LIBSSP 1) 156*600f14f4SXin Liendif() 157*600f14f4SXin Li 158*600f14f4SXin Liif(WITH_STACK_PROTECTOR) 159*600f14f4SXin Li if(NOT MSVC) 160*600f14f4SXin Li check_c_compiler_flag("-fstack-protector-strong" HAVE_STACK_PROTECTOR_FLAG) 161*600f14f4SXin Li endif() 162*600f14f4SXin Liendif() 163*600f14f4SXin Li 164*600f14f4SXin Liif(HAVE_WERROR_FLAG) 165*600f14f4SXin Li option(ENABLE_WERROR "Enable -Werror in all Makefiles" OFF) 166*600f14f4SXin Liendif() 167*600f14f4SXin Li 168*600f14f4SXin Liadd_compile_options( 169*600f14f4SXin Li $<$<BOOL:${MSVC}>:/wd4267> 170*600f14f4SXin Li $<$<BOOL:${MSVC}>:/wd4996> 171*600f14f4SXin Li $<$<BOOL:${ENABLE_WERROR}>:-Werror> 172*600f14f4SXin Li $<$<AND:$<COMPILE_LANGUAGE:CXX>,$<BOOL:${HAVE_WEFFCXX_FLAG}>>:-Weffc++> 173*600f14f4SXin Li $<$<AND:$<COMPILE_LANGUAGE:C>,$<BOOL:${HAVE_DECL_AFTER_STMT_FLAG}>>:-Wdeclaration-after-statement>) 174*600f14f4SXin Li 175*600f14f4SXin Liif(WITH_FORTIFY_SOURCE AND HAVE_LIBSSP) 176*600f14f4SXin Li add_definitions(-D_FORTIFY_SOURCE=2) 177*600f14f4SXin Liendif() 178*600f14f4SXin Li 179*600f14f4SXin Liif(HAVE_STACK_PROTECTOR_FLAG AND HAVE_LIBSSP) 180*600f14f4SXin Li add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-fstack-protector-strong>) 181*600f14f4SXin Liendif() 182*600f14f4SXin Li 183*600f14f4SXin Liif(CMAKE_SYSTEM_PROCESSOR STREQUAL "i686" AND HAVE_STACKREALIGN_FLAG) 184*600f14f4SXin Li add_compile_options($<$<OR:$<COMPILE_LANGUAGE:C>,$<COMPILE_LANGUAGE:CXX>>:-mstackrealign>) 185*600f14f4SXin Liendif() 186*600f14f4SXin Li 187*600f14f4SXin Liinclude_directories("include") 188*600f14f4SXin Li 189*600f14f4SXin Liinclude_directories("${CMAKE_CURRENT_BINARY_DIR}") 190*600f14f4SXin Liadd_definitions(-DHAVE_CONFIG_H) 191*600f14f4SXin Li 192*600f14f4SXin Liif(MSVC) 193*600f14f4SXin Li add_definitions( 194*600f14f4SXin Li -D_CRT_SECURE_NO_WARNINGS 195*600f14f4SXin Li -D_USE_MATH_DEFINES) 196*600f14f4SXin Liendif() 197*600f14f4SXin Liif(CMAKE_BUILD_TYPE STREQUAL Debug OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo) 198*600f14f4SXin Li add_definitions(-DFLAC__OVERFLOW_DETECT) 199*600f14f4SXin Liendif() 200*600f14f4SXin Li 201*600f14f4SXin Liadd_subdirectory("src") 202*600f14f4SXin Liadd_subdirectory("microbench") 203*600f14f4SXin Liif(BUILD_DOCS) 204*600f14f4SXin Li add_subdirectory("doc") 205*600f14f4SXin Liendif() 206*600f14f4SXin Liif(BUILD_EXAMPLES) 207*600f14f4SXin Li add_subdirectory("examples") 208*600f14f4SXin Liendif() 209*600f14f4SXin Liif(BUILD_TESTING) 210*600f14f4SXin Li add_subdirectory("test") 211*600f14f4SXin Liendif() 212*600f14f4SXin Li 213*600f14f4SXin Li# The following folder layout is mostly for MSVC 214*600f14f4SXin Liset_property(GLOBAL PROPERTY USE_FOLDERS ON) 215*600f14f4SXin Li 216*600f14f4SXin Liset_target_properties(FLAC grabbag getopt replaygain_analysis replaygain_synthesis utf8 PROPERTIES FOLDER Libraries) 217*600f14f4SXin Liif(BUILD_CXXLIBS) 218*600f14f4SXin Li set_target_properties(FLAC++ PROPERTIES FOLDER Libraries) 219*600f14f4SXin Liendif() 220*600f14f4SXin Liif(BUILD_PROGRAMS) 221*600f14f4SXin Li set_target_properties(flacapp metaflac PROPERTIES FOLDER Programs) 222*600f14f4SXin Liendif() 223*600f14f4SXin Liif(BUILD_TESTING) 224*600f14f4SXin Li set_target_properties(test_libFLAC test_libs_common test_picture test_seeking test_streams test_cuesheet PROPERTIES FOLDER Tests) 225*600f14f4SXin Li if(BUILD_CXXLIBS) 226*600f14f4SXin Li set_target_properties(test_libFLAC++ PROPERTIES FOLDER Tests) 227*600f14f4SXin Li endif() 228*600f14f4SXin Liendif() 229*600f14f4SXin Liif(BUILD_EXAMPLES) 230*600f14f4SXin Li set_target_properties(decode_file encode_file PROPERTIES FOLDER Examples) 231*600f14f4SXin Li if(BUILD_CXXLIBS) 232*600f14f4SXin Li set_target_properties(decode_file_cxx encode_file_cxx PROPERTIES FOLDER Examples) 233*600f14f4SXin Li endif() 234*600f14f4SXin Liendif() 235*600f14f4SXin Liif(BUILD_UTILS) 236*600f14f4SXin Li set_target_properties(flacdiff flactimer PROPERTIES FOLDER Utils) 237*600f14f4SXin Liendif() 238*600f14f4SXin Li 239*600f14f4SXin Liconfigure_file(config.cmake.h.in config.h) 240*600f14f4SXin Li 241*600f14f4SXin Liif(INSTALL_CMAKE_CONFIG_MODULE) 242*600f14f4SXin Li install( 243*600f14f4SXin Li EXPORT targets 244*600f14f4SXin Li DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" 245*600f14f4SXin Li NAMESPACE FLAC::) 246*600f14f4SXin Li export(EXPORT targets NAMESPACE FLAC:: FILE FLACTargets.cmake) 247*600f14f4SXin Li 248*600f14f4SXin Li configure_package_config_file( 249*600f14f4SXin Li ${PROJECT_SOURCE_DIR}/flac-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/flac-config.cmake 250*600f14f4SXin Li INSTALL_DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") 251*600f14f4SXin Li write_basic_package_version_file( 252*600f14f4SXin Li ${CMAKE_CURRENT_BINARY_DIR}/flac-config-version.cmake COMPATIBILITY AnyNewerVersion) 253*600f14f4SXin Li 254*600f14f4SXin Li install( 255*600f14f4SXin Li FILES ${CMAKE_CURRENT_BINARY_DIR}/flac-config.cmake ${CMAKE_CURRENT_BINARY_DIR}/flac-config-version.cmake 256*600f14f4SXin Li DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}" 257*600f14f4SXin Li ) 258*600f14f4SXin Li 259*600f14f4SXin Li install( 260*600f14f4SXin Li FILES 261*600f14f4SXin Li "${CMAKE_CURRENT_BINARY_DIR}/flac-config.cmake" 262*600f14f4SXin Li "${CMAKE_CURRENT_BINARY_DIR}/flac-config-version.cmake" 263*600f14f4SXin Li DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}") 264*600f14f4SXin Liendif() 265*600f14f4SXin Li 266*600f14f4SXin Lifile(GLOB FLAC_HEADERS "include/FLAC/*.h") 267*600f14f4SXin Lifile(GLOB FLAC++_HEADERS "include/FLAC++/*.h") 268*600f14f4SXin Liinstall(FILES ${FLAC_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/FLAC") 269*600f14f4SXin Liinstall(FILES ${FLAC++_HEADERS} DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/FLAC++") 270*600f14f4SXin Liif(INSTALL_MANPAGES) 271*600f14f4SXin Li find_program (HAVE_PANDOC pandoc) 272*600f14f4SXin Li if(HAVE_PANDOC) 273*600f14f4SXin Li file(MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/man") 274*600f14f4SXin Li add_custom_command( 275*600f14f4SXin Li OUTPUT man/flac.1 276*600f14f4SXin Li COMMAND pandoc --standalone --to man "${CMAKE_SOURCE_DIR}/man/flac.md" > man/flac.1 277*600f14f4SXin Li ) 278*600f14f4SXin Li add_custom_command( 279*600f14f4SXin Li OUTPUT man/metaflac.1 280*600f14f4SXin Li COMMAND pandoc --standalone --to man "${CMAKE_SOURCE_DIR}/man/metaflac.md" > man/metaflac.1 281*600f14f4SXin Li ) 282*600f14f4SXin Li add_custom_target(man ALL DEPENDS man/flac.1 man/metaflac.1) 283*600f14f4SXin Li install(FILES "${CMAKE_BINARY_DIR}/man/flac.1" "${CMAKE_BINARY_DIR}/man/metaflac.1" DESTINATION "${CMAKE_INSTALL_MANDIR}/man1") 284*600f14f4SXin Li else() 285*600f14f4SXin Li if(EXISTS "${CMAKE_SOURCE_DIR}/man/flac.1" AND EXISTS "${CMAKE_SOURCE_DIR}/man/metaflac.1") 286*600f14f4SXin Li install(FILES "man/flac.1" "man/metaflac.1" DESTINATION "${CMAKE_INSTALL_MANDIR}/man1") 287*600f14f4SXin Li else() 288*600f14f4SXin Li message(SEND_ERROR "Pandoc nor prebuild manpages are found. Cannot install manpages. Set INSTALL_MANPAGES to OFF to build without man pages") 289*600f14f4SXin Li endif() 290*600f14f4SXin Li endif() 291*600f14f4SXin Liendif() 292