# Author thomas.roehr@dfki.de # # Version 0.3 2013-07-02 # - rely on `gem content` to find library and header # - introduce GEM_OS_PKG to allow search via pkgconfig # Version 0.2 2010-01-14 # - add support for searching for multiple gems # Version 0.1 2010-12-15 # - support basic search functionality # - tested to find rice # # OUTPUT: # # GEM_INCLUDE_DIRS After successful search contains the include directores # # GEM_LIBRARIES After successful search contains the full path of each found library # # # Usage: # set(GEM_DEBUG TRUE) # find_package(Gem COMPONENTS rice hoe) # include_directories(${GEM_INCLUDE_DIRS}) # target_link_libraries(${GEM_LIBRARIES} # # in case pkg-config should be used to search for the os pkg, set GEM_OS_PKG, i.e. # set(GEM_OS_PKG TRUE) # # Check for how 'gem' should be called include(FindPackageHandleStandardArgs) find_program(GEM_EXECUTABLE NAMES "gem${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}" "gem${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}" "gem-${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}" "gem-${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}" "gem${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}${RUBY_VERSION_PATCH}" "gem${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}.${RUBY_VERSION_PATCH}" "gem-${RUBY_VERSION_MAJOR}${RUBY_VERSION_MINOR}${RUBY_VERSION_PATCH}" "gem-${RUBY_VERSION_MAJOR}.${RUBY_VERSION_MINOR}.${RUBY_VERSION_PATCH}" "gem") # Making backward compatible if(Gem_DEBUG) set(GEM_DEBUG TRUE) endif() if(NOT GEM_EXECUTABLE) MESSAGE(FATAL_ERROR "Could not find the gem executable - install 'gem' first") endif() if(NOT Gem_FIND_COMPONENTS) MESSAGE(FATAL_ERROR "If searching for a Gem you have to provide COMPONENTS with the name of the gem") endif() foreach(Gem_NAME ${Gem_FIND_COMPONENTS}) set(GEM_${Gem_NAME}_FOUND TRUE) list(APPEND components_found_vars GEM_${Gem_NAME}_FOUND) # If the gem is installed as a gem if(NOT GEM_OS_PKG) set(GEM_HOME ENV{GEM_HOME}) # Use `gem content ` to extract current information about installed gems # Store the information into ${GEM_LOCAL_INFO} EXECUTE_PROCESS(COMMAND ${GEM_EXECUTABLE} content ${Gem_NAME} RESULT_VARIABLE GEM_RUN_RESULT OUTPUT_VARIABLE GEM_LOCAL_INFO) if(GEM_RUN_RESULT STREQUAL "0") list(APPEND FOUND_GEMS ${Gem_NAME}) set(_library_NAME_PATTERN lib${Gem_NAME}.a lib${Gem_NAME}.so lib${Gem_NAME}.dylib ${Gem_NAME}.a ${Gem_NAME}.so ${Gem_NAME}.dylib .*.a .*.so .*.dylib ) set(_header_SUFFIX_PATTERN .h .hh .hpp ) # Create a list from the output results of the gem command string(REPLACE "\n" ";" GEM_CONTENT_LIST "${GEM_LOCAL_INFO}") foreach(_gem_CONTENT_PATH ${GEM_CONTENT_LIST}) # Convert so that only '/' Unix path separator are being using # needed to do proper regex matching FILE(TO_CMAKE_PATH ${_gem_CONTENT_PATH} gem_CONTENT_PATH) # Identify library -- checking for a library in the gems 'lib' (sub)directory # Search for an existing library, but only within the gems folder foreach(_library_NAME ${_library_NAME_PATTERN}) STRING(REGEX MATCH ".*${Gem_NAME}.*/lib/.*${_library_NAME}$" GEM_PATH_INFO "${gem_CONTENT_PATH}") if(NOT "${GEM_PATH_INFO}" STREQUAL "") list(APPEND GEM_LIBRARIES ${GEM_PATH_INFO}) break() endif() endforeach() # Identify headers # Checking for available headers in an include directory foreach(_header_PATTERN ${_header_SUFFIX_PATTERN}) STRING(REGEX MATCH ".*${Gem_NAME}.*/include/.*${_header_PATTERN}$" GEM_PATH_INFO "${gem_CONTENT_PATH}") if(NOT "${GEM_PATH_INFO}" STREQUAL "") STRING(REGEX REPLACE "(.*${Gem_NAME}.*/include/).*${_header_PATTERN}$" "\\1" GEM_PATH_INFO "${gem_CONTENT_PATH}") list(APPEND GEM_INCLUDE_DIRS ${GEM_PATH_INFO}) break() endif() endforeach() endforeach() else() set(GEM_${Gem_NAME}_FOUND FALSE) endif() else(NOT GEM_OS_PKG) pkg_check_modules(GEM_PKG ${Gem_NAME}) set(GEM_${GEM_NAME}_FOUND GEM_PKG_FOUND) set(GEM_INCLUDE_DIRS ${GEM_PKG_INCLUDE_DIRS}) set(GEM_LIBRARIES ${GEM_PKG_LIBRARIES} ${GEM_PKG_STATIC_LIBRARIES}) list(APPEND GEM_LIBRARIES ${GEM_PKG_LDFLAGS} ${GEM_PKG_STATIC_LDFLAGS}) list(APPEND GEM_LIBRARIES ${GEM_PKG_LDFLAGS_OTHER} ${GEM_PKG_STATIC_LDFLAGS_OTHER}) if(GEM_DEBUG) message(STATUS "GEM_OS_PKG is defined") message(STATUS "GEM_INCLUDE_DIRS ${GEM_INCLUDE_DIRS}") message(STATUS "GEM_STATIC_LIBRARY_DIRS ${GEM_PKG_STATIC_LIBRARY_DIRS}") message(STATUS "GEM_LIBRARY_DIRS ${GEM_PKG_STATIC_LIBRARY_DIRS}") message(STATUS "GEM_STATIC_LIBRARIES ${GEM_PKG_STATIC_LIBRARIES}") message(STATUS "GEM_LIBRARIES ${GEM_LIBRARIES}") endif() endif() if(GEM_DEBUG) message(STATUS "${Gem_NAME} library dir: ${GEM_LIBRARIES}") message(STATUS "${Gem_NAME} include dir: ${GEM_INCLUDE_DIRS}") endif() endforeach() # Compact the lists if(DEFINED GEM_LIBRARIES) LIST(REMOVE_DUPLICATES GEM_LIBRARIES) endif() if(DEFINED GEM_INCLUDE_DIRS) LIST(REMOVE_DUPLICATES GEM_INCLUDE_DIRS) endif() find_package_handle_standard_args(GEM REQUIRED_VARS ${components_found_vars} FAIL_MESSAGE "Could not find all required gems")