| 1 | # vim: syntax=cmake |
| 2 | if(NOT CMAKE_BUILD_TYPE) |
| 3 | # default to Release build for GCC builds |
| 4 | set(CMAKE_BUILD_TYPE Release CACHE STRING |
| 5 | "Choose the type of build, options are: None(CMAKE_CXX_FLAGS or CMAKE_C_FLAGS used) Debug Release RelWithDebInfo MinSizeRel." |
| 6 | FORCE) |
| 7 | endif() |
| 8 | message(STATUS "cmake version ${CMAKE_VERSION}") |
| 9 | if(POLICY CMP0025) |
| 10 | cmake_policy(SET CMP0025 OLD) # report Apple's Clang as just Clang |
| 11 | endif() |
| 12 | if(POLICY CMP0042) |
| 13 | cmake_policy(SET CMP0042 NEW) # MACOSX_RPATH |
| 14 | endif() |
| 15 | |
| 16 | project (x265) |
| 17 | cmake_minimum_required (VERSION 2.8.8) # OBJECT libraries require 2.8.8 |
| 18 | include(CheckIncludeFiles) |
| 19 | include(CheckFunctionExists) |
| 20 | include(CheckSymbolExists) |
| 21 | include(CheckCXXCompilerFlag) |
| 22 | |
| 23 | # X265_BUILD must be incremented each time the public API is changed |
| 24 | set(X265_BUILD 40) |
| 25 | configure_file("${PROJECT_SOURCE_DIR}/x265.def.in" |
| 26 | "${PROJECT_BINARY_DIR}/x265.def") |
| 27 | configure_file("${PROJECT_SOURCE_DIR}/x265_config.h.in" |
| 28 | "${PROJECT_BINARY_DIR}/x265_config.h") |
| 29 | |
| 30 | SET(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" "${CMAKE_MODULE_PATH}") |
| 31 | |
| 32 | option(CHECKED_BUILD "Enable run-time sanity checks (debugging)" OFF) |
| 33 | if(CHECKED_BUILD) |
| 34 | add_definitions(-DCHECKED_BUILD=1) |
| 35 | endif() |
| 36 | |
| 37 | # System architecture detection |
| 38 | string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" SYSPROC) |
| 39 | set(X86_ALIASES x86 i386 i686 x86_64 amd64) |
| 40 | list(FIND X86_ALIASES "${SYSPROC}" X86MATCH) |
| 41 | if("${SYSPROC}" STREQUAL "" OR X86MATCH GREATER "-1") |
| 42 | message(STATUS "Detected x86 target processor") |
| 43 | set(X86 1) |
| 44 | add_definitions(-DX265_ARCH_X86=1) |
| 45 | if("${CMAKE_SIZEOF_VOID_P}" MATCHES 8) |
| 46 | set(X64 1) |
| 47 | add_definitions(-DX86_64=1) |
| 48 | endif() |
| 49 | elseif(${SYSPROC} STREQUAL "armv6l") |
| 50 | message(STATUS "Detected ARM target processor") |
| 51 | set(ARM 1) |
| 52 | add_definitions(-DX265_ARCH_ARM=1 -DHAVE_ARMV6=1) |
| 53 | else() |
| 54 | message(STATUS "CMAKE_SYSTEM_PROCESSOR value `${CMAKE_SYSTEM_PROCESSOR}` is unknown") |
| 55 | message(STATUS "Please add this value near ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE}") |
| 56 | endif() |
| 57 | |
| 58 | if(UNIX) |
| 59 | SET(PLATFORM_LIBS pthread) |
| 60 | find_library(LIBRT rt) |
| 61 | if(LIBRT) |
| 62 | set(PLATFORM_LIBS ${PLATFORM_LIBS} rt) |
| 63 | endif() |
| 64 | endif(UNIX) |
| 65 | |
| 66 | if(X64 AND NOT WIN32) |
| 67 | option(ENABLE_PIC "Enable Position Independent Code" ON) |
| 68 | else() |
| 69 | option(ENABLE_PIC "Enable Position Independent Code" OFF) |
| 70 | endif(X64 AND NOT WIN32) |
| 71 | |
| 72 | # Compiler detection |
| 73 | if(CMAKE_GENERATOR STREQUAL "Xcode") |
| 74 | set(XCODE 1) |
| 75 | endif() |
| 76 | if (APPLE) |
| 77 | add_definitions(-DMACOS) |
| 78 | endif() |
| 79 | |
| 80 | if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") |
| 81 | set(CLANG 1) |
| 82 | endif() |
| 83 | if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") |
| 84 | set(INTEL_CXX 1) |
| 85 | endif() |
| 86 | if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") |
| 87 | set(GCC 1) |
| 88 | endif() |
| 89 | |
| 90 | if(INTEL_CXX AND WIN32) |
| 91 | # treat icl roughly like MSVC |
| 92 | set(MSVC 1) |
| 93 | endif() |
| 94 | if(MSVC) |
| 95 | option(STATIC_LINK_CRT "Statically link C runtime for release builds" OFF) |
| 96 | if (STATIC_LINK_CRT) |
| 97 | set(CompilerFlags CMAKE_CXX_FLAGS_RELEASE CMAKE_C_FLAGS_RELEASE) |
| 98 | foreach(CompilerFlag ${CompilerFlags}) |
| 99 | string(REPLACE "/MD" "/MT" ${CompilerFlag} "${${CompilerFlag}}") |
| 100 | endforeach() |
| 101 | endif (STATIC_LINK_CRT) |
| 102 | add_definitions(/W4) # Full warnings |
| 103 | add_definitions(/Ob2) # always inline |
| 104 | add_definitions(/MP) # multithreaded build |
| 105 | |
| 106 | # disable Microsofts suggestions for proprietary secure APIs |
| 107 | add_definitions(/D_CRT_SECURE_NO_WARNINGS) |
| 108 | |
| 109 | check_include_files(stdint.h HAVE_STDINT_H) |
| 110 | if(NOT HAVE_STDINT_H) |
| 111 | include_directories(compat/msvc) |
| 112 | endif() |
| 113 | endif(MSVC) |
| 114 | |
| 115 | check_include_files(inttypes.h HAVE_INT_TYPES_H) |
| 116 | if(HAVE_INT_TYPES_H) |
| 117 | add_definitions(-DHAVE_INT_TYPES_H=1) |
| 118 | endif() |
| 119 | |
| 120 | if(INTEL_CXX AND UNIX) |
| 121 | set(GCC 1) # treat icpc roughly like gcc |
| 122 | elseif(CLANG) |
| 123 | set(GCC 1) # treat clang roughly like gcc |
| 124 | elseif(CMAKE_COMPILER_IS_GNUCXX) |
| 125 | set(GCC 1) |
| 126 | endif() |
| 127 | if(GCC) |
| 128 | add_definitions(-Wall -Wextra -Wshadow) |
| 129 | add_definitions(-D__STDC_LIMIT_MACROS=1) |
| 130 | if(ENABLE_PIC) |
| 131 | add_definitions(-fPIC) |
| 132 | endif(ENABLE_PIC) |
| 133 | if(X86 AND NOT X64) |
| 134 | add_definitions(-march=i686) |
| 135 | endif() |
| 136 | if(ARM) |
| 137 | add_definitions(-march=armv6 -mfloat-abi=hard -mfpu=vfp) |
| 138 | endif() |
| 139 | check_cxx_compiler_flag(-Wno-narrowing CC_HAS_NO_NARROWING) |
| 140 | check_cxx_compiler_flag(-Wno-array-bounds CC_HAS_NO_ARRAY_BOUNDS) |
| 141 | if (CC_HAS_NO_ARRAY_BOUNDS) |
| 142 | add_definitions(-Wno-array-bounds) # these are unhelpful |
| 143 | endif() |
| 144 | check_cxx_compiler_flag(-ffast-math CC_HAS_FAST_MATH) |
| 145 | if (CC_HAS_FAST_MATH) |
| 146 | add_definitions(-ffast-math) |
| 147 | endif() |
| 148 | check_cxx_compiler_flag(-mstackrealign CC_HAS_STACK_REALIGN) |
| 149 | if (CC_HAS_STACK_REALIGN) |
| 150 | add_definitions(-mstackrealign) |
| 151 | endif() |
| 152 | # Disable exceptions. Reduce executable size, increase compability. |
| 153 | check_cxx_compiler_flag(-fno-exceptions CC_HAS_FNO_EXCEPTIONS_FLAG) |
| 154 | if(CC_HAS_FNO_EXCEPTIONS_FLAG) |
| 155 | add_definitions(-fno-exceptions) |
| 156 | endif() |
| 157 | execute_process(COMMAND ${CMAKE_CXX_COMPILER} -dumpversion OUTPUT_VARIABLE CC_VERSION) |
| 158 | endif(GCC) |
| 159 | |
| 160 | find_package(Yasm) |
| 161 | if(YASM_FOUND AND X86) |
| 162 | if (YASM_VERSION_STRING VERSION_LESS "1.2.0") |
| 163 | message(STATUS "Yasm version ${YASM_VERSION_STRING} is too old. 1.2.0 or later required") |
| 164 | option(ENABLE_ASSEMBLY "Enable use of assembly coded primitives" OFF) |
| 165 | else() |
| 166 | message(STATUS "Found Yasm ${YASM_VERSION_STRING} to build assembly primitives") |
| 167 | option(ENABLE_ASSEMBLY "Enable use of assembly coded primitives" ON) |
| 168 | endif() |
| 169 | endif() |
| 170 | |
| 171 | # Build options |
| 172 | set(LIB_INSTALL_DIR lib CACHE STRING "Install location of libraries") |
| 173 | set(BIN_INSTALL_DIR bin CACHE STRING "Install location of executables") |
| 174 | |
| 175 | if(X64) |
| 176 | # NOTE: We only officially support 16bit-per-pixel compiles of x265 |
| 177 | # on 64bit architectures. 16bpp plus large resolution plus slow |
| 178 | # preset plus 32bit address space usually means malloc failure. You |
| 179 | # can disable this if(X64) check if you desparately need a 32bit |
| 180 | # build with 10bit/12bit support, but this violates the "shrink wrap |
| 181 | # license" so to speak. If it breaks you get to keep both halves. |
| 182 | option(HIGH_BIT_DEPTH "Store pixels as 16bit values" OFF) |
| 183 | endif(X64) |
| 184 | if(HIGH_BIT_DEPTH) |
| 185 | add_definitions(-DHIGH_BIT_DEPTH=1) |
| 186 | else(HIGH_BIT_DEPTH) |
| 187 | add_definitions(-DHIGH_BIT_DEPTH=0) |
| 188 | endif(HIGH_BIT_DEPTH) |
| 189 | |
| 190 | option(WARNINGS_AS_ERRORS "Stop compiles on first warning" OFF) |
| 191 | if(WARNINGS_AS_ERRORS) |
| 192 | if(GCC) |
| 193 | add_definitions(-Werror) |
| 194 | elseif(MSVC) |
| 195 | add_definitions(/WX) |
| 196 | endif() |
| 197 | endif(WARNINGS_AS_ERRORS) |
| 198 | |
| 199 | |
| 200 | option(ENABLE_PPA "Enable PPA profiling instrumentation" OFF) |
| 201 | if(ENABLE_PPA) |
| 202 | add_definitions(-DENABLE_PPA) |
| 203 | add_subdirectory(PPA) |
| 204 | SET(PLATFORM_LIBS ${PLATFORM_LIBS} PPA) |
| 205 | if(UNIX) |
| 206 | SET(PLATFORM_LIBS ${PLATFORM_LIBS} dl) |
| 207 | endif(UNIX) |
| 208 | endif(ENABLE_PPA) |
| 209 | |
| 210 | if (WIN32) |
| 211 | # Visual leak detector |
| 212 | find_package(VLD QUIET) |
| 213 | if(VLD_FOUND) |
| 214 | add_definitions(-DHAVE_VLD) |
| 215 | include_directories(${VLD_INCLUDE_DIRS}) |
| 216 | set(PLATFORM_LIBS ${PLATFORM_LIBS} ${VLD_LIBRARIES}) |
| 217 | link_directories(${VLD_LIBRARY_DIRS}) |
| 218 | endif() |
| 219 | option(WINXP_SUPPORT "Make binaries compatible with Windows XP" OFF) |
| 220 | if(WINXP_SUPPORT) |
| 221 | # force use of workarounds for CONDITION_VARIABLE and atomic |
| 222 | # intrinsics introduced after XP |
| 223 | add_definitions(-D_WIN32_WINNT=_WIN32_WINNT_WINXP) |
| 224 | endif() |
| 225 | endif() |
| 226 | |
| 227 | include(version) # determine X265_VERSION and X265_LATEST_TAG |
| 228 | include_directories(. common encoder "${PROJECT_BINARY_DIR}") |
| 229 | add_subdirectory(encoder) |
| 230 | add_subdirectory(common) |
| 231 | |
| 232 | if((MSVC_IDE OR XCODE) AND ENABLE_ASSEMBLY) |
| 233 | # this is required because of this cmake bug |
| 234 | # http://www.cmake.org/Bug/print_bug_page.php?bug_id=8170 |
| 235 | if(WIN32) |
| 236 | set(SUFFIX obj) |
| 237 | else() |
| 238 | set(SUFFIX o) |
| 239 | endif() |
| 240 | foreach(ASM ${MSVC_ASMS}) |
| 241 | set(YASM_SRC ${CMAKE_CURRENT_SOURCE_DIR}/common/x86/${ASM}) |
| 242 | list(APPEND YASM_SRCS ${YASM_SRC}) |
| 243 | list(APPEND YASM_OBJS ${ASM}.${SUFFIX}) |
| 244 | add_custom_command( |
| 245 | OUTPUT ${ASM}.${SUFFIX} |
| 246 | COMMAND ${YASM_EXECUTABLE} ARGS ${YASM_FLAGS} ${YASM_SRC} -o ${ASM}.${SUFFIX} |
| 247 | DEPENDS ${YASM_SRC}) |
| 248 | endforeach() |
| 249 | endif() |
| 250 | |
| 251 | source_group(ASM FILES ${YASM_SRCS}) |
| 252 | add_library(x265-static STATIC $<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common> ${YASM_OBJS} ${YASM_SRCS}) |
| 253 | if(NOT MSVC) |
| 254 | set_target_properties(x265-static PROPERTIES OUTPUT_NAME x265) |
| 255 | endif() |
| 256 | install(TARGETS x265-static |
| 257 | LIBRARY DESTINATION ${LIB_INSTALL_DIR} |
| 258 | ARCHIVE DESTINATION ${LIB_INSTALL_DIR}) |
| 259 | install(FILES x265.h "${PROJECT_BINARY_DIR}/x265_config.h" DESTINATION include) |
| 260 | |
| 261 | if(CMAKE_RC_COMPILER) |
| 262 | # The resource compiler does not need CFLAGS or macro defines. It |
| 263 | # often breaks them |
| 264 | string(REPLACE "<FLAGS>" "" CMAKE_RC_COMPILE_OBJECT "${CMAKE_RC_COMPILE_OBJECT}") |
| 265 | string(REPLACE "<DEFINES>" "" CMAKE_RC_COMPILE_OBJECT "${CMAKE_RC_COMPILE_OBJECT}") |
| 266 | |
| 267 | # convert X265_LATEST_TAG (ex: 0.7) and X265_TAG_DISTANCE (ex: 103) to |
| 268 | # @X265_VERSION_MAJOR@,@X265_VERSION_MINOR@,@X265_BRANCH_ID@,@X265_TAG_DISTANCE@ |
| 269 | string(REPLACE "." ";" VERSION_LIST "${X265_LATEST_TAG}") |
| 270 | list(GET VERSION_LIST 0 X265_VERSION_MAJOR) |
| 271 | list(GET VERSION_LIST 1 X265_VERSION_MINOR) |
| 272 | set(X265_BRANCH_ID 0) # TODO: 0 - stable, 1 - default or other |
| 273 | set(X265_RC_FILE "${CMAKE_CURRENT_BINARY_DIR}/x265.rc") |
| 274 | configure_file("${CMAKE_CURRENT_SOURCE_DIR}/x265.rc.in" "${X265_RC_FILE}" @ONLY) |
| 275 | endif() |
| 276 | |
| 277 | if(NOT (MSVC_IDE OR XCODE)) |
| 278 | add_custom_target(clean-generated COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/clean-generated.cmake) |
| 279 | endif() |
| 280 | |
| 281 | option(ENABLE_SHARED "Build shared library" ON) |
| 282 | if(ENABLE_SHARED) |
| 283 | add_library(x265-shared SHARED "${PROJECT_BINARY_DIR}/x265.def" ${YASM_OBJS} |
| 284 | ${X265_RC_FILE} $<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common>) |
| 285 | target_link_libraries(x265-shared ${PLATFORM_LIBS}) |
| 286 | if(MSVC) |
| 287 | set_target_properties(x265-shared PROPERTIES OUTPUT_NAME libx265) |
| 288 | else() |
| 289 | set_target_properties(x265-shared PROPERTIES OUTPUT_NAME x265) |
| 290 | endif() |
| 291 | if(UNIX) |
| 292 | set_target_properties(x265-shared PROPERTIES VERSION ${X265_BUILD}) |
| 293 | if(APPLE) |
| 294 | set_target_properties(x265-shared PROPERTIES MACOSX_RPATH 1) |
| 295 | else() |
| 296 | set_target_properties(x265-shared PROPERTIES LINK_FLAGS "-Wl,-Bsymbolic,-znoexecstack") |
| 297 | endif() |
| 298 | endif() |
| 299 | set_target_properties(x265-shared PROPERTIES SOVERSION ${X265_BUILD}) |
| 300 | if(X265_LATEST_TAG) |
| 301 | if(WINDOWS) |
| 302 | set_target_properties(x265-shared PROPERTIES VERSION ${X265_LATEST_TAG}) |
| 303 | endif() |
| 304 | # shared library is not installed if a tag is not found |
| 305 | install(TARGETS x265-shared |
| 306 | LIBRARY DESTINATION ${LIB_INSTALL_DIR} |
| 307 | ARCHIVE DESTINATION ${LIB_INSTALL_DIR} |
| 308 | RUNTIME DESTINATION ${BIN_INSTALL_DIR}) |
| 309 | endif() |
| 310 | endif() |
| 311 | |
| 312 | if(X265_LATEST_TAG) |
| 313 | # convert lists of link libraries into -lstdc++ -lm etc.. |
| 314 | foreach(LIB ${CMAKE_CXX_IMPLICIT_LINK_LIBRARIES} ${PLATFORM_LIBS}) |
| 315 | if(IS_ABSOLUTE ${LIB} AND EXISTS ${LIB}) |
| 316 | list(APPEND PLIBLIST "${LIB}") |
| 317 | else() |
| 318 | list(APPEND PLIBLIST "-l${LIB}") |
| 319 | endif() |
| 320 | endforeach() |
| 321 | if(PLIBLIST) |
| 322 | # blacklist of libraries that should not be in Libs.private |
| 323 | list(REMOVE_ITEM PLIBLIST "-lc" "-lpthread") |
| 324 | string(REPLACE ";" " " PRIVATE_LIBS "${PLIBLIST}") |
| 325 | else() |
| 326 | set(PRIVATE_LIBS "") |
| 327 | endif(PLIBLIST) |
| 328 | |
| 329 | # Produce a pkg-config file |
| 330 | configure_file("x265.pc.in" "x265.pc" @ONLY) |
| 331 | install(FILES "${CMAKE_CURRENT_BINARY_DIR}/x265.pc" |
| 332 | DESTINATION "${CMAKE_INSTALL_PREFIX}/${LIB_INSTALL_DIR}/pkgconfig") |
| 333 | endif() |
| 334 | |
| 335 | if(NOT WIN32) |
| 336 | configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in" |
| 337 | "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake" |
| 338 | IMMEDIATE @ONLY) |
| 339 | add_custom_target(uninstall |
| 340 | "${CMAKE_COMMAND}" -P "${CMAKE_CURRENT_BINARY_DIR}/cmake/cmake_uninstall.cmake") |
| 341 | endif() |
| 342 | |
| 343 | # Main CLI application |
| 344 | option(ENABLE_CLI "Build standalone CLI application" ON) |
| 345 | if(ENABLE_CLI) |
| 346 | file(GLOB InputFiles input/*.cpp input/*.h) |
| 347 | file(GLOB OutputFiles output/*.cpp output/*.h) |
| 348 | file(GLOB FilterFiles filters/*.cpp filters/*.h) |
| 349 | source_group(input FILES ${InputFiles}) |
| 350 | source_group(output FILES ${OutputFiles}) |
| 351 | source_group(filters FILES ${FilterFiles}) |
| 352 | |
| 353 | check_include_files(getopt.h HAVE_GETOPT_H) |
| 354 | if(NOT HAVE_GETOPT_H) |
| 355 | if(MSVC) |
| 356 | set_source_files_properties(compat/getopt/getopt.c PROPERTIES COMPILE_FLAGS "/wd4100 /wd4131 -DHAVE_STRING_H=1") |
| 357 | endif(MSVC) |
| 358 | include_directories(compat/getopt) |
| 359 | set(GETOPT compat/getopt/getopt.c compat/getopt/getopt.h) |
| 360 | endif(NOT HAVE_GETOPT_H) |
| 361 | |
| 362 | if(XCODE) |
| 363 | # Xcode seems unable to link the CLI with libs, so link as one targget |
| 364 | add_executable(cli ../COPYING ${InputFiles} ${OutputFiles} ${FilterFiles} ${GETOPT} x265.cpp x265.h |
| 365 | $<TARGET_OBJECTS:encoder> $<TARGET_OBJECTS:common> ${YASM_OBJS} ${YASM_SRCS}) |
| 366 | else() |
| 367 | add_executable(cli ../COPYING ${InputFiles} ${OutputFiles} ${FilterFiles} ${GETOPT} ${X265_RC_FILE} x265.cpp x265.h) |
| 368 | if(WIN32 OR NOT ENABLE_SHARED OR INTEL_CXX) |
| 369 | # The CLI cannot link to the shared library on Windows, it |
| 370 | # requires internal APIs not exported from the DLL |
| 371 | target_link_libraries(cli x265-static ${PLATFORM_LIBS}) |
| 372 | else() |
| 373 | target_link_libraries(cli x265-shared ${PLATFORM_LIBS}) |
| 374 | endif() |
| 375 | endif() |
| 376 | set_target_properties(cli PROPERTIES OUTPUT_NAME x265) |
| 377 | |
| 378 | install(TARGETS cli DESTINATION ${BIN_INSTALL_DIR}) |
| 379 | endif(ENABLE_CLI) |
| 380 | |
| 381 | if(ENABLE_ASSEMBLY AND NOT XCODE) |
| 382 | option(ENABLE_TESTS "Enable Unit Tests" OFF) |
| 383 | if(ENABLE_TESTS) |
| 384 | add_subdirectory(test) |
| 385 | endif() |
| 386 | endif() |