From 3661b980695a65b6f84d5766e00c5af781754866 Mon Sep 17 00:00:00 2001 From: Vincent Rabaud Date: Mon, 21 Dec 2015 15:35:13 +0100 Subject: [PATCH] Add a CMakeLists.txt The goal is not to replace our autotools configuration, but to provide a minimal CMake file that can build the lib, cwebp and dwebp. Change-Id: I3be343bd698d118c5f00172449d232d87e868f23 --- .gitignore | 3 + CMakeLists.txt | 323 ++++++++++++++++++++++++++++++++++++++++++++++ README | 24 ++++ cmake/config.h.in | 146 +++++++++++++++++++++ 4 files changed, 496 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 cmake/config.h.in diff --git a/.gitignore b/.gitignore index f25586d5..d5a92008 100644 --- a/.gitignore +++ b/.gitignore @@ -31,3 +31,6 @@ src/webp/stamp-h1 *.pdb /iosbuild /WebP.framework +CMakeCache.txt +CMakeFiles/ +cmake_install.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 00000000..643a5bb5 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,323 @@ +cmake_minimum_required(VERSION 2.8.7) + +project(libwebp C) + +# Options for coder / decoder executables. +option(WEBP_BUILD_CWEBP "Build the cwebp command line tool." OFF) +option(WEBP_BUILD_DWEBP "Build the dwebp command line tool." OFF) +option(WEBP_EXPERIMENTAL_FEATURES "Build with experimental features." OFF) +option(WEBP_FORCE_ALIGNED "Force aligned memory operations." OFF) + +set(WEBP_DEP_LIBRARIES) +set(WEBP_DEP_INCLUDE_DIRS) + +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE + "Build type: Release, Debug or RelWithDebInfo" STRING FORCE + ) +endif() + +################################################################################ +# Generate the config.h to compile with specific intrinsics / libs. + +## Check for compiler options. +include(CheckCSourceCompiles) +check_c_source_compiles(" + int main(void) { + __builtin_bswap16(0); + return 0; + } + " + HAVE_BUILTIN_BSWAP16 +) +check_c_source_compiles(" + int main(void) { + __builtin_bswap32(0); + return 0; + } + " + HAVE_BUILTIN_BSWAP32 +) +check_c_source_compiles(" + int main(void) { + __builtin_bswap64(0); + return 0; + } + " + HAVE_BUILTIN_BSWAP64 +) + +## Check for libraries. +find_package(Threads) +if(Threads_FOUND) + if(CMAKE_USE_PTHREADS_INIT) + list(APPEND CMAKE_C_FLAGS "-pthread") + endif() + foreach(PTHREAD_TEST HAVE_PTHREAD_PRIO_INHERIT PTHREAD_CREATE_UNDETACHED) + check_c_source_compiles(" + #include + int main (void) { + int attr = ${PTHREAD_TEST}; + return attr; + } + " ${PTHREAD_TEST} + ) + endforeach() + list(APPEND WEBP_DEP_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) +endif() +set(WEBP_USE_THREAD ${Threads_FOUND}) + +# TODO: this seems unused, check with autotools. +set(LT_OBJDIR ".libs/") + +# Only useful for vwebp, so useless for now. +# find_package(OpenGL) +# set(WEBP_HAVE_GL ${OPENGL_FOUND}) +# set(WEBP_DEP_INCLUDE_DIRS ${WEBP_DEP_INCLUDE_DIRS} ${OPENGL_INCLUDE_DIRS}) +# set(WEBP_DEP_LIBRARIES ${WEBP_DEP_LIBRARIES} ${OPENGL_LIBRARIES}) + +# Find the standard C math library. +find_library(MATH_LIBRARY NAMES m) +if(MATH_LIBRARY) + list(APPEND WEBP_DEP_LIBRARIES ${MATH_LIBRARY}) +endif() + +# Find the standard image libraries. +set(WEBP_DEP_IMG_LIBRARIES) +set(WEBP_DEP_IMG_INCLUDE_DIRS) +foreach(I_LIB PNG JPEG TIFF GIF) + find_package(${I_LIB}) + set(WEBP_HAVE_${I_LIB} ${${I_LIB}_FOUND}) + if(${I_LIB}_FOUND) + list(APPEND WEBP_DEP_IMG_LIBRARIES ${${I_LIB}_LIBRARIES}) + list(APPEND WEBP_DEP_IMG_INCLUDE_DIRS ${${I_LIB}_INCLUDE_DIRS}) + endif() +endforeach() + +## Check for specific headers. +include(CheckIncludeFiles) +check_include_files("stdlib.h;stdarg.h;string.h;float.h" STDC_HEADERS) +check_include_files(dlfcn.h HAVE_DLFCN_H) +check_include_files(GLUT/glut.h HAVE_GLUT_GLUT_H) +check_include_files(GL/glut.h HAVE_GL_GLUT_H) +check_include_files(inttypes.h HAVE_INTTYPES_H) +check_include_files(memory.h HAVE_MEMORY_H) +check_include_files(OpenGL/glut.h HAVE_OPENGL_GLUT_H) +check_include_files(shlwapi.h HAVE_SHLWAPI_H) +check_include_files(stdint.h HAVE_STDINT_H) +check_include_files(stdlib.h HAVE_STDLIB_H) +check_include_files(strings.h HAVE_STRINGS_H) +check_include_files(string.h HAVE_STRING_H) +check_include_files(sys/stat.h HAVE_SYS_STAT_H) +check_include_files(sys/types.h HAVE_SYS_TYPES_H) +check_include_files(unistd.h HAVE_UNISTD_H) +check_include_files(wincodec.h HAVE_WINCODEC_H) +check_include_files(windows.h HAVE_WINDOWS_H) + +# Windows specifics +if(HAVE_WINCODEC_H) + list(APPEND WEBP_DEP_LIBRARIES shlwapi ole32 windowscodecs) +endif() + +## Check for SIMD extensions. +set(WEBP_SIMD_FLAGS "SSE2;SSE41;AVX2") +set(WEBP_SIMD_FILE_EXTENSIONS "_sse2.c;_sse41.c;_avx2.c") +if(MSVC) + # MSVC does not have a SSE4 flag but AVX2 support implies + # SSE4 support. + set(SIMD_ENABLE_FLAGS "/arch:SSE2;/arch:AVX2;/arch:AVX2") + set(SIMD_DISABLE_FLAGS) +else() + set(SIMD_ENABLE_FLAGS "-msse2;-msse4.1;-mavx2") + set(SIMD_DISABLE_FLAGS "-mno-sse2;-mno-sse4.1;-mno-avx2") +endif() + +set(WEBP_SIMD_FILES_TO_NOT_INCLUDE) +set(WEBP_SIMD_FILES_TO_INCLUDE) +set(WEBP_SIMD_FLAGS_TO_INCLUDE) + +list(LENGTH WEBP_SIMD_FLAGS WEBP_SIMD_FLAGS_LENGTH) +math(EXPR WEBP_SIMD_FLAGS_RANGE "${WEBP_SIMD_FLAGS_LENGTH} - 1") + +foreach(I_SIMD RANGE ${WEBP_SIMD_FLAGS_RANGE}) + list(GET WEBP_SIMD_FLAGS ${I_SIMD} WEBP_SIMD_FLAG) + list(GET SIMD_ENABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG) + set(CMAKE_REQUIRED_FLAGS ${SIMD_COMPILE_FLAG}) + check_c_source_compiles(" + #include \"${CMAKE_CURRENT_LIST_DIR}/src/dsp/dsp.h\" + int main(void) { + #if !defined(WEBP_USE_${WEBP_SIMD_FLAG}) + this is not valid code + #endif + return 0; + } + " + WEBP_HAVE_${WEBP_SIMD_FLAG} + ) + + # Check which files we should include or not. + list(GET WEBP_SIMD_FILE_EXTENSIONS ${I_SIMD} WEBP_SIMD_FILE_EXTENSION) + file(GLOB SIMD_FILES RELATIVE ${CMAKE_CURRENT_LIST_DIR} + "${CMAKE_CURRENT_SOURCE_DIR}/src/dsp/*${WEBP_SIMD_FILE_EXTENSION}" + ) + if(WEBP_HAVE_${WEBP_SIMD_FLAG}) + # Memorize the file and flags. + foreach(FILE ${SIMD_FILES}) + list(APPEND WEBP_SIMD_FILES_TO_INCLUDE ${FILE}) + list(APPEND WEBP_SIMD_FLAGS_TO_INCLUDE ${SIMD_COMPILE_FLAG}) + endforeach() + else() + # Remove the file from the list. + foreach(FILE ${SIMD_FILES}) + list(APPEND WEBP_SIMD_FILES_NOT_TO_INCLUDE ${FILE}) + endforeach() + # Explicitly disable SIMD. + if(SIMD_DISABLE_FLAGS) + list(GET SIMD_DISABLE_FLAGS ${I_SIMD} SIMD_COMPILE_FLAG) + include(CheckCCompilerFlag) + check_c_compiler_flag(${SIMD_COMPILE_FLAG} HAS_COMPILE_FLAG) + if(HAS_COMPILE_FLAG) + list(APPEND CMAKE_C_FLAGS ${SIMD_COMPILE_FLAG}) + endif() + endif() + endif() +endforeach() + +## Define extra info. +set(PACKAGE ${PROJECT_NAME}) +set(PACKAGE_NAME ${PROJECT_NAME}) + +# Read from configure.ac. +file(READ ${CMAKE_CURRENT_SOURCE_DIR}/configure.ac CONFIGURE_AC) +string(REGEX MATCHALL "\\[([0-9a-z\\.:/]*)\\]" + CONFIGURE_AC_PACKAGE_INFO ${CONFIGURE_AC} +) +function(strip_bracket VAR) + string(LENGTH ${${VAR}} TMP_LEN) + math(EXPR TMP_LEN ${TMP_LEN}-2) + string(SUBSTRING ${${VAR}} 1 ${TMP_LEN} TMP_SUB) + set(${VAR} ${TMP_SUB} PARENT_SCOPE) +endfunction() + +list(GET CONFIGURE_AC_PACKAGE_INFO 1 PACKAGE_VERSION) +strip_bracket(PACKAGE_VERSION) +list(GET CONFIGURE_AC_PACKAGE_INFO 2 PACKAGE_BUGREPORT) +strip_bracket(PACKAGE_BUGREPORT) +list(GET CONFIGURE_AC_PACKAGE_INFO 3 PACKAGE_URL) +strip_bracket(PACKAGE_URL) + +# Build more info. +set(PACKAGE_STRING "${PACKAGE_NAME} ${PACKAGE_VERSION}") +set(PACKAGE_TARNAME ${PACKAGE_NAME}) +set(VERSION ${PACKAGE_VERSION}) + +## Generate the config.h header. +configure_file(${CMAKE_CURRENT_LIST_DIR}/cmake/config.h.in + ${CMAKE_CURRENT_BINARY_DIR}/include/webp/config.h) +add_definitions(-DHAVE_CONFIG_H) +# The webp folder is included as we reference config.h as +# ../webp/config.h or webp/config.h +include_directories(${CMAKE_CURRENT_BINARY_DIR}/include + ${CMAKE_CURRENT_BINARY_DIR}/include/webp +) + + +################################################################################ +# WebP source files. +# Read the Makefile.am to get the source files. +set(WEBP_SRCS) + +function(parse_Makefile_am FOLDER WEBP_SRCS) + file(READ ${FOLDER}/Makefile.am MAKEFILE_AM) + string(REGEX MATCHALL "_SOURCES \\+= [^\n]*" + FILES_PER_LINE ${MAKEFILE_AM} + ) + set(SRCS ${WEBP_SRCS}) + foreach(FILES ${FILES_PER_LINE}) + string(SUBSTRING ${FILES} 12 -1 FILES) + string(REGEX MATCHALL "[0-9a-z\\._]+" + FILES ${FILES} + ) + foreach(FILE ${FILES}) + list(APPEND SRCS ${FOLDER}/${FILE}) + endforeach() + endforeach() + set(WEBP_SRCS ${SRCS} PARENT_SCOPE) +endfunction() + +parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/dec "${WEBP_SRCS}") +parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/demux "${WEBP_SRCS}") +parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/dsp "${WEBP_SRCS}") +parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/enc "${WEBP_SRCS}") +parse_Makefile_am(${CMAKE_CURRENT_SOURCE_DIR}/src/utils "${WEBP_SRCS}") + +# Remove the files specific to SIMD we don't user. +foreach(FILE ${WEBP_SIMD_FILES_NOT_TO_INCLUDE}) + list(REMOVE_ITEM WEBP_SRCS ${FILE}) +endforeach() + +# Build the library. +add_definitions(-Wall) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/src/ ${WEBP_DEP_INCLUDE_DIRS}) +add_library(webp ${WEBP_SRCS}) +target_link_libraries(webp ${WEBP_DEP_LIBRARIES}) + +# Change the compile flags for SIMD files we use. +list(LENGTH WEBP_SIMD_FILES_TO_INCLUDE WEBP_SIMD_FILES_TO_INCLUDE_LENGTH) +math(EXPR WEBP_SIMD_FILES_TO_INCLUDE_RANGE + "${WEBP_SIMD_FILES_TO_INCLUDE_LENGTH}-1" +) + +foreach(I_FILE RANGE ${WEBP_SIMD_FILES_TO_INCLUDE_RANGE}) + list(GET WEBP_SIMD_FILES_TO_INCLUDE ${I_FILE} FILE) + list(GET WEBP_SIMD_FLAGS_TO_INCLUDE ${I_FILE} SIMD_COMPILE_FLAG) + set_source_files_properties(${FILE} PROPERTIES + COMPILE_FLAGS ${SIMD_COMPILE_FLAG} + ) +endforeach() + +# Build the executables if asked for. +if(WEBP_BUILD_CWEBP OR WEBP_BUILD_DWEBP) + # Example utility library. + set(exampleutil_SRCS + ${CMAKE_CURRENT_SOURCE_DIR}/examples/example_util.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/example_util.h + ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h) + add_library(exampleutil ${exampleutil_SRCS}) + target_link_libraries(exampleutil webp ${WEBP_DEP_LIBRARIES}) +endif() + +if(WEBP_BUILD_DWEBP) + # dwebp + include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS}) + add_executable(dwebp + ${CMAKE_CURRENT_SOURCE_DIR}/examples/dwebp.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h + ) + target_link_libraries(dwebp webp exampleutil ${WEBP_DEP_LIBRARIES} + ${WEBP_DEP_IMG_LIBRARIES} + ) +endif() + +if(WEBP_BUILD_CWEBP) + # cwebp + include_directories(${WEBP_DEP_IMG_INCLUDE_DIRS}) + add_executable(cwebp + ${CMAKE_CURRENT_SOURCE_DIR}/examples/cwebp.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/metadata.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/metadata.h + ${CMAKE_CURRENT_SOURCE_DIR}/examples/stopwatch.h + ${CMAKE_CURRENT_SOURCE_DIR}/examples/jpegdec.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/jpegdec.h + ${CMAKE_CURRENT_SOURCE_DIR}/examples/pngdec.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/pngdec.h + ${CMAKE_CURRENT_SOURCE_DIR}/examples/tiffdec.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/tiffdec.h + ${CMAKE_CURRENT_SOURCE_DIR}/examples/webpdec.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/webpdec.h + ${CMAKE_CURRENT_SOURCE_DIR}/examples/wicdec.c + ${CMAKE_CURRENT_SOURCE_DIR}/examples/wicdec.h) + target_link_libraries(cwebp webp exampleutil ${WEBP_DEP_LIBRARIES} + ${WEBP_DEP_IMG_LIBRARIES} + ) +endif() diff --git a/README b/README index 381b9270..736d7cc3 100644 --- a/README +++ b/README @@ -84,6 +84,30 @@ be installed independently using a minor modification in the corresponding Makefile.am configure files (see comments there). See './configure --help' for more options. +CMake: +------ +The support for CMake is minimal: it only helps you compile libwebp, cwebp and +dwebp. + +Prerequisites: +A compiler (e.g., gcc with autotools) and CMake. +On a Debian-like system the following should install everything you need for a +minimal build: +$ sudo apt-get install build-essential cmake + +When building from git sources, you will need to run cmake to generate the +configure script. + +mkdir build && cd build && cmake ../ +make +make install + +If you also want cwebp or dwebp, you will need to enable them through CMake: + +cmake -DWEBP_BUILD_CWEBP=ON -DWEBP_BUILD_DWEBP=ON ../ + +or through your favorite interface (like ccmake or cmake-qt-gui). + SWIG bindings: -------------- diff --git a/cmake/config.h.in b/cmake/config.h.in new file mode 100644 index 00000000..cb3948ea --- /dev/null +++ b/cmake/config.h.in @@ -0,0 +1,146 @@ +/* Adapted from the autotools src/webp/config.h.in. */ + +/* Define if building universal (internal helper macro) */ +/* TODO: handle properly in CMake */ +#cmakedefine AC_APPLE_UNIVERSAL_BUILD 1 + +/* Set to 1 if __builtin_bswap16 is available */ +#cmakedefine HAVE_BUILTIN_BSWAP16 1 + +/* Set to 1 if __builtin_bswap32 is available */ +#cmakedefine HAVE_BUILTIN_BSWAP32 1 + +/* Set to 1 if __builtin_bswap64 is available */ +#cmakedefine HAVE_BUILTIN_BSWAP64 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_DLFCN_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GLUT_GLUT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_GL_GLUT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_INTTYPES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_MEMORY_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_OPENGL_GLUT_H 1 + +/* Have PTHREAD_PRIO_INHERIT. */ +#cmakedefine HAVE_PTHREAD_PRIO_INHERIT @HAVE_PTHREAD_PRIO_INHERIT@ + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SHLWAPI_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDINT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STDLIB_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRINGS_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_STRING_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_STAT_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_SYS_TYPES_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_UNISTD_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_WINCODEC_H 1 + +/* Define to 1 if you have the header file. */ +#cmakedefine HAVE_WINDOWS_H 1 + +/* Define to the sub-directory in which libtool stores uninstalled libraries. + */ +/* TODO: handle properly in CMake */ +#cmakedefine LT_OBJDIR "@LT_OBJDIR@" + +/* Name of package */ +#cmakedefine PACKAGE "@PROJECT_NAME@" + +/* Define to the address where bug reports for this package should be sent. */ +#cmakedefine PACKAGE_BUGREPORT "@PACKAGE_BUGREPORT@" + +/* Define to the full name of this package. */ +#cmakedefine PACKAGE_NAME "@PACKAGE_NAME@" + +/* Define to the full name and version of this package. */ +#cmakedefine PACKAGE_STRING "@PACKAGE_STRING@" + +/* Define to the one symbol short name of this package. */ +#cmakedefine PACKAGE_TARNAME "@PACKAGE_TARNAME@" + +/* Define to the home page for this package. */ +#cmakedefine PACKAGE_URL "@PACKAGE_URL@" + +/* Define to the version of this package. */ +#cmakedefine PACKAGE_VERSION "@PACKAGE_VERSION@" + +/* Define to necessary symbol if this constant uses a non-standard name on + your system. */ +#cmakedefine PTHREAD_CREATE_JOINABLE 1 + +/* Define to 1 if you have the ANSI C header files. */ +#cmakedefine STDC_HEADERS 1 + +/* Version number of package */ +#cmakedefine VERSION "@VERSION@" + +/* Enable experimental code */ +#cmakedefine WEBP_EXPERIMENTAL_FEATURES 1 + +/* Define to 1 to force aligned memory operations */ +#cmakedefine WEBP_FORCE_ALIGNED 1 + +/* Set to 1 if AVX2 is supported */ +#cmakedefine WEBP_HAVE_AVX2 1 + +/* Set to 1 if GIF library is installed */ +#cmakedefine WEBP_HAVE_GIF 1 + +/* Set to 1 if OpenGL is supported */ +#cmakedefine WEBP_HAVE_GL 1 + +/* Set to 1 if JPEG library is installed */ +#cmakedefine WEBP_HAVE_JPEG 1 + +/* Set to 1 if PNG library is installed */ +#cmakedefine WEBP_HAVE_PNG 1 + +/* Set to 1 if SSE2 is supported */ +#cmakedefine WEBP_HAVE_SSE2 1 + +/* Set to 1 if SSE4.1 is supported */ +#cmakedefine WEBP_HAVE_SSE41 1 + +/* Set to 1 if TIFF library is installed */ +#cmakedefine WEBP_HAVE_TIFF 1 + +/* Undefine this to disable thread support. */ +#cmakedefine WEBP_USE_THREAD 1 + +/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most + significant byte first (like Motorola and SPARC, unlike Intel). */ +#if defined AC_APPLE_UNIVERSAL_BUILD +# if defined __BIG_ENDIAN__ +# define WORDS_BIGENDIAN 1 +# endif +#else +# ifndef WORDS_BIGENDIAN +# undef WORDS_BIGENDIAN +# endif +#endif