cmake_minimum_required(VERSION 3.2 FATAL_ERROR) # It is 2017 so lets leverage a modern C++ set(CMAKE_CXX_STANDARD 14) set(CMAKE_CXX_STANDARD_REQUIRED True) set(CMAKE_CXX_EXTENSIONS False) set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") include(CheckFunctionExists) set(CMAKE_VERBOSE_MAKEFILE off CACHE BOOL "Show verbose build commands") set(WITH_MAGIC 1 CACHE BOOL "Use libmagic to identify file mime types") set(WITH_MYSQL 0 CACHE BOOL "Store media information in MySQL DB") set(WITH_CURL 1 CACHE BOOL "CURL required for YouTube and/or SopCast") set(WITH_INOTIFY 1 CACHE BOOL "Enable Inotify file monitoring support") set(WITH_JS 1 CACHE BOOL "Enable JavaScript for custom import script") set(WITH_TAGLIB 1 CACHE BOOL "Use TagLib to extract audio file metadata") set(WITH_AVCODEC 0 CACHE BOOL "Enable ffmpeg/libav") set(WITH_FFMPEGTHUMBNAILER 0 CACHE BOOL "Enable Thumbnail generation") set(WITH_EXIF 1 CACHE BOOL "Use libexif to extract image metadata") set(WITH_EXIV2 0 CACHE BOOL "Use libexiv2 to extract image metadata") set(WITH_PROTOCOL_EXTENSIONS 1 CACHE BOOL "Add incomplete DLNA protocol extensions to resposnses") set(WITH_SYSTEMD 1 CACHE BOOL "Install Systemd unit file") set(WITH_LASTFM 0 CACHE BOOL "Enable LastFM") set(WITH_DEBUG 1 CACHE BOOL "Enables debug logging") project("gerbera") set(gerbera_MAJOR_VERSION 1) set(gerbera_MINOR_VERSION 1) set(gerbera_PATCH_VERSION 0) set(gerbera_RELEASE "") set(gerbera_SUFFIX "") set(libgerberaFILES src/action_request.cc src/action_request.h src/atrailers_content_handler.cc src/atrailers_content_handler.h src/atrailers_service.cc src/atrailers_service.h src/autoscan.cc src/autoscan.h src/autoscan_inotify.cc src/autoscan_inotify.h src/buffered_io_handler.cc src/buffered_io_handler.h src/cached_url.cc src/cached_url.h src/cds_objects.cc src/cds_objects.h src/cds_resource.cc src/cds_resource.h src/cds_resource_manager.cc src/cds_resource_manager.h src/common.h src/config_manager.cc src/config_manager.h src/config_options.h src/content_manager.cc src/content_manager.h src/contrib/md5.c src/contrib/md5.h src/curl_io_handler.cc src/curl_io_handler.h src/destroyer.cc src/destroyer.h src/dictionary.cc src/dictionary.h src/exceptions.cc src/exceptions.h src/executor.h src/fd_io_handler.cc src/fd_io_handler.h src/file_io_handler.cc src/file_io_handler.h src/file_request_handler.cc src/file_request_handler.h src/filesystem.cc src/filesystem.h src/generic_task.cc src/generic_task.h src/io_handler_buffer_helper.cc src/io_handler_buffer_helper.h src/io_handler.cc src/io_handler_chainer.cc src/io_handler_chainer.h src/io_handler.h src/jpeg_resolution.cc src/lastfm_scrobbler.cc src/lastfm_scrobbler.h src/layout/fallback_layout.cc src/layout/fallback_layout.h src/layout/js_layout.cc src/layout/js_layout.h src/layout/layout.h src/logger.cc src/logger.h src/mem_io_handler.cc src/mem_io_handler.h src/memory.cc src/memory.h src/metadata/exiv2_handler.cc src/metadata/exiv2_handler.h src/metadata/ffmpeg_handler.cc src/metadata/ffmpeg_handler.h src/metadata_handler.cc src/metadata_handler.h src/metadata/libexif_handler.cc src/metadata/libexif_handler.h src/metadata/taglib_handler.cc src/metadata/taglib_handler.h src/metadata/fanart_handler.cc src/metadata/fanart_handler.h src/mt_inotify.cc src/mt_inotify.h src/mxml/attribute.cc src/mxml/attribute.h src/mxml/comment.cc src/mxml/comment.h src/mxml/context.cc src/mxml/context.h src/mxml/document.cc src/mxml/document.h src/mxml/element.cc src/mxml/element.h src/mxml/mxml.h src/mxml/node.cc src/mxml/node.h src/mxml/parseexception.cc src/mxml/parseexception.h src/mxml/parser_expat.cc src/mxml/parser.h src/mxml/xml_text.cc src/mxml/xml_text.h src/mxml/xml_to_json.cc src/mxml/xml_to_json.h src/object_dictionary.h src/online_service.cc src/online_service.h src/online_service_helper.cc src/online_service_helper.h src/play_hook.cc src/play_hook.h src/process.cc src/process_executor.cc src/process_executor.h src/process.h src/process_io_handler.cc src/process_io_handler.h src/reentrant_array.h src/request_handler.cc src/request_handler.h src/rexp.cc src/rexp.h src/scripting/import_script.cc src/scripting/import_script.h src/scripting/js_functions.cc src/scripting/js_functions.h src/scripting/playlist_parser_script.cc src/scripting/playlist_parser_script.h src/scripting/runtime.cc src/scripting/runtime.h src/scripting/script.cc src/scripting/script.h src/server.cc src/serve_request_handler.cc src/serve_request_handler.h src/server.h src/session_manager.cc src/session_manager.h src/singleton.cc src/singleton.h src/sopcast_content_handler.cc src/sopcast_content_handler.h src/sopcast_service.cc src/sopcast_service.h src/storage/cache_object.cc src/storage/cache_object.h src/storage.cc src/storage.h src/storage/mysql/mysql_create_sql.h src/storage/mysql/mysql_storage.cc src/storage/mysql/mysql_storage.h src/storage/sqlite3/sqlite3_create_sql.h src/storage/sqlite3/sqlite3_storage.cc src/storage/sqlite3/sqlite3_storage.h src/storage/sql_storage.cc src/storage/sql_storage.h src/storage/storage_cache.cc src/storage/storage_cache.h src/string_converter.cc src/string_converter.h src/subscription_request.cc src/subscription_request.h src/task_processor.cc src/task_processor.h src/thread_executor.cc src/thread_executor.h src/timer.cc src/timer.h src/tools.cc src/tools.h src/transcoding/transcode_dispatcher.cc src/transcoding/transcode_dispatcher.h src/transcoding/transcode_ext_handler.cc src/transcoding/transcode_ext_handler.h src/transcoding/transcode_handler.h src/transcoding/transcoding.cc src/transcoding/transcoding.h src/transcoding/transcoding_process_executor.cc src/transcoding/transcoding_process_executor.h src/update_manager.cc src/update_manager.h src/upnp_cds.cc src/upnp_cds.h src/upnp_cm.cc src/upnp_cm.h src/upnp_mrreg.cc src/upnp_mrreg.h src/upnp_xml.cc src/upnp_xml.h src/url.cc src/url.h src/url_request_handler.cc src/url_request_handler.h src/web/action.cc src/web/add.cc src/web/add_object.cc src/web/auth.cc src/web_callbacks.cc src/web_callbacks.h src/web/containers.cc src/web/directories.cc src/web/edit_load.cc src/web/edit_save.cc src/web/files.cc src/web/items.cc src/web/pages.cc src/web/pages.h src/web/remove.cc src/web_request_handler.cc src/web_request_handler.h src/web/tasks.cc src/web/web_autoscan.cc src/web/web_update.cc src/xpath.cc src/xpath.h src/youtube_content_handler.cc src/youtube_content_handler.h src/youtube_service.cc src/youtube_service.h src/youtube_video_url.cc src/youtube_video_url.h src/zmm/array.cc src/zmm/array.h src/zmm/base_array.h src/zmm/base_queue.h src/zmm/base_stack.h src/zmm/exception.cc src/zmm/exception.h src/zmm/object_queue.h src/zmm/object_stack.h src/zmm/stringtokenizer.cc src/zmm/stringtokenizer.h src/zmm/zmmf.h src/zmm/object.cc src/zmm/object.h src/zmm/ref.h src/zmm/stringbuffer.cc src/zmm/stringbuffer.h src/zmm/strings.cc src/zmm/strings.h src/zmm/zmm.h) add_library(libgerbera OBJECT ${libgerberaFILES}) target_include_directories(libgerbera PRIVATE "${CMAKE_SOURCE_DIR}/src") add_executable(gerbera src/main.cc $) target_include_directories(gerbera PRIVATE "${CMAKE_SOURCE_DIR}/src") # Warnings are nice set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall") # Add the automatically determined parts of the RPATH which point to # dirss outside the build tree to the install RPATH set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) # Provide __FILENAME__ for debug statements include(DefFileName) define_file_path_for_sources(libgerbera) define_file_path_for_sources(gerbera) # Use libc++ with clang if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++") endif() # Host OS Check if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(HOST_OS "linux") set(LINUX 1) elseif(${CMAKE_SYSTEM_NAME} MATCHES ".*(SunOS|Solaris).*") set(HOST_OS "solaris") set(SOLARIS 1) elseif(${CMAKE_SYSTEM_NAME} MATCHES ".*BSD.*") set(HOST_OS "bsd") set(BSD 1) elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") set(HOST_OS "darwin") set(DARWIN 1) endif() if(NOT HOST_OS) message(FATAL_ERROR "Gerbera was unable to deterimine the host OS. Please report this. Value of CMAKE_SYSTEM_NAME: ${CMAKE_SYSTEM_NAME}") endif() if (SOLARIS) add_definitions(-DSOLARIS) endif() if (BSD) add_definitions(-DBSD) endif() add_definitions(-DPACKAGE_NAME="gerbera${gerbera_SUFFIX}") add_definitions(-DVERSION="${gerbera_MAJOR_VERSION}.${gerbera_MINOR_VERSION}.${gerbera_PATCH_VERSION}${gerbera_RELEASE}${gerbera_SUFFIX}") add_definitions(-DPACKAGE_DATADIR="${CMAKE_INSTALL_PREFIX}/share/gerbera") # Generate Compile Information include("GenCompileInfo") generate_compile_info() target_compile_definitions(gerbera PRIVATE -DCOMPILE_INFO="${COMPILE_INFO}") target_compile_definitions(gerbera PRIVATE -DGIT_BRANCH="${GIT_BRANCH}") target_compile_definitions(gerbera PRIVATE -DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}") add_definitions(-DEXTERNAL_TRANSCODING -DAUTO_CREATE_DATABASE) if (WITH_DEBUG) add_definitions(-DTOMBDEBUG) endif() if (WITH_PROTOCOL_EXTENSIONS) add_definitions(-DEXTEND_PROTOCOLINFO) endif() find_package(Threads REQUIRED) target_link_libraries(gerbera ${CMAKE_THREAD_LIBS_INIT}) find_package(Iconv REQUIRED) include_directories(${ICONV_INCLUDE_DIR}) target_link_libraries(gerbera ${ICONV_LIBRARIES}) if (ICONV_SECOND_ARGUMENT_IS_CONST) add_definitions(-DICONV_CONST) endif() find_package(UUID REQUIRED) include_directories(${UUID_INCLUDE_DIRS}) target_link_libraries(gerbera ${UUID_LIBRARIES}) if (FOUND_BSD_UUID) add_definitions(-DBSD_NATIVE_UUID) endif() find_package(LFS REQUIRED) if (LFS_FOUND) add_definitions(${LFS_DEFINITIONS}) add_compile_options(${LFS_COMPILE_OPTIONS}) target_link_libraries(gerbera ${LFS_LIBRARIES}) endif() find_package (LibUpnp REQUIRED) include_directories(${UPNP_INCLUDE_DIRS}) target_link_libraries (gerbera ${UPNP_LIBRARIES}) if (UPNP_VERSION_STRING VERSION_LESS "1.8.0") message(FATAL_ERROR "gerbera requires libupnp 1.8.0 or above.") endif() if (NOT UPNP_HAS_IPV6) message(FATAL_ERROR "gerbera requires libupnp with IPv6 support.") endif() if (NOT UPNP_HAS_REUSEADDR) message(WARNING "\n !! It is strongly recommended to build libupnp with --enable-reuseaddr !!\nWithout this option Gerbera will be unable to restart with the same port number.") endif() # Debian ships a snapshot from 2010: libupnp4 (1.8.0~svn20100507-1.2) # This is missing templated types so we need to ifdef if(UPNP_INCLUDE_DIR AND NOT EXISTS "${UPNP_INCLUDE_DIR}/TemplateInclude.h") message (FATAL_ERROR "\n!! You are using a very old 1.8 snapshot. Please upgrade to a 1.8.x release from upstream (https://github.com/mrjimenez/pupnp) !!\n") endif() find_package (EXPAT REQUIRED) if (EXPAT_FOUND) include_directories(${EXPAT_INCLUDE_DIRS}) target_link_libraries (gerbera ${EXPAT_LIBRARIES}) else() message(FATAL_ERROR "Expat not found!") endif() find_package (SQLite3 REQUIRED) if(SQLITE3_FOUND) include_directories(${SQLITE3_INCLUDE_DIRS}) target_link_libraries (gerbera ${SQLITE3_LIBRARIES}) add_definitions(-DHAVE_SQLITE3) else() message(FATAL_ERROR "SQLite3 not found!") endif() check_function_exists(nl_langinfo HAVE_NL_LANGINFO) if (HAVE_NL_LANGINFO) add_definitions("-DHAVE_NL_LANGINFO") endif() check_function_exists(setlocale HAVE_SETLOCALE) if (HAVE_SETLOCALE) add_definitions("-DHAVE_SETLOCALE") endif() # Link to the socket library if it exists. This is something you need on Solaris/OmniOS/Joyent find_library(SOCKET_LIBRARY socket) if(SOCKET_LIBRARY) set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${SOCKET_LIBRARY}) target_link_libraries(gerbera ${SOCKET_LIBRARY}) endif() # Link to libnsl (Network services library) if it exists. This is something you need on Solaris/OmniOS/Joyent find_library(NSL_LIBRARY nsl) if(NSL_LIBRARY) set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${NSL_LIBRARY}) target_link_libraries(gerbera ${NSL_LIBRARY}) endif() if(WITH_INOTIFY) find_package(INotify) if(INOTIFY_FOUND) include_directories(${INOTIFY_INCLUDE_DIR}) add_definitions(-DHAVE_INOTIFY) # FreeBSD INotify shim! if(INOTIFY_LIBRARY) target_link_libraries(gerbera ${INOTIFY_LIBRARY}) endif() endif () endif() if(WITH_JS) find_package(Duktape) IF (DUKTAPE_FOUND) include_directories(${DUKTAPE_INCLUDE_DIRS}) target_link_libraries (gerbera ${DUKTAPE_LIBRARIES}) add_definitions(-DHAVE_JS) else() message(FATAL_ERROR "Duktape not found!") endif() endif() if(WITH_MYSQL) find_package(MySQL REQUIRED) if (MYSQL_FOUND) include_directories(${MYSQL_INCLUDE_DIRS}) target_link_libraries (gerbera ${MYSQL_CLIENT_LIBS}) add_definitions(-DHAVE_MYSQL) else() message(FATAL_ERROR "MySQL not found") endif () endif() if(WITH_CURL) find_package (CURL REQUIRED) if (CURL_FOUND) include_directories(${CURL_INCLUDE_DIRS}) target_link_libraries (gerbera ${CURL_LIBRARIES}) add_definitions(-DHAVE_CURL) add_definitions(-DONLINE_SERVICES) add_definitions(-DYOUTUBE) else() message(FATAL_ERROR "cURL not found") endif() endif() if(WITH_TAGLIB) find_package (Taglib) if (TAGLIB_FOUND) include_directories(${TAGLIB_INCLUDE_DIRS}) target_link_libraries (gerbera ${TAGLIB_LIBRARIES}) add_definitions(-DHAVE_TAGLIB) else() message(FATAL_ERROR "Taglib not found!") endif() endif() if(WITH_MAGIC) find_package (LibMagic) if (MAGIC_FOUND) include_directories(${MAGIC_INCLUDE_DIRS}) target_link_libraries (gerbera ${MAGIC_LIBRARIES}) add_definitions(-DHAVE_MAGIC) else() message(FATAL_ERROR "Magic not found") endif () endif() if(WITH_AVCODEC) find_package (FFMPEG) if (FFMPEG_FOUND) include_directories(${FFMPEG_INCLUDE_DIR}) target_link_libraries (gerbera ${FFMPEG_LIBRARIES}) add_definitions(-DHAVE_FFMPEG) if (HAVE_AVSTREAM_CODECPAR) add_definitions(-DHAVE_AVSTREAM_CODECPAR) endif() else() message(FATAL_ERROR "FFMpeg/LibAV not found") endif () endif() if(WITH_FFMPEGTHUMBNAILER) find_package (FFMpegThumbnailer) if (FFMPEGTHUMBNAILER_FOUND) include_directories(${FFMPEGTHUMBNAILER_INCLUDE_DIR}) target_link_libraries (gerbera ${FFMPEGTHUMBNAILER_LIBRARIES}) add_definitions(-DHAVE_FFMPEGTHUMBNAILER) else() message(FATAL_ERROR "FFMpegThumbnailer not found") endif () endif() if(WITH_EXIF) find_package (EXIF) if (EXIF_FOUND) include_directories(${EXIF_INCLUDE_DIRS}) target_link_libraries (gerbera ${EXIF_LIBRARIES}) add_definitions(-DHAVE_LIBEXIF) else() message(FATAL_ERROR "LibExif not found") endif() endif() if(WITH_EXIV2) find_package (EXIV2) if (EXIV2_FOUND) include_directories(${EXIV2_INCLUDE_DIRS}) target_link_libraries (gerbera ${EXIV2_LIBRARIES}) add_definitions(-DHAVE_EXIV2) else() message(FATAL_ERROR "Exiv2 not found") endif() endif() if(WITH_LASTFM) find_package (LastFMLib) if (LASTFMLIB_FOUND) include_directories(${LASTFMLIB_INCLUDE_DIRS}) target_link_libraries (gerbera ${LASTFMLIB_LIBRARIES}) add_definitions(-DHAVE_LASTFMLIB) else() message(FATAL_ERROR "LastFMLib not found") endif() endif() if(WITH_SYSTEMD) find_package(Systemd) if(SYSTEMD_FOUND) if(WITH_MYSQL AND MYSQL_FOUND) set (SYSTEMD_AFTER_TARGET "mysql.target network.target") set (SYSTEMD_DESCRIPTION "Gerbera Media Server with MySQL") else() set (SYSTEMD_AFTER_TARGET "network.target") set (SYSTEMD_DESCRIPTION "Gerbera Media Server") endif() configure_file(${CMAKE_SOURCE_DIR}/scripts/systemd/gerbera.service.cmake gerbera.service) message(STATUS "Configuring systemd unit file: gerbera.service" ) INSTALL(FILES ${CMAKE_CURRENT_BINARY_DIR}/gerbera.service DESTINATION ${SYSTEMD_UNIT_DIR} COMPONENT init) else() message(FATAL_ERROR "Systemd not found") endif() endif() # Needs to be towards the end (after CURL, TagLib, etc...) find_package (ZLIB REQUIRED) include_directories(${ZLIB_INCLUDE_DIRS}) target_link_libraries (gerbera ${ZLIB_LIBRARIES}) INSTALL(TARGETS gerbera DESTINATION bin) INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/scripts/js DESTINATION share/gerbera) INSTALL(DIRECTORY ${PROJECT_SOURCE_DIR}/web DESTINATION share/gerbera) INSTALL(FILES ${PROJECT_SOURCE_DIR}/config/mappings.xml ${PROJECT_SOURCE_DIR}/config/mysql.sql ${PROJECT_SOURCE_DIR}/config/sqlite3.sql DESTINATION share/gerbera) INSTALL(FILES ${PROJECT_SOURCE_DIR}/doc/gerbera.1 DESTINATION share/man/man1)