From b20d528c88153f8bb69a93f5aa8977d1fb9a3d25 Mon Sep 17 00:00:00 2001 From: King_DuckZ Date: Thu, 25 Aug 2016 23:57:17 +0200 Subject: [PATCH] Allow building against the system's miniupnpc --- CMakeLists.txt | 49 +++++++---- cmake/FindMiniupnpc.cmake | 179 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 212 insertions(+), 16 deletions(-) create mode 100644 cmake/FindMiniupnpc.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index ea24a74..7facf5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,31 +1,48 @@ cmake_minimum_required(VERSION 3.2 FATAL_ERROR) project(keepupnpup CXX) -if (BUILD_SHARED_LIBS) - set(upnp_lib_type "shared") - set(UPNPC_BUILD_STATIC OFF CACHE BOOL "" FORCE) - set(UPNPC_BUILD_SHARED ON CACHE BOOL "" FORCE) -else() - set(upnp_lib_type "static") - set(UPNPC_BUILD_STATIC ON CACHE BOOL "" FORCE) - set(UPNPC_BUILD_SHARED OFF CACHE BOOL "" FORCE) -endif() -set(UPNPC_BUILD_TESTS OFF CACHE BOOL "" FORCE) -set(CXX_STANDARD_REQUIRED ON) +option (USE_SYSTEM_MINIUPNP "Try to locate miniupnpc on the system and build against that" ON) -add_subdirectory(lib/miniupnp/miniupnpc) +if (USE_SYSTEM_MINIUPNP) + find_package(Miniupnpc 2.0 REQUIRED) +else() + if (BUILD_SHARED_LIBS) + set(upnp_lib_type "shared") + set(UPNPC_BUILD_STATIC OFF CACHE BOOL "" FORCE) + set(UPNPC_BUILD_SHARED ON CACHE BOOL "" FORCE) + else() + set(upnp_lib_type "static") + set(UPNPC_BUILD_STATIC ON CACHE BOOL "" FORCE) + set(UPNPC_BUILD_SHARED OFF CACHE BOOL "" FORCE) + endif() + set(UPNPC_BUILD_TESTS OFF CACHE BOOL "" FORCE) + set(CXX_STANDARD_REQUIRED ON) + + add_subdirectory(lib/miniupnp/miniupnpc) +endif() add_executable(${PROJECT_NAME} src/main.cpp ) target_include_directories(${PROJECT_NAME} - PRIVATE lib/miniupnp/miniupnpc PRIVATE lib/better-enums ) -target_link_libraries(${PROJECT_NAME} - libminiupnpc-${upnp_lib_type} -) +if (USE_SYSTEM_MINIUPNP) + target_include_directories(${PROJECT_NAME} SYSTEM + PRIVATE ${MINIUPNP_INCLUDE_DIR} + ) + target_link_libraries(${PROJECT_NAME} + PRIVATE ${MINIUPNP_LIBRARY} + ) +else() + target_include_directories(${PROJECT_NAME} + PRIVATE lib/miniupnp/miniupnpc + ) + target_link_libraries(${PROJECT_NAME} + libminiupnpc-${upnp_lib_type} + ) +endif() set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11) diff --git a/cmake/FindMiniupnpc.cmake b/cmake/FindMiniupnpc.cmake new file mode 100644 index 0000000..34bf6ad --- /dev/null +++ b/cmake/FindMiniupnpc.cmake @@ -0,0 +1,179 @@ +# --------------------------------- 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_PRE1_6 --> set if we detect the version of miniupnpc is +# pre 1.6 +# MINIUPNPC_VERSION_PRE1_5 --> set if we detect the version of miniupnpc is +# pre 1.5 +# +# 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/ + +#============================================================================= +# Copyright 2011 Mark Vejvoda +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distributed this file outside of CMake, substitute the full +# License text for the above reference.) + +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 + PATH_SUFFIXES miniupnpc) +find_library(MINIUPNP_LIBRARY miniupnpc) + +if (MINIUPNP_INCLUDE_DIR AND MINIUPNP_LIBRARY) + set (MINIUPNP_FOUND TRUE) +endif () + +if (MINIUPNP_FOUND) + include(CheckCXXSourceRuns) + if (NOT MINIUPNP_FIND_QUIETLY) + message (STATUS "Found the miniupnpc libraries at ${MINIUPNP_LIBRARY}") + message (STATUS "Found the miniupnpc headers at ${MINIUPNP_INCLUDE_DIR}") + endif () + + message(STATUS "Detecting version of miniupnpc in path: ${MINIUPNP_INCLUDE_DIR}") + + set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY}) + check_cxx_source_runs(" + #include + #include + #include + #include + int main() + { + static struct UPNPUrls urls; + static struct IGDdatas data; + GetUPNPUrls (&urls, &data, \"myurl\",0); + return 0; + }" + MINIUPNPC_VERSION_1_7_OR_HIGHER) + +IF (NOT MINIUPNPC_VERSION_1_7_OR_HIGHER) + set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY}) + check_cxx_source_runs(" + #include + #include + #include + #include + int main() + { + struct UPNPDev *devlist = NULL; + int upnp_delay = 5000; + const char *upnp_multicastif = NULL; + const char *upnp_minissdpdsock = NULL; + int upnp_sameport = 0; + int upnp_ipv6 = 0; + int upnp_error = 0; + devlist = upnpDiscover(upnp_delay, upnp_multicastif, upnp_minissdpdsock, upnp_sameport, upnp_ipv6, &upnp_error); + return 0; + }" + MINIUPNPC_VERSION_PRE1_7) + ENDIF() + + IF (NOT MINIUPNPC_VERSION_PRE1_7 AND NOT MINIUPNPC_VERSION_1_7_OR_HIGHER) + set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY}) + check_cxx_source_runs(" + #include + #include + #include + #include + int main() + { + struct UPNPDev *devlist = NULL; + int upnp_delay = 5000; + const char *upnp_multicastif = NULL; + const char *upnp_minissdpdsock = NULL; + int upnp_sameport = 0; + int upnp_ipv6 = 0; + int upnp_error = 0; + devlist = upnpDiscover(upnp_delay, upnp_multicastif, upnp_minissdpdsock, upnp_sameport); + return 0; + }" + MINIUPNPC_VERSION_PRE1_6) + + ENDIF() + + IF (NOT MINIUPNPC_VERSION_PRE1_6 AND NOT MINIUPNPC_VERSION_PRE1_7 AND NOT MINIUPNPC_VERSION_1_7_OR_HIGHER) + set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY}) + check_cxx_source_runs(" + #include + #include + #include + #include + static struct UPNPUrls urls; + static struct IGDdatas data; + int main() + { + char externalIP[16] = \"\"; + UPNP_GetExternalIPAddress(urls.controlURL, data.first.servicetype, externalIP); + return 0; + }" + MINIUPNPC_VERSION_1_5_OR_HIGHER) + ENDIF() + + IF (NOT MINIUPNPC_VERSION_1_5_OR_HIGHER AND NOT MINIUPNPC_VERSION_PRE1_6 AND NOT MINIUPNPC_VERSION_PRE1_7 AND NOT MINIUPNPC_VERSION_1_7_OR_HIGHER) + set(CMAKE_REQUIRED_INCLUDES ${MINIUPNP_INCLUDE_DIR}) + set(CMAKE_REQUIRED_LIBRARIES ${MINIUPNP_LIBRARY}) + check_cxx_source_runs(" + #include + #include + #include + #include + static struct UPNPUrls urls; + static struct IGDdatas data; + int main() + { + char externalIP[16] = \"\"; + UPNP_GetExternalIPAddress(urls.controlURL, data.servicetype, externalIP); + return 0; + }" + MINIUPNPC_VERSION_PRE1_5) + +ENDIF() + +IF(MINIUPNPC_VERSION_PRE1_5) + message(STATUS "Found miniupnpc version is pre v1.5") +ENDIF() +IF(MINIUPNPC_VERSION_PRE1_6) + message(STATUS "Found miniupnpc version is pre v1.6") +ENDIF() +IF(MINIUPNPC_VERSION_PRE1_7) + message(STATUS "Found miniupnpc version is pre v1.7") +ENDIF() + +IF(NOT MINIUPNPC_VERSION_PRE1_5 AND NOT MINIUPNPC_VERSION_PRE1_6 AND NOT MINIUPNPC_VERSION_PRE1_7) + IF(MINIUPNPC_VERSION_1_5_OR_HIGHER) + message(STATUS "Found miniupnpc version is v1.5 or higher") + ELSE() + message(STATUS "Found miniupnpc version is v1.7 or higher") + ENDIF() +ENDIF() + +else () + message (STATUS "Could not find miniupnp") +endif () + +MARK_AS_ADVANCED(MINIUPNP_INCLUDE_DIR MINIUPNP_LIBRARY) +# --------------------------------- FindMiniupnpc End ---------------------------------