diff --git a/cmake/modules/FindMiniUPnPc.cmake b/cmake/modules/FindMiniUPnPc.cmake new file mode 100644 --- /dev/null +++ b/cmake/modules/FindMiniUPnPc.cmake @@ -0,0 +1,45 @@ +# Try to find libminiupnpc +# MINIUPNPC_FOUND - system has libminiupnpc +# MINIUPNPC_INCLUDE_DIR - the libminiupnpc include directory +# MINIUPNPC_LIBRARY - Library needed to use libminiupnpc + +if (MINIUPNPC_INCLUDE_DIR AND MINIUPNPC_LIBRARY) + # Already in cache, be silent + set(MINIUPNPC_FIND_QUIETLY TRUE) +endif() + +find_path(MINIUPNPC_INCLUDE_DIR miniupnpc/miniupnpc.h) + +set(MINIUPNPC_REQUIRED_HEADERS + miniupnpc/miniwget.h + miniupnpc/upnpcommands.h + miniupnpc/upnperrors.h +) + +include(SanitizeHelper) +set(CMAKE_REQUIRED_INCLUDES ${MINIUPNPC_INCLUDE_DIR}) +foreach(_miniupnpc_header ${MINIUPNPC_REQUIRED_HEADERS}) + sanitize_variable(HAVE_MINIUPNPC_ ${_miniupnpc_header} HEADER_FOUND) + check_include_files(${_miniupnpc_header} ${HEADER_FOUND}) + if(NOT ${HEADER_FOUND}) + set(MINIUPNPC_MISSING_HEADER ON) + endif() +endforeach() + +if(NOT MINIUPNPC_MISSING_HEADER) + find_library(MINIUPNPC_LIBRARY NAMES miniupnpc libminiupnpc) + + message(STATUS "MiniUPnPc lib: " ${MINIUPNPC_LIBRARY}) + + include(FindPackageHandleStandardArgs) + find_package_handle_standard_args( + MiniUPnPc DEFAULT_MSG + MINIUPNPC_INCLUDE_DIR + MINIUPNPC_LIBRARY + ) + + mark_as_advanced(MINIUPNPC_INCLUDE_DIR MINIUPNPC_LIBRARY) + + set(MiniUPnPc_LIBRARIES ${MINIUPNPC_LIBRARY}) + set(MiniUPnPc_INCLUDE_DIRS ${MINIUPNPC_INCLUDE_DIR}) +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -20,6 +20,8 @@ option(ENABLE_STATIC_LIBSTDCXX "Statically link libstdc++" OFF) option(ENABLE_GLIBC_BACK_COMPAT "Enable Glibc compatibility features" OFF) option(ENABLE_QRCODE "Enable QR code display" ON) +option(ENABLE_UPNP "Enable UPnP support" ON) +option(START_WITH_UPNP "Make UPnP the default to map ports" OFF) # Allow usage of sanitizers by setting ECM_ENABLE_SANITIZERS if(ENABLE_SANITIZERS) @@ -378,6 +380,24 @@ memenv ) +if(ENABLE_UPNP) + target_include_directories(server PUBLIC ${MINIUPNPC_INCLUDE_DIR}) + target_link_libraries(server ${MINIUPNPC_LIBRARY}) + + if(${CMAKE_SYSTEM_NAME} MATCHES "Windows") + find_library(IPHLPAPI_LIBRARY NAMES iphlpapi) + if(NOT IPHLPAPI_LIBRARY) + message(FATAL_ERROR "Lib iphlpapi is missing") + endif() + target_link_libraries(server ${IPHLPAPI_LIBRARY}) + + target_compile_definitions(server + PUBLIC -DSTATICLIB + PUBLIC -DMINIUPNP_STATICLIB + ) + endif() +endif() + # Test suite. add_subdirectory(test) diff --git a/src/config/CMakeLists.txt b/src/config/CMakeLists.txt --- a/src/config/CMakeLists.txt +++ b/src/config/CMakeLists.txt @@ -164,5 +164,16 @@ set(USE_QRCODE 1 CACHE INTERNAL "QR code is enabled") endif() +# Try to find miniupnpc +if(ENABLE_UPNP) + find_package(MiniUPnPc REQUIRED) + + # The expected behavior is as follow: + # - If UPnP is enabled USE_UPNP must be defined + # - If UPnP should be the default port map method, USE_UPNP should be + # defined to 1, otherwise it should be defined to 0. + set(USE_UPNP ${START_WITH_UPNP} CACHE INTERNAL "UPnP is enabled") +endif() + # Generate the config configure_file(bitcoin-config.h.cmake.in bitcoin-config.h ESCAPE_QUOTES) diff --git a/src/config/bitcoin-config.h.cmake.in b/src/config/bitcoin-config.h.cmake.in --- a/src/config/bitcoin-config.h.cmake.in +++ b/src/config/bitcoin-config.h.cmake.in @@ -58,4 +58,11 @@ /* Define if QR support should be compiled in */ #cmakedefine USE_QRCODE 1 +/* UPnP support not compiled if undefined */ +#cmakedefine ENABLE_UPNP +#ifdef ENABLE_UPNP +/* Value (0 or 1) determines the UPnP default state at startup. */ +#cmakedefine01 USE_UPNP +#endif + #endif // BITCOIN_BITCOIN_CONFIG_H