From 57b75d2cd1eee96f2333325145dfa05d230f43c9 Mon Sep 17 00:00:00 2001 From: Roman Proskuryakov Date: Sun, 12 Jun 2016 20:09:14 +0300 Subject: [PATCH 1/3] Teaches LibFindMacros to find version from 'const int NAME = 42;' --- cmake/LibFindMacros.cmake | 151 +++++++++++++++++++++++++++++++------- 1 file changed, 124 insertions(+), 27 deletions(-) diff --git a/cmake/LibFindMacros.cmake b/cmake/LibFindMacros.cmake index 0ddbcba081..56b39a1ad9 100644 --- a/cmake/LibFindMacros.cmake +++ b/cmake/LibFindMacros.cmake @@ -3,6 +3,8 @@ # Maintained at https://github.com/Tronic/cmake-modules # Please send your improvements as pull requests on Github. +include(CMakeParseArguments) + # Find another package and make it a dependency of the current package. # This also automatically forwards the "REQUIRED" argument. # Usage: libfind_package( [extra args to find_package]) @@ -54,43 +56,138 @@ function (libfind_pkg_detect PREFIX) endif() endfunction() -# Extracts a version #define from a version.h file, output stored to _VERSION. -# Usage: libfind_version_header(Foobar foobar/version.h FOOBAR_VERSION_STR) -# Fourth argument "QUIET" may be used for silently testing different define names. +# libfind_header_path( [PATHS [ ...]] NAMES [name ...] VAR [QUIET]) +# Get fullpath of the first found header looking inside _INCLUDE_DIR or in the given PATHS +# Usage: libfind_header_path(Foobar NAMES foobar/version.h VAR filepath) +function (libfind_header_path PREFIX) + set(options QUIET) + set(one_value_keywords VAR PATH) + set(multi_value_keywords NAMES PATHS) + CMAKE_PARSE_ARGUMENTS(OPT "${options}" "${one_value_keywords}" "${multi_value_keywords}" ${ARGN}) + if (NOT OPT_VAR OR NOT OPT_NAMES) + message(FATAL_ERROR "Arguments VAR, NAMES are required!") + endif() + if (OPT_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Calling function with unused arguments '${OPT_UNPARSED_ARGUMENTS}'!") + endif() + if (OPT_QUIET OR ${PREFIX}_FIND_QUIETLY) + set(quiet TRUE) + endif() + set(paths ${OPT_PATHS} ${PREFIX}_INCLUDE_DIR) + + foreach(name ${OPT_NAMES}) + foreach(path ${paths}) + set(filepath "${${path}}/${name}") + # check for existance + if (EXISTS ${filepath}) + set(${OPT_VAR} ${filepath} PARENT_SCOPE) # export path + return() + endif() + endforeach() + endforeach() + + # report error if not found + set(${OPT_VAR} NOTFOUND PARENT_SCOPE) + if (NOT quiet) + message(AUTHOR_WARNING "Unable to find '${OPT_NAMES}'") + endif() +endfunction() + +# libfind_version_n_header( +# NAMES [ ...] +# DEFINES [ ...] | CONSTANTS [ ...] +# [PATHS [ ...]] +# [QUIET] +# ) +# Collect all defines|constants from a header inside _INCLUDE_DIR or in the given PATHS +# output stored to _VERSION. # This function does nothing if the version variable is already defined. -function (libfind_version_header PREFIX VERSION_H DEFINE_NAME) - # Skip processing if we already have a version or if the include dir was not found - if (${PREFIX}_VERSION OR NOT ${PREFIX}_INCLUDE_DIR) +# Usage: libfind_version_n_header(Foobar NAMES foobar/version.h DEFINES FOOBAR_VERSION_MAJOR FOOBAR_VERSION_MINOR) +function (libfind_version_n_header PREFIX) + # Skip processing if we already have a version + if (${PREFIX}_VERSION) return() endif() - set(quiet ${${PREFIX}_FIND_QUIETLY}) - # Process optional arguments - foreach(arg ${ARGN}) - if (arg STREQUAL "QUIET") - set(quiet TRUE) + + set(options QUIET) + set(one_value_keywords ) + set(multi_value_keywords NAMES PATHS DEFINES CONSTANTS) + CMAKE_PARSE_ARGUMENTS(OPT "${options}" "${one_value_keywords}" "${multi_value_keywords}" ${ARGN}) + if (NOT OPT_NAMES OR (NOT OPT_DEFINES AND NOT OPT_CONSTANTS)) + message(FATAL_ERROR "Arguments NAMES, DEFINES|CONSTANTS are required!") + endif() + if (OPT_DEFINES AND OPT_CONSTANTS) + message(FATAL_ERROR "Either DEFINES or CONSTANTS must be set!") + endif() + if (OPT_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Calling function with unused arguments '${OPT_UNPARSED_ARGUMENTS}'!") + endif() + if (OPT_QUIET OR ${PREFIX}_FIND_QUIETLY) + set(quiet TRUE) + set(force_quiet "QUIET") # to propagate argument QUIET + endif() + + # Read the header + libfind_header_path(${PREFIX} NAMES ${OPT_NAMES} PATHS ${OPT_PATHS} VAR filename ${force_quiet}) + if (NOT filename) + return() + endif() + file(READ "${filename}" header) + # Parse for version number + unset(version_parts) + foreach(define_name ${OPT_DEFINES}) + string(REGEX MATCH "# *define +${define_name} +((\"([^\n]*)\")|([^ \n]*))" match "${header}") + # No regex match? + if (NOT match OR match STREQUAL header) + if (NOT quiet) + message(AUTHOR_WARNING "Unable to find \#define ${define_name} \"\" from ${filename}") + endif() + return() else() - message(AUTHOR_WARNING "Unknown argument ${arg} to libfind_version_header ignored.") + list(APPEND version_parts "${CMAKE_MATCH_3}${CMAKE_MATCH_4}") endif() endforeach() - # Read the header and parse for version number - set(filename "${${PREFIX}_INCLUDE_DIR}/${VERSION_H}") - if (NOT EXISTS ${filename}) - if (NOT quiet) - message(AUTHOR_WARNING "Unable to find ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}") + foreach(constant_name ${OPT_CONSTANTS}) + string(REGEX MATCH "${constant_name} *= *((\"([^\;]*)\")|([^ \;]*))" match "${header}") + # No regex match? + if (NOT match OR match STREQUAL header) + if (NOT quiet) + message(AUTHOR_WARNING "Unable to find ${constant_name} = \"\" from ${filename}") + endif() + return() + else() + list(APPEND version_parts "${CMAKE_MATCH_3}${CMAKE_MATCH_4}") endif() + endforeach() + + # Export the version string + string(REPLACE ";" "." version "${version_parts}") + set(${PREFIX}_VERSION "${version}" PARENT_SCOPE) +endfunction() + +# libfind_version_header(
[PATHS [ ...]] [QUIET]) +# Extracts a version #define from a version.h file, output stored to _VERSION. +# This function does nothing if the version variable is already defined. +# Usage: libfind_version_header(Foobar foobar/version.h FOOBAR_VERSION_STR) +function (libfind_version_header PREFIX VERSION_H DEFINE_NAME) + # Skip processing if we already have a version + if (${PREFIX}_VERSION) return() endif() - file(READ "${filename}" header) - string(REGEX MATCH ".*#[ \t]*define[ \t]+${DEFINE_NAME}[ \t]+((\"([^\n]*)\")|([^\n]*))" match "${header}") - # No regex match? - if (match STREQUAL header) - if (NOT quiet) - message(AUTHOR_WARNING "Unable to find \#define ${DEFINE_NAME} \"\" from ${${PREFIX}_INCLUDE_DIR}/${VERSION_H}") - endif() - return() + + set(options QUIET) + set(one_value_keywords ) + set(multi_value_keywords PATHS) + CMAKE_PARSE_ARGUMENTS(OPT "${options}" "${one_value_keywords}" "${multi_value_keywords}" ${ARGN}) + if (OPT_UNPARSED_ARGUMENTS) + message(FATAL_ERROR "Calling function with unused arguments '${OPT_UNPARSED_ARGUMENTS}'!") endif() - # Export the version string - set(${PREFIX}_VERSION "${CMAKE_MATCH_3}${CMAKE_MATCH_4}" PARENT_SCOPE) + if (OPT_QUIET OR ${PREFIX}_FIND_QUIETLY) + set(force_quiet "QUIET") # to propagate argument QUIET + endif() + + libfind_version_n_header(${PREFIX} NAMES ${VERSION_H} PATHS ${OPT_PATHS} DEFINES ${DEFINE_NAME} ${force_quiet}) + set(${PREFIX}_VERSION "${${PREFIX}_VERSION}" PARENT_SCOPE) endfunction() # Do the final processing once the paths have been detected. From 4d0544e61a75083d7ea16793fd3b43cffe8a746c Mon Sep 17 00:00:00 2001 From: Roman Proskuryakov Date: Sun, 12 Jun 2016 20:11:53 +0300 Subject: [PATCH 2/3] Adds FindTinyXML.cmake --- cmake/FindTinyXML.cmake | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 cmake/FindTinyXML.cmake diff --git a/cmake/FindTinyXML.cmake b/cmake/FindTinyXML.cmake new file mode 100644 index 0000000000..d79a21c4a7 --- /dev/null +++ b/cmake/FindTinyXML.cmake @@ -0,0 +1,20 @@ +# Try to find TinyXML library + +# Once done this will define +# TinyXML_FOUND - System has the all required components. +# TinyXML_INCLUDE_DIRS - Include directory necessary for using the required components headers. +# TinyXML_LIBRARIES - Link these to use TinyXML. +# + +include(LibFindMacros) +include(PreprocessorUtils) + +libfind_pkg_detect(TinyXML tinyxml + FIND_PATH tinyxml.h + FIND_LIBRARY tinyxml +) +libfind_version_n_header(TinyXML + NAMES tinyxml.h + CONSTANTS TIXML_MAJOR_VERSION TIXML_MINOR_VERSION TIXML_PATCH_VERSION +) +libfind_process(TinyXML) From 28c63aea72c5bb5ea53bf69e3216edf97f4def52 Mon Sep 17 00:00:00 2001 From: Roman Proskuryakov Date: Sun, 12 Jun 2016 21:03:33 +0300 Subject: [PATCH 3/3] Uses FindTinyXML to find package --- CMakeLists.txt | 15 +++---------- apps/openmw/CMakeLists.txt | 2 +- extern/oics/CMakeLists.txt | 43 ++++++++++++++------------------------ 3 files changed, 20 insertions(+), 40 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c96a18e036..14a1c15c80 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -155,17 +155,10 @@ add_definitions(-D__STDC_CONSTANT_MACROS) # TinyXML option(USE_SYSTEM_TINYXML "Use system TinyXML library instead of internal." OFF) -if(USE_SYSTEM_TINYXML) - find_library(TINYXML_LIBRARIES tinyxml) - find_path(TINYXML_INCLUDE_DIR tinyxml.h) - message(STATUS "Found TinyXML: ${TINYXML_LIBRARIES} ${TINYXML_INCLUDE_DIR}") +if (USE_SYSTEM_TINYXML) + find_package(TinyXML REQUIRED) add_definitions (-DTIXML_USE_STL) - if(TINYXML_LIBRARIES AND TINYXML_INCLUDE_DIR) - include_directories(${TINYXML_INCLUDE_DIR}) - message(STATUS "Using system TinyXML library.") - else() - message(FATAL_ERROR "Detection of system TinyXML incomplete.") - endif() + include_directories(SYSTEM ${TinyXML_INCLUDE_DIRS}) endif() # Platform specific @@ -676,8 +669,6 @@ if (WIN32) endforeach(d) set_target_properties(components PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}") - # oics uses tinyxml, which has an initialized but unused variable - set_target_properties(oics PROPERTIES COMPILE_FLAGS "${WARNINGS} /wd4189 ${MT_BUILD}") set_target_properties(osg-ffmpeg-videoplayer PROPERTIES COMPILE_FLAGS "${WARNINGS} ${MT_BUILD}") if (BUILD_BSATOOL) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 8e938e0335..f7a9fea3c2 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -165,7 +165,7 @@ if (ANDROID) endif (ANDROID) if (USE_SYSTEM_TINYXML) - target_link_libraries(openmw ${TINYXML_LIBRARIES}) + target_link_libraries(openmw ${TinyXML_LIBRARIES}) endif() if (NOT UNIX) diff --git a/extern/oics/CMakeLists.txt b/extern/oics/CMakeLists.txt index 52ffb42a26..00d77f52c6 100644 --- a/extern/oics/CMakeLists.txt +++ b/extern/oics/CMakeLists.txt @@ -1,32 +1,21 @@ -set(OICS_LIBRARY "oics") - -# Sources - -set(OICS_SOURCE_FILES - ICSChannel.cpp - ICSControl.cpp - ICSInputControlSystem.cpp - ICSInputControlSystem_keyboard.cpp - ICSInputControlSystem_mouse.cpp - ICSInputControlSystem_joystick.cpp - ICSPrerequisites.h -) - -set(TINYXML_SOURCE_FILES - tinyxml.cpp - tinyxmlparser.cpp - tinyxmlerror.cpp - tinystr.cpp +add_library(oics STATIC + ICSChannel.cpp + ICSControl.cpp + ICSInputControlSystem.cpp + ICSInputControlSystem_keyboard.cpp + ICSInputControlSystem_mouse.cpp + ICSInputControlSystem_joystick.cpp + ICSPrerequisites.h ) if(USE_SYSTEM_TINYXML) - add_library(${OICS_LIBRARY} STATIC ${OICS_SOURCE_FILES}) - target_link_libraries(${OICS_LIBRARY} ${TINYXML_LIBRARIES}) + target_link_libraries(oics ${TinyXML_LIBRARIES}) else() - add_library(${OICS_LIBRARY} STATIC - ${OICS_SOURCE_FILES} - ${TINYXML_SOURCE_FILES}) + add_library(local_tinyxml STATIC + tinyxml.cpp + tinyxmlparser.cpp + tinyxmlerror.cpp + tinystr.cpp + ) + target_link_libraries(oics local_tinyxml) endif() - -# Does this do anything? -link_directories(${CMAKE_CURRENT_BINARY_DIR})