From 521b04452efca5a4d66a7eda03aef5fdd2b8c10b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 30 Nov 2021 11:29:28 +0800 Subject: [PATCH] ext: Support building with system miniUPnPc --- CMakeLists.txt | 133 ++++++++++++++++-------------- cmake/Modules/FindMINIUPNPC.cmake | 60 ++++++++++++++ 2 files changed, 130 insertions(+), 63 deletions(-) create mode 100644 cmake/Modules/FindMINIUPNPC.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 86ddf08cb1..5771898f35 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,6 +154,7 @@ option(USE_SYSTEM_LIBZIP "Dynamically link against system libzip" ${USE_SYSTEM_L option(USE_SYSTEM_LIBSDL2 "Dynamically link against system SDL2" ON) option(USE_SYSTEM_LIBPNG "Dynamically link against system libpng" ON) option(USE_SYSTEM_ZSTD "Dynamically link against system zstd" ${USE_SYSTEM_ZSTD}) +option(USE_SYSTEM_MINIUPNPC "Dynamically link against system miniUPnPc" ${USE_SYSTEM_MINIUPNPC}) option(USE_ASAN "Use address sanitizer" OFF) option(USE_UBSAN "Use undefined behaviour sanitizer" OFF) @@ -2045,71 +2046,77 @@ endif() # miniUPnPc integration (MiniUPnPc supposed to works on any POSIX system, not sure if some of these are redundant/not needed tho) if(USE_MINIUPNPC) - set (MINIUPNPC_VERSION 2.1) # used by miniupnpcstrings.h.cmake - set (MINIUPNPC_API_VERSION 17) - option(UPNPC_BUILD_STATIC "Build static library" TRUE) - option(NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE) - mark_as_advanced(NO_GETADDRINFO) - if (NO_GETADDRINFO) - add_definitions(-DNO_GETADDRINFO) - endif() - - if (NOT WIN32) - add_definitions (-DMINIUPNPC_SET_SOCKET_TIMEOUT) - add_definitions (-D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112L) - endif() - if (MACOSX) - add_definitions (-D_DARWIN_C_SOURCE) - endif() - if(WIN32) - add_definitions(-DWIN32 -DMINIUPNP_EXPORTS ) + if(USE_SYSTEM_MINIUPNPC) + find_package(MINIUPNPC REQUIRED) + target_include_directories(${CoreLibName} PRIVATE ${MINIUPNP_INCLUDE_DIR}) + target_link_libraries(${CoreLibName} ${MINIUPNP_LIBRARY}) else() - add_definitions(-fPIC) - endif() + set (MINIUPNPC_VERSION 2.1) # used by miniupnpcstrings.h.cmake + set (MINIUPNPC_API_VERSION 17) + option(UPNPC_BUILD_STATIC "Build static library" TRUE) + option(NO_GETADDRINFO "Define NO_GETADDRINFO" FALSE) + mark_as_advanced(NO_GETADDRINFO) + if (NO_GETADDRINFO) + add_definitions(-DNO_GETADDRINFO) + endif() - add_definitions(-DWITH_UPNP -DMINIUPNP_STATICLIB) - set(MINIUPNP_DIR "ext/miniupnp/miniupnpc") - include_directories(${CMAKE_CURRENT_BINARY_DIR}) - configure_file(${MINIUPNP_DIR}/miniupnpcstrings.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/miniupnpcstrings.h) # by default miniupnp repo doesn't contains miniupnpcstrings.h and need to be generated - set(MINIUPNPC_SOURCES - # the needed bits of miniupnpc (no python module, no tests, no cli) - ${MINIUPNP_DIR}/addr_is_reserved.c - ${MINIUPNP_DIR}/connecthostport.c - ${MINIUPNP_DIR}/igd_desc_parse.c - ${MINIUPNP_DIR}/minisoap.c - ${MINIUPNP_DIR}/minissdpc.c - ${MINIUPNP_DIR}/miniupnpc.c - ${MINIUPNP_DIR}/miniwget.c - ${MINIUPNP_DIR}/minixml.c - ${MINIUPNP_DIR}/minixmlvalid.c - ${MINIUPNP_DIR}/portlistingparse.c - ${MINIUPNP_DIR}/receivedata.c - #${MINIUPNP_DIR}/upnpc.c # causing an error due to already existing _main() - ${MINIUPNP_DIR}/upnpcommands.c - ${MINIUPNP_DIR}/upnpdev.c - ${MINIUPNP_DIR}/upnperrors.c - ${MINIUPNP_DIR}/upnpreplyparse.c - ${CMAKE_CURRENT_BINARY_DIR}/miniupnpcstrings.h - ) - if (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") - #set(MINIUPNPC_SOURCES ${MINIUPNPC_SOURCES} minissdpc.c) # causing an error due to duplication in MINIUPNPC_SOURCES? - endif() - if (WIN32) - set_source_files_properties(${MINIUPNPC_SOURCES} PROPERTIES COMPILE_DEFINITIONS "MINIUPNP_STATICLIB;MINIUPNP_EXPORTS") - set(LDLIBS ws2_32 iphlpapi ${LDLIBS}) - #elseif (CMAKE_SYSTEM_NAME STREQUAL "Solaris") - # find_library (SOCKET_LIBRARY NAMES socket) - # find_library (NSL_LIBRARY NAMES nsl) - # find_library (RESOLV_LIBRARY NAMES resolv) - # set (LDLIBS ${SOCKET_LIBRARY} ${NSL_LIBRARY} ${RESOLV_LIBRARY} ${LDLIBS}) - endif() - if (UPNPC_BUILD_STATIC) - add_library(miniupnpc STATIC ${MINIUPNPC_SOURCES}) - target_link_libraries(${CoreLibName} miniupnpc ${LDLIBS}) - set(UPNPC_LIBRARY miniupnpc) - if (MSVC) - # Suppress noise warnings - target_compile_definitions(miniupnpc PRIVATE _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS) + if (NOT WIN32) + add_definitions (-DMINIUPNPC_SET_SOCKET_TIMEOUT) + add_definitions (-D_BSD_SOURCE -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200112L) + endif() + if (MACOSX) + add_definitions (-D_DARWIN_C_SOURCE) + endif() + if(WIN32) + add_definitions(-DWIN32 -DMINIUPNP_EXPORTS ) + else() + add_definitions(-fPIC) + endif() + + add_definitions(-DWITH_UPNP -DMINIUPNP_STATICLIB) + set(MINIUPNP_DIR "ext/miniupnp/miniupnpc") + include_directories(${CMAKE_CURRENT_BINARY_DIR}) + configure_file(${MINIUPNP_DIR}/miniupnpcstrings.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/miniupnpcstrings.h) # by default miniupnp repo doesn't contains miniupnpcstrings.h and need to be generated + set(MINIUPNPC_SOURCES + # the needed bits of miniupnpc (no python module, no tests, no cli) + ${MINIUPNP_DIR}/addr_is_reserved.c + ${MINIUPNP_DIR}/connecthostport.c + ${MINIUPNP_DIR}/igd_desc_parse.c + ${MINIUPNP_DIR}/minisoap.c + ${MINIUPNP_DIR}/minissdpc.c + ${MINIUPNP_DIR}/miniupnpc.c + ${MINIUPNP_DIR}/miniwget.c + ${MINIUPNP_DIR}/minixml.c + ${MINIUPNP_DIR}/minixmlvalid.c + ${MINIUPNP_DIR}/portlistingparse.c + ${MINIUPNP_DIR}/receivedata.c + #${MINIUPNP_DIR}/upnpc.c # causing an error due to already existing _main() + ${MINIUPNP_DIR}/upnpcommands.c + ${MINIUPNP_DIR}/upnpdev.c + ${MINIUPNP_DIR}/upnperrors.c + ${MINIUPNP_DIR}/upnpreplyparse.c + ${CMAKE_CURRENT_BINARY_DIR}/miniupnpcstrings.h + ) + if (NOT WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "AmigaOS") + #set(MINIUPNPC_SOURCES ${MINIUPNPC_SOURCES} minissdpc.c) # causing an error due to duplication in MINIUPNPC_SOURCES? + endif() + if (WIN32) + set_source_files_properties(${MINIUPNPC_SOURCES} PROPERTIES COMPILE_DEFINITIONS "MINIUPNP_STATICLIB;MINIUPNP_EXPORTS") + set(LDLIBS ws2_32 iphlpapi ${LDLIBS}) + #elseif (CMAKE_SYSTEM_NAME STREQUAL "Solaris") + # find_library (SOCKET_LIBRARY NAMES socket) + # find_library (NSL_LIBRARY NAMES nsl) + # find_library (RESOLV_LIBRARY NAMES resolv) + # set (LDLIBS ${SOCKET_LIBRARY} ${NSL_LIBRARY} ${RESOLV_LIBRARY} ${LDLIBS}) + endif() + if (UPNPC_BUILD_STATIC) + add_library(miniupnpc STATIC ${MINIUPNPC_SOURCES}) + target_link_libraries(${CoreLibName} miniupnpc ${LDLIBS}) + set(UPNPC_LIBRARY miniupnpc) + if (MSVC) + # Suppress noise warnings + target_compile_definitions(miniupnpc PRIVATE _CRT_SECURE_NO_WARNINGS _WINSOCK_DEPRECATED_NO_WARNINGS) + endif() endif() endif() endif() diff --git a/cmake/Modules/FindMINIUPNPC.cmake b/cmake/Modules/FindMINIUPNPC.cmake new file mode 100644 index 0000000000..38dd7b0433 --- /dev/null +++ b/cmake/Modules/FindMINIUPNPC.cmake @@ -0,0 +1,60 @@ + +# --------------------------------- FindMINIUPNPC Start --------------------------------- +# Locate miniupnp library +# This module defines +# MINIUPNP_FOUND, if false, do not try to link to miniupnp +# MINIUPNP_LIBRARY, the miniupnp variant +# MINIUPNP_INCLUDE_DIR, where to find miniupnpc.h and family) +# MINIUPNPC_VERSION_1_7_OR_HIGHER, set if we detect the version of miniupnpc is 1.7 or higher +# +# Note that the expected include convention is +# #include "miniupnpc.h" +# and not +# #include +# This is because, the miniupnpc location is not standardized and may exist +# in locations other than miniupnpc/ + +if (MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY) + # Already in cache, be silent + set(MINIUPNP_FIND_QUIETLY TRUE) +endif () + +find_path(MINIUPNP_INCLUDE_DIR miniupnpc.h + HINTS $ENV{MINIUPNP_INCLUDE_DIR} + PATH_SUFFIXES miniupnpc +) + +find_library(MINIUPNP_LIBRARY miniupnpc + HINTS $ENV{MINIUPNP_LIBRARY} +) + +find_library(MINIUPNP_STATIC_LIBRARY libminiupnpc.a + HINTS $ENV{MINIUPNP_STATIC_LIBRARY} +) + +set(MINIUPNP_INCLUDE_DIRS ${MINIUPNP_INCLUDE_DIR}) +set(MINIUPNP_LIBRARIES ${MINIUPNP_LIBRARY}) +set(MINIUPNP_STATIC_LIBRARIES ${MINIUPNP_STATIC_LIBRARY}) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args( + MINIUPNPC DEFAULT_MSG + MINIUPNP_INCLUDE_DIR + MINIUPNP_LIBRARY +) + +IF(MINIUPNPC_FOUND) + file(STRINGS "${MINIUPNP_INCLUDE_DIR}/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}") + if (${MINIUPNPC_API_VERSION} GREATER "10" OR ${MINIUPNPC_API_VERSION} EQUAL "10") + message(STATUS "Found miniupnpc API version " ${MINIUPNPC_API_VERSION}) + set(MINIUPNP_FOUND true) + set(MINIUPNPC_VERSION_1_7_OR_HIGHER true) + endif() +endif() + +ENDIF() + +mark_as_advanced(MINIUPNP_INCLUDE_DIR MINIUPNP_LIBRARY MINIUPNP_STATIC_LIBRARY) +# --------------------------------- FindMINIUPNPC End ---------------------------------