From: Mike Gelfand Date: Mon, 1 Dec 2014 19:55:22 +0000 (+0000) Subject: #5828: Initial CMake build system support X-Git-Tag: 2.90~342 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=83c4edb00810ff14a6fe86fbbb3868f2d6c36511;p=transmission #5828: Initial CMake build system support --- diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 000000000..7abb0ef92 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,395 @@ +cmake_minimum_required(VERSION 2.8.5 FATAL_ERROR) +project(transmission) + +list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake) + +include(CheckIncludeFile) +include(CheckIncludeFiles) +include(CheckFunctionExists) +include(CheckLibraryExists) +include(ExternalProject) +include(GNUInstallDirs) +include(TrMacros) + + option(ENABLE_DAEMON "Build daemon" ON) +tr_auto_option(ENABLE_GTK "Build GTK+ client" AUTO) +tr_auto_option(ENABLE_QT "Build Qt client" AUTO) + option(ENABLE_UTILS "Build utils (create, edit, show)" ON) + option(ENABLE_CLI "Build command-line client" OFF) + option(ENABLE_TESTS "Build unit tests" ON) + option(ENABLE_LIGHTWEIGHT "Optimize libtransmission for low-resource systems: smaller cache size, prefer unencrypted peer connections, etc." OFF) + option(ENABLE_UTP "Build µTP support" ON) + option(ENABLE_NLS "Enable native language support" ON) + option(INSTALL_DOC "Build/install documentation" ON) + option(INSTALL_LIB "Install the library" OFF) + option(USE_QT5 "Use Qt 5 (instead of default Qt 4)" OFF) +tr_auto_option(USE_SYSTEM_EVENT2 "Use system event2 library" AUTO) +tr_auto_option(USE_SYSTEM_DHT "Use system dht library" AUTO) +tr_auto_option(USE_SYSTEM_MINIUPNPC "Use system miniupnpc library" AUTO) +tr_auto_option(USE_SYSTEM_NATPMP "Use system natpmp library" AUTO) +tr_auto_option(USE_SYSTEM_UTP "Use system utp library" AUTO) +tr_auto_option(WITH_INOTIFY "Enable inotify support (on systems that support it)" AUTO) +tr_auto_option(WITH_KQUEUE "Enable kqueue support (on systems that support it)" AUTO) +tr_auto_option(WITH_SYSTEMD "Add support for systemd startup notification (on systems that support it)" AUTO) + +set(TR_NAME ${PROJECT_NAME}) + +# convention: -TR MAJOR MINOR MAINT STATUS - (each a single char) +# STATUS: "X" for prerelease beta builds, +# "Z" for unsupported trunk builds, +# "0" for stable, supported releases +# these should be the only two lines you need to change +set(TR_USER_AGENT_PREFIX "2.84+") +set(TR_PEER_ID_PREFIX "-TR284Z-") + +string(REGEX MATCH "^([0-9]+)\\.([0-9]+).*" TR_VERSION "${TR_USER_AGENT_PREFIX}") +set(TR_VERSION_MAJOR "${CMAKE_MATCH_1}") +set(TR_VERSION_MINOR "${CMAKE_MATCH_2}") + +if(TR_PEER_ID_PREFIX MATCHES "X-$") + set(TR_BETA_RELEASE 1) +elseif(TR_PEER_ID_PREFIX MATCHES "Z-$") + set(TR_NIGHTLY_RELEASE 1) +else() + set(TR_STABLE_RELEASE 1) +endif() + +if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.svn) + find_package(Subversion) + if(Subversion_FOUND) + Subversion_WC_INFO(${CMAKE_SOURCE_DIR} TR_SVN) + set(TR_SCM_REVISION "${TR_SVN_WC_REVISION}") + endif() + + if("${TR_SCM_REVISION}" STREQUAL "") + file(GLOB_RECURSE TR_ALL_SOURCES RELATIVE ${CMAKE_SOURCE_DIR} *.cc *.[chm] *.po) + set(TR_SCM_REVISION 0) + foreach(F ${TR_ALL_SOURCES}) + file(STRINGS ${F} F_ID REGEX "\\$Id:") + if(F_ID MATCHES "\\$Id: [^ ]+ ([0-9]+) " AND CMAKE_MATCH_1 GREATER TR_SCM_REVISION) + set(TR_SCM_REVISION ${CMAKE_MATCH_1}) + endif() + endforeach() + endif() +elseif(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/.git) + find_package(Git) + if(GIT_FOUND) + execute_process( + COMMAND + ${GIT_EXECUTABLE} rev-list --max-count=1 --abbrev-commit HEAD + WORKING_DIRECTORY + ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE + TR_SCM_REVISION + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + endif() +endif() + +if("${TR_SCM_REVISION}" STREQUAL "") + set(TR_SCM_REVISION 0) +endif() + +set(CURL_MINIMUM 7.15.4) +set(EVENT2_MINIMUM 2.0.10) +set(OPENSSL_MINIMUM 0.9.4) +set(ZLIB_MINIMUM 1.2.3) +set(GTK_MINIMUM 3.4.0) +set(GLIB_MINIMUM 2.32.0) +set(GIO_MINIMUM 2.26.0) +set(LIBAPPINDICATOR_MINIMUM 0.4.90) + +tr_github_upstream(EVENT2 libevent/libevent be1aeff21a b9135e43c925b1f86ec43ea71a8c367a) +tr_github_upstream(NATPMP miniupnp/libnatpmp 31ebda6226 7e8deb00a98220622a6f2aeb98b8921b) +tr_github_upstream(MINIUPNPC miniupnp/miniupnp c490b42547 f9b7a4715bcd5034abae866e31102888) +tr_github_upstream(DHT jech/dht bf62643a95 0a2a2abe447d8a73f0084c1bc837e566) +tr_github_upstream(UTP bittorrent/libutp 7c4f19abdf 8b92aa05abec5f6675cdde6477cd6f51) + +if(WIN32) + foreach(L C CXX) + # Target version (Vista and up) + set(CMAKE_${L}_FLAGS "${CMAKE_${L}_FLAGS} -DWINVER=0x0600 -D_WIN32_WINNT=0x0600") + # Use Unicode API (although we always use W or A names explicitly) + set(CMAKE_${L}_FLAGS "${CMAKE_${L}_FLAGS} -DUNICODE -D_UNICODE") + # Filter out needless definitions + set(CMAKE_${L}_FLAGS "${CMAKE_${L}_FLAGS} -DWIN32_LEAN_AND_MEAN -DNOMINMAX") + # Ignore various deprecation and security warnings (at least for now) + set(CMAKE_${L}_FLAGS "${CMAKE_${L}_FLAGS} -D_CRT_SECURE_NO_DEPRECATE -D_CRT_NONSTDC_NO_DEPRECATE -D_SCL_SECURE_NO_WARNINGS -D_WINSOCK_DEPRECATED_NO_WARNINGS") + # Increase maximum FD_SET size + set(CMAKE_${L}_FLAGS "${CMAKE_${L}_FLAGS} -DFD_SETSIZE=1024") + if(MSVC) + # Reduce noise (at least for now) + set(CMAKE_${L}_FLAGS "${CMAKE_${L}_FLAGS} /wd4244 /wd4267") + endif() + endforeach() +endif() + +find_package(Threads) +find_package(PkgConfig QUIET) + +find_package(OpenSSL ${OPENSSL_MINIMUM} REQUIRED) +find_package(CURL ${CURL_MINIMUM} REQUIRED) + +if(UNIX) + find_package(ICONV REQUIRED) +endif() + +if(ENABLE_GTK) + tr_get_required_flag(ENABLE_GTK GTK_IS_REQUIRED) + + pkg_check_modules(GTK ${GTK_IS_REQUIRED} + gtk+-3.0>=${GTK_MINIMUM} + glib-2.0>=${GLIB_MINIMUM} + gio-2.0>=${GIO_MINIMUM} + gmodule-2.0>=${GLIB_MINIMUM} + gthread-2.0>=${GLIB_MINIMUM}) + + tr_fixup_auto_option(ENABLE_GTK GTK_FOUND GTK_IS_REQUIRED) + + set(WITH_LIBAPPINDICATOR OFF) + if(ENABLE_GTK) + pkg_check_modules(LIBAPPINDICATOR appindicator3-0.1>=${LIBAPPINDICATOR_MINIMUM}) + if(LIBAPPINDICATOR_FOUND) + set(WITH_LIBAPPINDICATOR ON) + endif() + endif() +endif() + +if(ENABLE_QT) + tr_get_required_flag(ENABLE_QT QT_IS_REQUIRED) + + if(POLICY CMP0020) + cmake_policy(SET CMP0020 NEW) + endif() + + if(USE_QT5) + set(TR_QT5_MODULES Core Gui Widgets Network DBus LinguistTools) + set(QT_FOUND ON) + foreach(M ${TR_QT5_MODULES}) + find_package(Qt5${M} ${QT_IS_REQUIRED}) + if(NOT Qt5${M}_FOUND) + set(QT_FOUND OFF) + break() + endif() + endforeach() + else() + find_package(Qt4 4.6.2 ${QT_IS_REQUIRED} COMPONENTS QtCore QtGui QtNetwork QtDBus) + endif() + + tr_fixup_auto_option(ENABLE_QT QT_FOUND QT_IS_REQUIRED) +endif() + +find_package(ZLIB ${ZLIB_MINIMUM}) +if(ZLIB_FOUND) + add_definitions(-DHAVE_ZLIB) +endif() + +set(THIRD_PARTY_DIR ${CMAKE_SOURCE_DIR}/third-party) + +if(WIN32) + tr_add_external_auto_library(EVENT2 event + PATCH_COMMAND "${CMAKE_COMMAND}" -E copy "${THIRD_PARTY_DIR}/event2.cmake" "/CMakeLists.txt") +else() + tr_add_external_auto_library(EVENT2 event + BUILD_IN_SOURCE 1 + CONFIGURE_COMMAND "/autogen.sh" + COMMAND "/configure" "--prefix=" "--disable-shared") +endif() + +tr_add_external_auto_library(NATPMP natpmp + PATCH_COMMAND "${CMAKE_COMMAND}" -E copy "${THIRD_PARTY_DIR}/natpmp.cmake" "/CMakeLists.txt") +if(NOT USE_SYSTEM_NATPMP) + set(NATPMP_DEFINITIONS -DNATPMP_STATICLIB) +endif() + +tr_add_external_auto_library(MINIUPNPC miniupnpc + PATCH_COMMAND "${CMAKE_COMMAND}" -E remove_directory "/minissdpd" + COMMAND "${CMAKE_COMMAND}" -E remove_directory "/miniupnpc-async" + COMMAND "${CMAKE_COMMAND}" -E remove_directory "/miniupnpc-libevent" + COMMAND "${CMAKE_COMMAND}" -E remove_directory "/miniupnpd" + COMMAND "${CMAKE_COMMAND}" -E remove "/README" + COMMAND "${CMAKE_COMMAND}" -E copy_directory "/miniupnpc" "" + COMMAND "${CMAKE_COMMAND}" -E remove_directory "/miniupnpc" + CMAKE_ARGS + -DUPNPC_BUILD_STATIC=ON + -DUPNPC_BUILD_SHARED=OFF + -DUPNPC_BUILD_TESTS=OFF) +set(MINIUPNPC_DEFINITIONS -DSYSTEM_MINIUPNP) +if(NOT USE_SYSTEM_MINIUPNPC) + list(APPEND MINIUPNPC_DEFINITIONS -DMINIUPNP_STATICLIB) + set(MINIUPNPC_VERSION 1.9) + set(MINIUPNPC_API_VERSION 10) +endif() + +tr_add_external_auto_library(DHT dht + PATCH_COMMAND "${CMAKE_COMMAND}" -E copy "${THIRD_PARTY_DIR}/dht.cmake" "/CMakeLists.txt") + +if(ENABLE_UTP) + tr_add_external_auto_library(UTP utp + PATCH_COMMAND "${CMAKE_COMMAND}" -E copy "${THIRD_PARTY_DIR}/utp.cmake" "/CMakeLists.txt" + COMMAND "${CMAKE_COMMAND}" -E copy "${THIRD_PARTY_DIR}/utp_config.h" "/utp_config.h") +endif() + +if(WITH_INOTIFY) + tr_get_required_flag(WITH_INOTIFY INOTIFY_IS_REQUIRED) + + set(INOTIFY_FOUND OFF) + check_include_file(sys/inotify.h HAVE_SYS_INOTIFY_H) + check_function_exists(inotify_init HAVE_INOTIFY_INIT) + if(HAVE_SYS_INOTIFY_H AND HAVE_INOTIFY_INIT) + set(INOTIFY_FOUND ON) + endif() + + tr_fixup_auto_option(WITH_INOTIFY INOTIFY_FOUND INOTIFY_IS_REQUIRED) +endif() + +if(WITH_KQUEUE) + tr_get_required_flag(WITH_KQUEUE KQUEUE_IS_REQUIRED) + + set(KQUEUE_FOUND OFF) + check_include_files("sys/types.h;sys/event.h" HAVE_SYS_EVENT_H) + check_function_exists(kqueue HAVE_KQUEUE) + if(HAVE_SYS_EVENT_H AND HAVE_KQUEUE) + set(KQUEUE_FOUND ON) + endif() + + tr_fixup_auto_option(WITH_KQUEUE KQUEUE_FOUND KQUEUE_IS_REQUIRED) +endif() + +if(WITH_SYSTEMD) + tr_get_required_flag(WITH_SYSTEMD SYSTEMD_IS_REQUIRED) + + pkg_check_modules(SYSTEMD_DAEMON ${SYSTEMD_IS_REQUIRED} libsystemd-daemon) + + tr_fixup_auto_option(WITH_SYSTEMD SYSTEMD_DAEMON_FOUND SYSTEMD_IS_REQUIRED) +endif() + +include_directories(${CMAKE_BINARY_DIR}) + +if(CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=gnu99") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11") + + set(NEEDED_COMPILER_FLAGS + -Wpointer-arith + -Wformat + -Wformat-security + -Wcast-align + -Wundef + -Wcast-align + -Wmissing-declarations + -Wmissing-format-attribute + -Wredundant-decls + -Wunused-parameter + -Wwrite-strings + -Winline + -Wfloat-equal + -Wextra + -Winit-self + -Wvariadic-macros) + + set(NEEDED_C_COMPILER_FLAGS + ${NEEDED_COMPILER_FLAGS} + -Wstrict-prototypes + -Wnested-externs + -Wdeclaration-after-statement) + string(REPLACE ";" " " NEEDED_C_COMPILER_FLAGS_STRING "${NEEDED_C_COMPILER_FLAGS}") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${NEEDED_C_COMPILER_FLAGS_STRING}") + + set(NEEDED_CXX_COMPILER_FLAGS + ${NEEDED_COMPILER_FLAGS}) + string(REPLACE ";" " " NEEDED_CXX_COMPILER_FLAGS_STRING "${NEEDED_CXX_COMPILER_FLAGS}") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${NEEDED_CXX_COMPILER_FLAGS_STRING}") +endif() + +set(NEEDED_HEADERS + libintl.h + stdbool.h + sys/statvfs.h + xfs/xfs.h) + +foreach(H ${NEEDED_HEADERS}) + tr_make_id("${H}" H_ID) + check_include_file(${H} HAVE_${H_ID}) + if(HAVE_${H_ID}) + add_definitions(-DHAVE_${H_ID}) + endif() +endforeach() + +set(NEEDED_FUNCTIONS + daemon + fallocate64 + getmntent + getpagesize + htonll + iconv_open + localtime_r + memmem + mkdtemp + ntohll + posix_fadvise + posix_fallocate + posix_memalign + pread + pwrite + statvfs + strlcpy + strsep + syslog + valloc) + +foreach(F ${NEEDED_FUNCTIONS}) + tr_make_id("${F}" F_ID) + check_function_exists(${F} HAVE_${F_ID}) + if(HAVE_${F_ID}) + add_definitions(-DHAVE_${F_ID}) + endif() +endforeach() + +if(MINGW) + check_function_exists(__mingw_printf HAVE_MINGW_PRINTF) + if(HAVE_MINGW_PRINTF) + add_definitions(-D__USE_MINGW_ANSI_STDIO=1 -D__STDC_FORMAT_MACROS=1) + endif() +endif() + +check_library_exists(m sqrt "" HAVE_LIBM) +if(HAVE_LIBM) + set(LIBM_LIBRARY m) +endif() + +if(ENABLE_TESTS) + enable_testing() +endif() + +add_subdirectory(libtransmission) + +foreach(P daemon cli utils gtk qt) + string(TOUPPER "${P}" P_ID) + if(ENABLE_${P_ID}) + add_subdirectory(${P}) + endif() +endforeach() + +if(ENABLE_DAEMON OR ENABLE_GTK OR ENABLE_QT) + install(DIRECTORY web DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/${TR_NAME} + PATTERN *.am EXCLUDE + PATTERN *.scss EXCLUDE) +endif() + +if(ENABLE_GTK AND ENABLE_NLS) + find_package(Gettext REQUIRED) + add_subdirectory(po) +endif() + +if(INSTALL_DOC) + install(FILES AUTHORS COPYING NEWS README extras/rpc-spec.txt extras/send-email-when-torrent-done.sh DESTINATION ${CMAKE_INSTALL_DOCDIR}) +endif() + +set(CPACK_SOURCE_GENERATOR TBZ2) +set(CPACK_SOURCE_PACKAGE_FILE_NAME "${TR_NAME}-${TR_USER_AGENT_PREFIX}") +set(CPACK_SOURCE_IGNORE_FILES + \\\\.svn +) + +include(CPack) diff --git a/cli/CMakeLists.txt b/cli/CMakeLists.txt new file mode 100644 index 000000000..0928314d9 --- /dev/null +++ b/cli/CMakeLists.txt @@ -0,0 +1,13 @@ +project(trcli) + +include_directories(${CMAKE_SOURCE_DIR}) + +add_executable(${TR_NAME}-cli cli.c) +include_directories(${TR_NAME}-cli ${CURL_INCLUDE_DIRS}) +target_link_libraries(${TR_NAME}-cli ${TR_NAME}) + +install(TARGETS ${TR_NAME}-cli DESTINATION ${CMAKE_INSTALL_BINDIR}) + +if(INSTALL_DOC) + install(FILES ${TR_NAME}-cli.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) +endif() diff --git a/cmake/FindDHT.cmake b/cmake/FindDHT.cmake new file mode 100644 index 000000000..059292aca --- /dev/null +++ b/cmake/FindDHT.cmake @@ -0,0 +1,34 @@ +if(DHT_PREFER_STATIC_LIB) + set(DHT_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() +endif() + +if(UNIX) + find_package(PkgConfig QUIET) + pkg_check_modules(_DHT QUIET libdht) +endif() + +find_path(DHT_INCLUDE_DIR NAMES dht/dht.h HINTS ${_DHT_INCLUDEDIR}) +find_library(DHT_LIBRARY NAMES dht HINTS ${_DHT_LIBDIR}) + +set(DHT_INCLUDE_DIRS ${DHT_INCLUDE_DIR}) +set(DHT_LIBRARIES ${DHT_LIBRARY}) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(DHT + REQUIRED_VARS + DHT_LIBRARY + DHT_INCLUDE_DIR +) + +mark_as_advanced(DHT_INCLUDE_DIR DHT_LIBRARY) + +if(DHT_PREFER_STATIC_LIB) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${DHT_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) + unset(DHT_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +endif() diff --git a/cmake/FindEVENT2.cmake b/cmake/FindEVENT2.cmake new file mode 100644 index 000000000..254a8a146 --- /dev/null +++ b/cmake/FindEVENT2.cmake @@ -0,0 +1,47 @@ +if(EVENT2_PREFER_STATIC_LIB) + set(EVENT2_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() +endif() + +if(UNIX) + find_package(PkgConfig QUIET) + pkg_check_modules(_EVENT2 QUIET libevent) +endif() + +find_path(EVENT2_INCLUDE_DIR NAMES event2/event.h HINTS ${_EVENT2_INCLUDEDIR}) +find_library(EVENT2_LIBRARY NAMES event HINTS ${_EVENT2_LIBDIR}) + +if(EVENT2_INCLUDE_DIR) + if(_EVENT2_VERSION) + set(EVENT2_VERSION ${_EVENT2_VERSION}) + else() + file(STRINGS "${EVENT2_INCLUDE_DIR}/event2/event-config.h" EVENT2_VERSION_STR REGEX "^#define[\t ]+_EVENT_VERSION[\t ]+\"[^\"]+\"") + if(EVENT2_VERSION_STR MATCHES "\"([^\"]+)\"") + set(EVENT2_VERSION "${CMAKE_MATCH_1}") + endif() + endif() +endif() + +set(EVENT2_INCLUDE_DIRS ${EVENT2_INCLUDE_DIR}) +set(EVENT2_LIBRARIES ${EVENT2_LIBRARY}) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(EVENT2 + REQUIRED_VARS + EVENT2_LIBRARY + EVENT2_INCLUDE_DIR + VERSION_VAR + EVENT2_VERSION +) + +mark_as_advanced(EVENT2_INCLUDE_DIR EVENT2_LIBRARY) + +if(EVENT2_PREFER_STATIC_LIB) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${EVENT2_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) + unset(EVENT2_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +endif() diff --git a/cmake/FindICONV.cmake b/cmake/FindICONV.cmake new file mode 100644 index 000000000..5e81ce141 --- /dev/null +++ b/cmake/FindICONV.cmake @@ -0,0 +1,43 @@ +# Grabbed from http://public.kitware.com/Bug/view.php?id=13517 and slightly modified. + +find_path(ICONV_INCLUDE_DIR iconv.h) +find_library(ICONV_LIBRARY NAMES iconv libiconv libiconv-2 c) + +set(ICONV_INCLUDE_DIRS ${ICONV_INCLUDE_DIR}) +set(ICONV_LIBRARIES ${ICONV_LIBRARY}) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(ICONV + REQUIRED_VARS + ICONV_LIBRARY + ICONV_INCLUDE_DIR + VERSION_VAR + ICONV_VERSION +) + +if(ICONV_FOUND AND NOT DEFINED ICONV_SECOND_ARGUMENT_IS_CONST) + include(CheckCSourceCompiles) + + set(CMAKE_REQUIRED_INCLUDES ${ICONV_INCLUDE_DIRS}) + set(CMAKE_REQUIRED_LIBRARIES ${ICONV_LIBRARIES}) + + check_c_source_compiles( + " + #include + int main () + { + iconv_t conv = 0; + const char * in = 0; + size_t ilen = 0; + char * out = 0; + size_t olen = 0; + iconv (conv, &in, &ilen, &out, &olen); + return 0; + }" ICONV_SECOND_ARGUMENT_IS_CONST) + + set(CMAKE_REQUIRED_INCLUDES) + set(CMAKE_REQUIRED_LIBRARIES) +endif() + +mark_as_advanced(ICONV_INCLUDE_DIR ICONV_LIBRARY ICONV_SECOND_ARGUMENT_IS_CONST) diff --git a/cmake/FindMINIUPNPC.cmake b/cmake/FindMINIUPNPC.cmake new file mode 100644 index 000000000..85410708d --- /dev/null +++ b/cmake/FindMINIUPNPC.cmake @@ -0,0 +1,133 @@ +if(MINIUPNPC_PREFER_STATIC_LIB) + set(MINIUPNPC_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() +endif() + +if(UNIX) + find_package(PkgConfig QUIET) + pkg_check_modules(_MINIUPNPC QUIET libminiupnpc) +endif() + +find_path(MINIUPNPC_INCLUDE_DIR NAMES miniupnpc/miniupnpc.h HINTS ${_MINIUPNPC_INCLUDEDIR}) +find_library(MINIUPNPC_LIBRARY NAMES miniupnpc libminiupnpc HINTS ${_MINIUPNPC_LIBDIR}) + +if(MINIUPNPC_INCLUDE_DIR) + if(_MINIUPNPC_VERSION) + set(MINIUPNPC_VERSION ${_MINIUPNPC_VERSION}) + else() + file(STRINGS "${MINIUPNPC_INCLUDE_DIR}/miniupnpc/miniupnpc.h" MINIUPNPC_VERSION_STR REGEX "^#define[\t ]+MINIUPNPC_VERSION[\t ]+\"[^\"]+\"") + if(MINIUPNPC_VERSION_STR MATCHES "\"([^\"]+)\"") + set(MINIUPNPC_VERSION "${CMAKE_MATCH_1}") + endif() + + # Let's hope it's 1.7 or higher, since it provides + # MINIUPNPC_API_VERSION and we won't have to figure + # it out on our own + file(STRINGS "${MINIUPNPC_INCLUDE_DIR}/miniupnpc/miniupnpc.h" MINIUPNPC_API_VERSION_STR REGEX "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+[0-9]+") + if(MINIUPNPC_API_VERSION_STR MATCHES "^#define[\t ]+MINIUPNPC_API_VERSION[\t ]+([0-9]+)") + set(MINIUPNPC_API_VERSION "${CMAKE_MATCH_1}") + endif() + endif() + + if(MINIUPNPC_LIBRARY) + # Or maybe it's miniupnp 1.6 + if(NOT DEFINED MINIUPNPC_API_VERSION) + file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckMiniUPnPC_1.6.c + " + #include + #include + #include + #include + int main() + { + struct UPNPDev * devlist; + struct UPNPUrls urls; + struct IGDdatas data; + char lanaddr[16]; + char portStr[8]; + char intPort[8]; + char intClient[16]; + upnpDiscover( 2000, NULL, NULL, 0, 0, &errno ); + UPNP_GetValidIGD( devlist, &urls, &data, lanaddr, sizeof( lanaddr ) ); + UPNP_GetSpecificPortMappingEntry( urls.controlURL, data.first.servicetype, + portStr, \"TCP\", intClient, intPort, NULL, NULL, NULL ); + return 0; + } + ") + try_compile(_MINIUPNPC_HAVE_VERSION_1_6 + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckMiniUPnPC_1.6.c + COMPILE_DEFINITIONS -DINCLUDE_DIRECTORIES=${MINIUPNPC_INCLUDE_DIR} + LINK_LIBRARIES ${MINIUPNPC_LIBRARY} + OUTPUT_VARIABLE OUTPUT) + if(_MINIUPNPC_HAVE_VERSION_1_6) + if(NOT DEFINED MINIUPNPC_VERSION) + set(MINIUPNPC_VERSION 1.6) + endif() + set(MINIUPNPC_API_VERSION 8) + endif() + endif() + + # Or maybe it's miniupnp 1.5 + if(NOT DEFINED MINIUPNPC_API_VERSION) + file(WRITE ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckMiniUPnPC_1.5.c + " + #include + #include + #include + int main() + { + struct UPNPDev * devlist; + struct UPNPUrls urls; + struct IGDdatas data; + char lanaddr[16]; + char portStr[8]; + char intPort[8]; + char intClient[16]; + upnpDiscover( 2000, NULL, NULL, 0 ); + UPNP_GetValidIGD( devlist, &urls, &data, lanaddr, sizeof( lanaddr ) ); + UPNP_GetSpecificPortMappingEntry( urls.controlURL, data.first.servicetype, + portStr, \"TCP\", intClient, intPort ); + return 0; + } + ") + try_compile(_MINIUPNPC_HAVE_VERSION_1_5 + ${CMAKE_BINARY_DIR} + ${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/CMakeTmp/CheckMiniUPnPC_1.5.c + COMPILE_DEFINITIONS -DINCLUDE_DIRECTORIES=${MlINIUPNPC_INCLUDE_DIR} + LINK_LIBRARIES ${MINIUPNPC_LIBRARY} + OUTPUT_VARIABLE OUTPUT) + if(_MINIUPNPC_HAVE_VERSION_1_5) + if(NOT DEFINED MINIUPNPC_VERSION) + set(MINIUPNPC_VERSION 1.5) + endif() + set(MINIUPNPC_API_VERSION 5) + endif() + endif() + endif() +endif() + +set(MINIUPNPC_INCLUDE_DIRS ${MINIUPNPC_INCLUDE_DIR}) +set(MINIUPNPC_LIBRARIES ${MINIUPNPC_LIBRARY}) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(MINIUPNPC + REQUIRED_VARS + MINIUPNPC_LIBRARY + MINIUPNPC_INCLUDE_DIR + MINIUPNPC_API_VERSION + VERSION_VAR + MINIUPNPC_VERSION +) + +mark_as_advanced(MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY) + +if(MINIUPNPC_PREFER_STATIC_LIB) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${MINIUPNPC_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) + unset(MINIUPNPC_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +endif() diff --git a/cmake/FindNATPMP.cmake b/cmake/FindNATPMP.cmake new file mode 100644 index 000000000..abac825ce --- /dev/null +++ b/cmake/FindNATPMP.cmake @@ -0,0 +1,34 @@ +if(NATPMP_PREFER_STATIC_LIB) + set(NATPMP_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() +endif() + +if(UNIX) + find_package(PkgConfig QUIET) + pkg_check_modules(_NATPMP QUIET libnatpmp) +endif() + +find_path(NATPMP_INCLUDE_DIR NAMES natpmp.h HINTS ${_NATPMP_INCLUDEDIR}) +find_library(NATPMP_LIBRARY NAMES natpmp HINTS ${_NATPMP_LIBDIR}) + +set(NATPMP_INCLUDE_DIRS ${NATPMP_INCLUDE_DIR}) +set(NATPMP_LIBRARIES ${NATPMP_LIBRARY}) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(NATPMP + REQUIRED_VARS + NATPMP_LIBRARY + NATPMP_INCLUDE_DIR +) + +mark_as_advanced(NATPMP_INCLUDE_DIR NATPMP_LIBRARY) + +if(NATPMP_PREFER_STATIC_LIB) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${NATPMP_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) + unset(NATPMP_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +endif() diff --git a/cmake/FindUTP.cmake b/cmake/FindUTP.cmake new file mode 100644 index 000000000..1f749d0b9 --- /dev/null +++ b/cmake/FindUTP.cmake @@ -0,0 +1,34 @@ +if(UTP_PREFER_STATIC_LIB) + set(UTP_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .a .lib ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + endif() +endif() + +if(UNIX) + find_package(PkgConfig QUIET) + pkg_check_modules(_UTP QUIET libutp) +endif() + +find_path(UTP_INCLUDE_DIR NAMES libutp/utp.h HINTS ${_UTP_INCLUDEDIR}) +find_library(UTP_LIBRARY NAMES utp HINTS ${_UTP_LIBDIR}) + +set(UTP_INCLUDE_DIRS ${UTP_INCLUDE_DIR}) +set(UTP_LIBRARIES ${UTP_LIBRARY}) + +include(FindPackageHandleStandardArgs) + +find_package_handle_standard_args(UTP + REQUIRED_VARS + UTP_LIBRARY + UTP_INCLUDE_DIR +) + +mark_as_advanced(UTP_INCLUDE_DIR UTP_LIBRARY) + +if(UTP_PREFER_STATIC_LIB) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${UTP_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) + unset(UTP_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES) +endif() diff --git a/cmake/TrMacros.cmake b/cmake/TrMacros.cmake new file mode 100644 index 000000000..f1f7ef36b --- /dev/null +++ b/cmake/TrMacros.cmake @@ -0,0 +1,77 @@ +macro(tr_auto_option_changed NAME ACC VAL FIL STK) + if(NOT ("${VAL}" STREQUAL "AUTO" OR "${VAL}" STREQUAL "ON" OR "${VAL}" STREQUAL "OFF")) + if("${VAL}" STREQUAL "0" OR "${VAL}" STREQUAL "NO" OR "${VAL}" STREQUAL "FALSE" OR "${VAL}" STREQUAL "N") + set_property(CACHE ${NAME} PROPERTY VALUE OFF) + elseif("${VAL}" MATCHES "^[-+]?[0-9]+$" OR "${VAL}" STREQUAL "YES" OR "${VAL}" STREQUAL "TRUE" OR "${VAL}" STREQUAL "Y") + set_property(CACHE ${NAME} PROPERTY VALUE ON) + else() + message(FATAL_ERROR "Option '${NAME}' set to unrecognized value '${VAL}'. Should be boolean or 'AUTO'.") + endif() + endif() +endmacro() + +macro(tr_auto_option NAME DESC VAL) + set(${NAME} "${VAL}" CACHE STRING "${DESC}") + set_property(CACHE ${NAME} PROPERTY STRINGS "AUTO;ON;OFF") + variable_watch(${NAME} tr_auto_option_changed) +endmacro() + +macro(tr_fixup_auto_option NAME ISFOUND ISREQ) + if(${ISFOUND}) + set_property(CACHE ${NAME} PROPERTY VALUE ON) + elseif(NOT (${ISREQ})) + set_property(CACHE ${NAME} PROPERTY VALUE OFF) + endif() +endmacro() + +macro(tr_get_required_flag IVAR OVAR) + set(${OVAR}) + if (${IVAR} AND NOT ${IVAR} STREQUAL "AUTO") + set(${OVAR} REQUIRED) + endif() +endmacro() + +function(tr_make_id INPUT OVAR) + string(TOUPPER "${INPUT}" ID) + string(REGEX REPLACE "[^A-Z0-9]+" "_" ID "${ID}") + string(REGEX REPLACE "^_+|_+$" "" ID "${ID}") + set(${OVAR} "${ID}" PARENT_SCOPE) +endfunction() + +macro(tr_github_upstream ID REPOID RELID RELMD5) + set(${ID}_RELEASE "${RELID}") + set(${ID}_UPSTREAM URL "https://github.com/${REPOID}/archive/${RELID}.tar.gz" URL_MD5 "${RELMD5}") +endmacro() + +macro(tr_add_external_auto_library ID LIBNAME) + if(USE_SYSTEM_${ID}) + tr_get_required_flag(USE_SYSTEM_${ID} SYSTEM_${ID}_IS_REQUIRED) + find_package(${ID} ${${ID}_MINIMUM} ${SYSTEM_${ID}_IS_REQUIRED}) + tr_fixup_auto_option(USE_SYSTEM_${ID} ${ID}_FOUND SYSTEM_${ID}_IS_REQUIRED) + endif() + + if(USE_SYSTEM_${ID}) + unset(${ID}_UPSTREAM_TARGET) + else() + set(${ID}_UPSTREAM_TARGET ${LIBNAME}-${${ID}_RELEASE}) + set(${ID}_PREFIX "${CMAKE_BINARY_DIR}/third-party/${${ID}_UPSTREAM_TARGET}") + + ExternalProject_Add( + ${${ID}_UPSTREAM_TARGET} + ${${ID}_UPSTREAM} + ${ARGN} + PREFIX "${${ID}_PREFIX}" + CMAKE_ARGS + "-DCMAKE_C_FLAGS:STRING=${CMAKE_C_FLAGS}" + "-DCMAKE_CXX_FLAGS:STRING=${CMAKE_CXX_FLAGS}" + "-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}" + "-DCMAKE_INSTALL_PREFIX:PATH=" + ) + + set(${ID}_INCLUDE_DIR "${${ID}_PREFIX}/include" CACHE INTERNAL "") + set(${ID}_LIBRARY "${${ID}_PREFIX}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}${LIBNAME}${CMAKE_STATIC_LIBRARY_SUFFIX}" CACHE INTERNAL "") + + set(${ID}_INCLUDE_DIRS ${${ID}_INCLUDE_DIR}) + set(${ID}_LIBRARIES ${${ID}_LIBRARY}) + endif() +endmacro() diff --git a/daemon/CMakeLists.txt b/daemon/CMakeLists.txt new file mode 100644 index 000000000..bce61b6ca --- /dev/null +++ b/daemon/CMakeLists.txt @@ -0,0 +1,53 @@ +project(trdaemon) + +if(WITH_INOTIFY) + add_definitions(-DWITH_INOTIFY) +endif() + +if(WITH_KQUEUE) + add_definitions(-DWITH_KQUEUE) +endif() + +if(WITH_SYSTEMD) + add_definitions(-DUSE_SYSTEMD_DAEMON) +endif() + +include_directories( + ${CMAKE_SOURCE_DIR} + ${EVENT2_INCLUDE_DIRS} +) + +add_executable(${TR_NAME}-daemon + daemon.c + watch.c + watch.h +) + +set_target_properties(${TR_NAME}-daemon PROPERTIES + COMPILE_FLAGS "${SYSTEMD_DAEMON_CFLAGS}" + LINK_FLAGS "${SYSTEMD_DAEMON_LDFLAGS}" +) + +target_link_libraries(${TR_NAME}-daemon + ${TR_NAME} + ${EVENT2_LIBRARIES} +) + +add_executable(${TR_NAME}-remote remote.c) + +target_include_directories(${TR_NAME}-remote PRIVATE + ${CURL_INCLUDE_DIRS} +) + +target_link_libraries(${TR_NAME}-remote + ${TR_NAME} + ${CURL_LIBRARIES} +) + +foreach(P daemon remote) + install(TARGETS ${TR_NAME}-${P} DESTINATION ${CMAKE_INSTALL_BINDIR}) + + if(INSTALL_DOC) + install(FILES ${TR_NAME}-${P}.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + endif() +endforeach() diff --git a/gtk/CMakeLists.txt b/gtk/CMakeLists.txt new file mode 100644 index 000000000..21bceda85 --- /dev/null +++ b/gtk/CMakeLists.txt @@ -0,0 +1,178 @@ +project(trgtk) + +if(WITH_LIBAPPINDICATOR) + add_definitions(-DHAVE_LIBAPPINDICATOR) +endif() + +execute_process( + COMMAND + ${PKG_CONFIG_EXECUTABLE} gio-2.0 --variable glib_compile_resources + OUTPUT_VARIABLE + GLIB_COMPILE_RESOURCES_EXECUTABLE + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +if(NOT GLIB_COMPILE_RESOURCES_EXECUTABLE) + message(SEND_ERROR "Unable to find glib-compile-resources executable") +endif() + +add_custom_command( + OUTPUT + ${CMAKE_CURRENT_BINARY_DIR}/transmission-resources.c + ${CMAKE_CURRENT_BINARY_DIR}/transmission-resources.h + COMMAND + ${GLIB_COMPILE_RESOURCES_EXECUTABLE} + --target=${CMAKE_CURRENT_BINARY_DIR}/transmission-resources.c + --sourcedir=${CMAKE_CURRENT_SOURCE_DIR} + --generate-source + --c-name transmission + transmission.gresource.xml + COMMAND + ${GLIB_COMPILE_RESOURCES_EXECUTABLE} + --target=${CMAKE_CURRENT_BINARY_DIR}/transmission-resources.h + --sourcedir=${CMAKE_CURRENT_SOURCE_DIR} + --generate-header + --c-name transmission + transmission.gresource.xml + DEPENDS + transmission.gresource.xml + transmission-ui.xml + WORKING_DIRECTORY + ${CMAKE_CURRENT_SOURCE_DIR} +) + +if(ENABLE_NLS) + find_program(INTLTOOL_MERGE_EXECUTABLE intltool-merge REQUIRED) + set(${PROJECT_NAME}_DESKTOP_FILE "${PROJECT_BINARY_DIR}/${TR_NAME}-gtk.desktop") + add_custom_command( + OUTPUT ${${PROJECT_NAME}_DESKTOP_FILE} + COMMAND ${INTLTOOL_MERGE_EXECUTABLE} --desktop-style --utf8 ${CMAKE_SOURCE_DIR}/po ${PROJECT_SOURCE_DIR}/transmission-gtk.desktop.in ${${PROJECT_NAME}_DESKTOP_FILE} + DEPENDS ${PROJECT_SOURCE_DIR}/transmission-gtk.desktop.in + VERBATIM + ) +endif() + +set(${PROJECT_NAME}_SOURCES + actions.c + conf.c + details.c + dialogs.c + favicon.c + file-list.c + filter.c + hig.c + icons.c + main.c + makemeta-ui.c + msgwin.c + notify.c + open-dialog.c + relocate.c + stats.c + torrent-cell-renderer.c + tr-core.c + tr-icon.c + tr-prefs.c + tr-window.c + util.c + ${CMAKE_CURRENT_BINARY_DIR}/transmission-resources.c +) + +set(${PROJECT_NAME}_HEADERS + actions.h + conf.h + details.h + dialogs.h + favicon.h + file-list.h + filter.h + hig.h + icon-lock.h + icon-logo-24.h + icon-logo-48.h + icon-ratio.h + icons.h + icon-turtle.h + icon-utilities.h + makemeta-ui.h + msgwin.h + notify.h + open-dialog.h + relocate.h + stats.h + torrent-cell-renderer.h + tr-core.h + tr-icon.h + tr-prefs.h + tr-window.h + util.h + ${CMAKE_CURRENT_BINARY_DIR}/transmission-resources.h +) + +include_directories( + ${CMAKE_SOURCE_DIR} + ${PROJECT_BINARY_DIR} + ${GTK_INCLUDE_DIRS} + ${CURL_INCLUDE_DIRS} +) + +link_directories( + ${GTK_LIBRARY_DIRS} +) + +add_definitions( + "-DTRANSMISSIONLOCALEDIR=\"${CMAKE_INSTALL_FULL_LOCALEDIR}\"" + "-DGETTEXT_PACKAGE=\"${TR_NAME}-gtk\"" + -DG_DISABLE_DEPRECATED + -DGDK_PIXBUF_DISABLE_DEPRECATED + -DGDK_DISABLE_DEPRECATED + # FIXME: migrate from GtkUIManager to GtkBuilder in 2.90 + # -DGTK_DISABLE_DEPRECATED + -DPANGO_DISABLE_DEPRECATED + # FIXME: these break libnotify's headers + # -DG_DISABLE_SINGLE_INCLUDES + # -DGTK_DISABLE_SINGLE_INCLUDES + ${GTK_CFLAGS_OTHER} +) + +add_executable(${TR_NAME}-gtk + ${${PROJECT_NAME}_SOURCES} + ${${PROJECT_NAME}_HEADERS} + ${${PROJECT_NAME}_DESKTOP_FILE} +) + +target_link_libraries(${TR_NAME}-gtk + ${TR_NAME} + ${GTK_LIBRARIES} + ${CURL_LIBRARIES} + ${EVENT2_LIBRARIES} +) + +install(TARGETS ${TR_NAME}-gtk DESTINATION ${CMAKE_INSTALL_BINDIR}) + +set(${PROJECT_NAME}_PUBLIC_ICONS + hicolor_apps_16x16_transmission.png + hicolor_apps_22x22_transmission.png + hicolor_apps_24x24_transmission.png + hicolor_apps_32x32_transmission.png + hicolor_apps_48x48_transmission.png + hicolor_apps_256x256_transmission.png + hicolor_apps_scalable_transmission.svg +) + +set(ICON_NAME_REGEX "^([^_]+)_([^_]+)_([^_]+)_(.+)$") +foreach(ICON ${${PROJECT_NAME}_PUBLIC_ICONS}) + string(REGEX REPLACE ${ICON_NAME_REGEX} "\\1/\\3/\\2" ICON_DIR ${ICON}) + string(REGEX REPLACE ${ICON_NAME_REGEX} "\\4" ICON_NAME ${ICON}) + install(FILES icons/${ICON} DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/${ICON_DIR}/ RENAME ${ICON_NAME}) +endforeach() + +if(INSTALL_DOC) + install(FILES ${TR_NAME}-gtk.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) +endif() + +if(ENABLE_NLS) + install(FILES ${${PROJECT_NAME}_DESKTOP_FILE} DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) +else() + install(FILES transmission-gtk.desktop.in DESTINATION ${CMAKE_INSTALL_DATADIR}/applications RENAME ${TR_NAME}-gtk.desktop) +endif() diff --git a/libtransmission/CMakeLists.txt b/libtransmission/CMakeLists.txt new file mode 100644 index 000000000..f987f99ec --- /dev/null +++ b/libtransmission/CMakeLists.txt @@ -0,0 +1,226 @@ +project(libtr) + +configure_file(version.h.in version.h) + +set(${PROJECT_NAME}_SOURCES + announcer.c + announcer-http.c + announcer-udp.c + bandwidth.c + bitfield.c + blocklist.c + cache.c + clients.c + completion.c + ConvertUTF.c + crypto.c + error.c + fdlimit.c + file.c + handshake.c + history.c + inout.c + list.c + log.c + magnet.c + makemeta.c + metainfo.c + natpmp.c + net.c + peer-io.c + peer-mgr.c + peer-msgs.c + platform.c + platform-quota.c + port-forwarding.c + ptrarray.c + quark.c + resume.c + rpcimpl.c + rpc-server.c + session.c + stats.c + torrent.c + torrent-ctor.c + torrent-magnet.c + tr-dht.c + trevent.c + tr-getopt.c + tr-lpd.c + tr-udp.c + upnp.c + utils.c + variant-benc.c + variant.c + variant-json.c + verify.c + web.c + webseed.c + wildmat.c +) + +if(WIN32) + list(APPEND ${PROJECT_NAME}_SOURCES file-win32.c) +else() + list(APPEND ${PROJECT_NAME}_SOURCES file-posix.c) +endif() + +set(${PROJECT_NAME}_PUBLIC_HEADERS + error.h + file.h + log.h + makemeta.h + quark.h + rpcimpl.h + tr-getopt.h + transmission.h + utils.h + variant.h + web.h + ${PROJECT_BINARY_DIR}/version.h +) + +set(${PROJECT_NAME}_PRIVATE_HEADERS + announcer-common.h + announcer.h + bandwidth.h + bitfield.h + blocklist.h + cache.h + clients.h + completion.h + ConvertUTF.h + crypto.h + fdlimit.h + handshake.h + history.h + inout.h + list.h + magnet.h + metainfo.h + natpmp_local.h + net.h + peer-common.h + peer-io.h + peer-mgr.h + peer-msgs.h + platform.h + platform-quota.h + port-forwarding.h + ptrarray.h + resume.h + rpc-server.h + session.h + stats.h + torrent.h + torrent-magnet.h + tr-dht.h + trevent.h + tr-lpd.h + tr-udp.h + upnp.h + variant-common.h + verify.h + version.h + webseed.h +) + +if(ENABLE_UTP) + list(APPEND ${PROJECT_NAME}_SOURCES tr-utp.c) + list(APPEND ${PROJECT_NAME}_PRIVATE_HEADERS tr-utp.h) +endif() + +add_definitions( + -D__TRANSMISSION__ + "-DPACKAGE_DATA_DIR=\"${CMAKE_INSTALL_FULL_DATAROOTDIR}\"" + ${NATPMP_DEFINITIONS} + ${MINIUPNPC_DEFINITIONS} +) + +if(ENABLE_LIGHTWEIGHT) + add_definitions(-DTR_LIGHTWEIGHT) +endif() + +if(NOT ENABLE_NLS) + add_definitions(-DDISABLE_GETTEXT) +endif() + +if(ENABLE_UTP) + add_definitions(-DWITH_UTP) +endif() + +if(MINIUPNPC_VERSION VERSION_LESS 1.7) + # API version macro was only added in 1.7 + add_definitions(-DMINIUPNPC_API_VERSION=${MINIUPNPC_API_VERSION}) +endif() + +include_directories( + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} + ${ZLIB_INCLUDE_DIRS} + ${OPENSSL_INCLUDE_DIRS} + ${CURL_INCLUDE_DIRS} + ${ICONV_INCLUDE_DIRS} + ${EVENT2_INCLUDE_DIRS} + ${NATPMP_INCLUDE_DIRS} + ${MINIUPNPC_INCLUDE_DIRS} + ${DHT_INCLUDE_DIRS} + ${UTP_INCLUDE_DIRS} +) + +if(ENABLE_UTP) + include_directories(${TP_TOP}/libutp) +endif() + +add_library(${TR_NAME} STATIC + ${${PROJECT_NAME}_SOURCES} + ${${PROJECT_NAME}_PUBLIC_HEADERS} + ${${PROJECT_NAME}_PRIVATE_HEADERS} +) + +foreach(UT ${EVENT2_UPSTREAM_TARGET} + ${NATPMP_UPSTREAM_TARGET} + ${MINIUPNPC_UPSTREAM_TARGET} + ${DHT_UPSTREAM_TARGET} + ${UTP_UPSTREAM_TARGET}) + add_dependencies(${TR_NAME} ${UT}) +endforeach() + +target_link_libraries(${TR_NAME} + ${CMAKE_THREAD_LIBS_INIT} + ${ZLIB_LIBRARIES} + ${OPENSSL_LIBRARIES} + ${CURL_LIBRARIES} + ${ICONV_LIBRARIES} + ${EVENT2_LIBRARIES} + ${NATPMP_LIBRARIES} + ${MINIUPNPC_LIBRARIES} + ${DHT_LIBRARIES} + ${UTP_LIBRARIES} + ${LIBM_LIBRARY} +) + +if(WIN32) + target_link_libraries(${TR_NAME} iphlpapi ws2_32) +endif() + +if(ENABLE_TESTS) + add_library(${TR_NAME}-test STATIC + libtransmission-test.c + libtransmission-test.h + ) + + target_link_libraries(${TR_NAME}-test ${TR_NAME}) + + foreach(T bitfield blocklist clients crypto error file history json magnet metainfo move peer-msgs quark rename rpc session tr-getopt utils variant) + set(TP ${TR_NAME}-test-${T}) + add_executable(${TP} ${T}-test.c) + target_link_libraries(${TP} ${TR_NAME} ${TR_NAME}-test) + add_test(${T} ${TP}) + endforeach() +endif() + +if(INSTALL_LIB) + install(TARGETS ${TR_NAME} DESTINATION ${CMAKE_INSTALL_LIBDIR}) + install(FILES ${${PROJECT_NAME}_PUBLIC_HEADERS} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${TR_NAME}) +endif() diff --git a/libtransmission/version.h.in b/libtransmission/version.h.in new file mode 100644 index 000000000..78d3e1832 --- /dev/null +++ b/libtransmission/version.h.in @@ -0,0 +1,18 @@ +#ifndef TR_VERSION_H +#define TR_VERSION_H + +#define PEERID_PREFIX "${TR_PEER_ID_PREFIX}" +#define USERAGENT_PREFIX "${TR_USER_AGENT_PREFIX}" +#define SVN_REVISION "${TR_SCM_REVISION}" +#define SVN_REVISION_NUM ${TR_SCM_REVISION} +#define SHORT_VERSION_STRING "${TR_USER_AGENT_PREFIX}" +#define LONG_VERSION_STRING "${TR_USER_AGENT_PREFIX} (${TR_SCM_REVISION})" +#define VERSION_STRING_INFOPLIST ${TR_USER_AGENT_PREFIX} +#define MAJOR_VERSION ${TR_VERSION_MAJOR} +#define MINOR_VERSION ${TR_VERSION_MINOR} + +#cmakedefine TR_BETA_RELEASE 1 +#cmakedefine TR_NIGHTLY_RELEASE 1 +#cmakedefine TR_STABLE_RELEASE 1 + +#endif /* TR_VERSION_H */ diff --git a/po/CMakeLists.txt b/po/CMakeLists.txt new file mode 100644 index 000000000..83af8f7b7 --- /dev/null +++ b/po/CMakeLists.txt @@ -0,0 +1,127 @@ +project(trpo) + +set(${PROJECT_NAME}_LINGUAS + an + ar + ast + az + be + be@latin + bg + bn + bo + br + bs + ca + ca@valencia + ceb + ckb + cs + da + de + el + en_AU + en_CA + en_GB + eo + es + et + eu + fa + fi + fil + fo + fr + ga + gl + gv + he + hi + hr + hu + hy + ia + id + is + it + ja + ka + kk + ko + ku + ky + li + lt + lv + mk + ml + mr + ms + mt + my + nb + nds + nl + nn + oc + pa + pl + pt + pt_BR + ro + ru + si + sk + sl + sq + sr + sv + sw + ta_LK + te + th + tl + tr + ur + ug + uk + uz + vi + zh_CN + zh_TW +) + +set(GETTEXT_PACKAGE ${TR_NAME}-gtk) + +if(ENABLE_NLS) + set(${PROJECT_NAME}_ENABLED_LINGUAS ${${PROJECT_NAME}_LINGUAS}) +else() + set(${PROJECT_NAME}_ENABLED_LINGUAS) +endif() + +set(${PROJECT_NAME}_MO_FILES) +foreach(LANG ${${PROJECT_NAME}_ENABLED_LINGUAS}) + set(msgfmt_INPUT_FILE ${LANG}.po) + set(msgfmt_OUTPUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/${GETTEXT_PACKAGE}-${LANG}.mo) + + add_custom_command( + OUTPUT + ${msgfmt_OUTPUT_FILE} + COMMAND + ${GETTEXT_MSGFMT_EXECUTABLE} + --output-file=${msgfmt_OUTPUT_FILE} + ${msgfmt_INPUT_FILE} + WORKING_DIRECTORY + ${CMAKE_CURRENT_SOURCE_DIR} + DEPENDS + ${msgfmt_INPUT_FILE} + ) + + list(APPEND ${PROJECT_NAME}_MO_FILES ${msgfmt_OUTPUT_FILE}) + + install(FILES ${msgfmt_OUTPUT_FILE} DESTINATION ${CMAKE_INSTALL_LOCALEDIR}/${LANG}/LC_MESSAGES/ RENAME ${GETTEXT_PACKAGE}.mo) +endforeach() + +if(${PROJECT_NAME}_MO_FILES) + add_custom_target(${GETTEXT_PACKAGE}-po ALL DEPENDS ${${PROJECT_NAME}_MO_FILES}) +endif() diff --git a/qt/CMakeLists.txt b/qt/CMakeLists.txt new file mode 100644 index 000000000..b916a770b --- /dev/null +++ b/qt/CMakeLists.txt @@ -0,0 +1,174 @@ +project(trqt) + +if(USE_QT5) + macro(tr_qt_wrap_ui) + qt5_wrap_ui(${ARGN}) + endmacro() + macro(tr_qt_add_resources) + qt5_add_resources(${ARGN}) + endmacro() + macro(tr_qt_add_translation) + qt5_add_translation(${ARGN}) + endmacro() +else() + include(${QT_USE_FILE}) + + macro(tr_qt_wrap_ui) + qt4_wrap_ui(${ARGN}) + endmacro() + macro(tr_qt_add_resources) + qt4_add_resources(${ARGN}) + endmacro() + macro(tr_qt_add_translation) + qt4_add_translation(${ARGN}) + endmacro() +endif() + +set(${PROJECT_NAME}_SOURCES + about.cc + add-data.cc + app.cc + dbus-adaptor.cc + details.cc + favicon.cc + file-tree.cc + filterbar.cc + filters.cc + formatter.cc + freespace-label.cc + hig.cc + license.cc + mainwin.cc + make-dialog.cc + options.cc + prefs-dialog.cc + prefs.cc + relocate.cc + session-dialog.cc + session.cc + squeezelabel.cc + stats-dialog.cc + torrent-delegate-min.cc + torrent-delegate.cc + torrent-filter.cc + torrent-model.cc + torrent.cc + tracker-delegate.cc + tracker-model-filter.cc + tracker-model.cc + triconpushbutton.cc + utils.cc + watchdir.cc +) + +set(${PROJECT_NAME}_HEADERS + about.h + add-data.h + app.h + dbus-adaptor.h + details.h + favicon.h + file-tree.h + filterbar.h + filters.h + formatter.h + freespace-label.h + hig.h + license.h + mainwin.h + make-dialog.h + options.h + prefs-dialog.h + prefs.h + relocate.h + session-dialog.h + session.h + speed.h + squeezelabel.h + stats-dialog.h + torrent-delegate-min.h + torrent-delegate.h + torrent-filter.h + torrent-model.h + torrent.h + tracker-delegate.h + tracker-model-filter.h + tracker-model.h + triconpushbutton.h + types.h + utils.h + watchdir.h +) + +tr_qt_wrap_ui(${PROJECT_NAME}_UI_SOURCES + mainwin.ui +) + +tr_qt_add_resources(${PROJECT_NAME}_QRC_SOURCES + application.qrc +) + +set(${PROJECT_NAME}_LINGUAS + en + es + eu + fr + hu + kk + lt + pt_BR + ru + uk +) + +if(ENABLE_NLS) + set(${PROJECT_NAME}_ENABLED_LINGUAS ${${PROJECT_NAME}_LINGUAS}) +else() + set(${PROJECT_NAME}_ENABLED_LINGUAS) +endif() + +set(${PROJECT_NAME}_TS_FILES) +foreach(LANG ${${PROJECT_NAME}_ENABLED_LINGUAS}) + list(APPEND ${PROJECT_NAME}_TS_FILES translations/transmission_${LANG}.ts) +endforeach() + +if(${PROJECT_NAME}_TS_FILES) + tr_qt_add_translation(${PROJECT_NAME}_QM_FILES ${${PROJECT_NAME}_TS_FILES}) +endif() + +include_directories( + ${CMAKE_SOURCE_DIR} + ${PROJECT_SOURCE_DIR} + ${PROJECT_BINARY_DIR} + ${CURL_INCLUDE_DIRS} + ${EVENT2_INCLUDE_DIRS} +) + +add_executable(${TR_NAME}-qt + ${${PROJECT_NAME}_SOURCES} + ${${PROJECT_NAME}_UI_SOURCES} + ${${PROJECT_NAME}_QRC_SOURCES} + ${${PROJECT_NAME}_HEADERS} + ${${PROJECT_NAME}_QM_FILES} +) + +target_link_libraries(${TR_NAME}-qt + ${TR_NAME} + ${QT_LIBRARIES} + ${CURL_LIBRARIES} + ${EVENT2_LIBRARIES} +) + +if(USE_QT5) + qt5_use_modules(${TR_NAME}-qt ${TR_QT5_MODULES}) +endif() + +set_target_properties(${TR_NAME}-qt PROPERTIES AUTOMOC TRUE) + +install(TARGETS ${TR_NAME}-qt DESTINATION ${CMAKE_INSTALL_BINDIR}) + +if(INSTALL_DOC) + install(FILES ${TR_NAME}-qt.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) +endif() + +install(FILES transmission-qt.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications) diff --git a/third-party/dht.cmake b/third-party/dht.cmake new file mode 100644 index 000000000..6d4aa99bd --- /dev/null +++ b/third-party/dht.cmake @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 2.8) +project(dht C) + +add_library(${PROJECT_NAME} STATIC + dht.c +) + +install(TARGETS ${PROJECT_NAME} DESTINATION lib) +install(FILES dht.h DESTINATION include/dht) diff --git a/third-party/event2.cmake b/third-party/event2.cmake new file mode 100644 index 000000000..e4be55013 --- /dev/null +++ b/third-party/event2.cmake @@ -0,0 +1,41 @@ +cmake_minimum_required(VERSION 2.8) +project(event C) + +set(${PROJECT_NAME}_ADD_SOURCES + win32select.c + evthread_win32.c + buffer_iocp.c + event_iocp.c + bufferevent_async.c +) + +add_definitions(-DHAVE_CONFIG_H) + +include_directories(include compat WIN32-Code) + +add_library(${PROJECT_NAME} STATIC + event.c + buffer.c + bufferevent.c + bufferevent_sock.c + bufferevent_pair.c + listener.c + evmap.c + log.c + evutil.c + strlcpy.c + signal.c + bufferevent_filter.c + evthread.c + bufferevent_ratelim.c + evutil_rand.c + event_tagging.c + http.c + evdns.c + evrpc.c + ${${PROJECT_NAME}_ADD_SOURCES} +) + +install(TARGETS ${PROJECT_NAME} DESTINATION lib) +install(DIRECTORY include/event2 DESTINATION include) +install(DIRECTORY WIN32-Code/event2 DESTINATION include) diff --git a/third-party/natpmp.cmake b/third-party/natpmp.cmake new file mode 100644 index 000000000..fbfad30af --- /dev/null +++ b/third-party/natpmp.cmake @@ -0,0 +1,19 @@ +cmake_minimum_required(VERSION 2.8) +project(natpmp C) + +add_definitions(-DNATPMP_STATICLIB -DENABLE_STRNATPMPERR) + +if(WIN32) + set(${PROJECT_NAME}_ADD_SOURCES + wingettimeofday.c + ) +endif() + +add_library(${PROJECT_NAME} STATIC + getgateway.c + natpmp.c + ${${PROJECT_NAME}_ADD_SOURCES} +) + +install(TARGETS ${PROJECT_NAME} DESTINATION lib) +install(FILES declspec.h natpmp.h DESTINATION include) diff --git a/third-party/utp.cmake b/third-party/utp.cmake new file mode 100644 index 000000000..b68a3f6fe --- /dev/null +++ b/third-party/utp.cmake @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 2.8) +project(utp CXX) + +if(WIN32) + set(${PROJECT_NAME}_ADD_SOURCES + win32_inet_ntop.cpp + ) +else() + add_definitions(-DPOSIX) +endif() + +include_directories(.) + +add_library(${PROJECT_NAME} STATIC + utp.cpp + utp_utils.cpp + ${${PROJECT_NAME}_ADD_SOURCES} +) + +install(TARGETS ${PROJECT_NAME} DESTINATION lib) +install(FILES utp.h utypes.h DESTINATION include/libutp) diff --git a/third-party/utp_config.h b/third-party/utp_config.h new file mode 100644 index 000000000..01d6ba07e --- /dev/null +++ b/third-party/utp_config.h @@ -0,0 +1,39 @@ +#define CCONTROL_TARGET (100 * 1000) // us +#define RATE_CHECK_INTERVAL 10000 // ms +#define DYNAMIC_PACKET_SIZE_ENABLED false +#define DYNAMIC_PACKET_SIZE_FACTOR 2 +// This should return the global number of bytes sent, used for determining dynamic +// packet size based on rate + +#warning implement this in libtransmission +uint64 UTP_GetGlobalUTPBytesSent(const struct sockaddr *remote, socklen_t remotelen) { return 0; } + +enum bandwidth_type_t { + payload_bandwidth, connect_overhead, + close_overhead, ack_overhead, + header_overhead, retransmit_overhead +}; + +#ifdef _WIN32 +#define I64u "%I64u" +#else +#define I64u "%Lu" +#endif +#ifdef _WIN32 +#define snprintf _snprintf +#endif + +#define g_log_utp 0 +#define g_log_utp_verbose 0 +void utp_log(char const* fmt, ...) +{ + /* + printf("[%u] ", UTP_GetMilliseconds()); + va_list vl; + va_start(vl, fmt); + vprintf(fmt, vl); + va_end(vl); + puts(""); + fflush(stdout); + */ +}; diff --git a/utils/CMakeLists.txt b/utils/CMakeLists.txt new file mode 100644 index 000000000..37eace9f7 --- /dev/null +++ b/utils/CMakeLists.txt @@ -0,0 +1,15 @@ +project(trutils) + +include_directories(${CMAKE_SOURCE_DIR}) + +foreach(P create edit show) + add_executable(${TR_NAME}-${P} ${P}.c) + include_directories(${TR_NAME}-${P} ${EVENT2_INCLUDE_DIRS} ${CURL_INCLUDE_DIRS}) + target_link_libraries(${TR_NAME}-${P} ${TR_NAME}) + + install(TARGETS ${TR_NAME}-${P} DESTINATION ${CMAKE_INSTALL_BINDIR}) + + if(INSTALL_DOC) + install(FILES ${TR_NAME}-${P}.1 DESTINATION ${CMAKE_INSTALL_MANDIR}/man1) + endif() +endforeach()