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,27 @@ +# 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) + +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}) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -16,6 +16,8 @@ option(BUILD_BITCOIN_TX "Build bitcoin-tx" ON) option(BUILD_BITCOIN_QT "Build bitcoin-qt" ON) option(ENABLE_HARDENING "Harden the executables" ON) +option(ENABLE_UPNP "Enable UPnP support" ON) +option(START_WITH_UPNP "Make UPnP the default to map ports" OFF) # Cmake uses the CMAKE_BUILD_TYPE variable to select the build configuration. # By default it supports more configurations that needed for Bitcoin ABC, and @@ -302,6 +304,24 @@ memenv ) +if(USE_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 @@ -154,5 +154,51 @@ # Activate ZeroMQ set(ENABLE_ZMQ ${BUILD_BITCOIN_ZMQ}) +# Try to find miniupnpc +if(ENABLE_UPNP) + find_package(MiniUPnPc REQUIRED) + + set(MINIUPNPC_REQUIRED_HEADERS + miniupnpc/miniwget.h + miniupnpc/miniupnpc.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}) + message(FATAL_ERROR "Could not find ${_miniupnpc_header}") + endif() + endforeach() + + # 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. + # + # What we need is some tristate value: + # - /* #undef USE_UPNP */ if UPnP is disabled + # - #define USE_UPNP 0 if UPnP is enabled but not the default method + # - #define USE_UPNP 1 if UPnP is enabled and is the default method + # + # CMake cannot differentiate between a 0 value and the #undef case when + # using the configure_file function. + # To workaround this limitation, the #define 0 case is set to a value + # which is not interpreted as false by CMake but will be casted to + # boolean as false in the code. + if(START_WITH_UPNP) + set(USE_UPNP_VALUE 1) + else() + # Use parenthesis to avoid CMake to interpret as false, and use a + # quoted variable to avoid CMake escaping the parenthesis. + set(USE_UPNP_VALUE "(0)") + endif() + set(USE_UPNP ${USE_UPNP_VALUE} 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 @@ -61,4 +61,10 @@ #cmakedefine ENABLE_WALLET 1 #cmakedefine ENABLE_ZMQ 1 +/* + * UPnP support not compiled if undefined, otherwise value (0 or 1) determines + * default state. + */ +#cmakedefine USE_UPNP ${USE_UPNP} + #endif // BITCOIN_BITCOIN_CONFIG_H