[CMake] Writing a custom Find*.cmake file for Pantheios

Philipp Berger newsletters at philippberger.de
Mon Jul 16 22:11:48 EDT 2012


I built a beta-version of the FindPantheios.cmake (see attached version,
no copyright stuff, I'm sorry), it works - at least on windows and in my
configuration.
As I am new to this and this is my first try with Find* files, could
those experienced in the art of CMakeing please have a look at it, give
me some tips & tricks?
Suggestions welcome ;)

Another thing: I understand the function find_library is to be used to
"find" libs - the docs did not help me with understanding the naming
scheme used. Is it possible to use find_library to locate e.g.
"pantheios.1.core.vc10.x64.dll.debug.lib" if I have the string
"pantheios.1.core" and also ".dll.debug"? I do not know anything about
the part in the middle nor the ending. Sorry if this is a stupid question :/

My current solution is not very pretty and more of a hack and will only
work in Windows as it uses FILE GLOB.

Third question: Is there an easy way to deal with the singular/plural
variables, for example _INCLUDE_DIR and _INCLUDE_DIRS? How exactly is
the syntax for setting those (String, List, etc)?

Thank you for your time, help and patience

Philipp Berger

Am 13.07.2012 08:30, schrieb Rolf Eike Beer:
> Am Freitag, 13. Juli 2012, 02:41:50 schrieb Philipp Berger:
>> Hello everybody,
>>
>> I'm relatively new to CMake, but managed to learn everything I needed,
>> up until now.
>> For a software project in C++ we want to use Pantheios (
>> http://www.pantheios.org <http://www.pantheios.org/> ) as logging framework.
>> Sadly, there is no FindPantheios.cmake file readily available, so I set of
>> to write my own.
>>
>> The part for searching the include files/path was easy.
>>
>> The big problem I am facing and find myself unable to solve is the wide
>> variety of library files.
>> The amount of available lib files is huge, see the attached file for the
>> list.
>>
>> For example, the core libs:
>> pantheios.1.core.vc10.x64.dll.debug.lib
>> pantheios.1.core.vc10.x64.dll.lib
>> pantheios.1.core.vc10.x64.mt.debug.lib
>> pantheios.1.core.vc10.x64.mt.lib
>> pantheios.1.core.vc10.x64.widestring.dll.debug.lib
>> pantheios.1.core.vc10.x64.widestring.dll.lib
>> pantheios.1.core.vc10.x64.widestring.mt.debug.lib
>> pantheios.1.core.vc10.x64.widestring.mt.lib
>>
>> I would like to have a checkbox to select Widestring capability yes/no.
>>
>> A main problem for me is to check that the selected libs are valid for
>> the current configuration (if VC10 x64 was selected as compiler, only
>> allow vc10.x64 libs) - is there a way to securely achieve that? Or
>> should I rather let the user select arbitrary lib files and hope that
>> they will work?
>>
>> What I need is six fields for the user to select lib files - the core
>> lib, one frontend and a backend. And that for both Debug and Release. It
>> would be much more useful if the user could select from a dropdown menu
>> which Front-/Backend he would like together with the Widestring checkbox
>> and the CMake file would assign the required Debug and Release libs to
>> the variables, but as sated above, I do not know how to produce the
>> required version string and how to create such mechanisms in CMake in
>> general.
> The debug/release stuff can be handled by CMake, just put both of them in the 
> result variable prefixed with "debug" and "optimized". See what I've done 
> recently in e.g. FindBZip2.cmake.
>
> I would put the backends in the COMPONENTS section, as well as the widestring, 
> so you could do something like this:
>
> find_package(Pantheios COMPONENTS SomeBackend WideString)
Thanks for the tip, I implemented that.
> Choose one backend as default for the case the user does not select any and 
> raise an error if more than one is specified (unless that actually makes sense, 
> dunno).
>
> Eike
>
>
> --
>
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20120717/523015d3/attachment-0001.htm>
-------------- next part --------------
# Locate the Pantheois Logging Framework.
#
# Defines the following variables:
#
#   PANTHEIOS_FOUND - Found the Pantheios Logging Framework
#   PANTHEIOS_INCLUDE_DIRS - Include directories
#
# Accepts the following variables as input:
#
#   PANTHEIOS_ROOT - (as a CMake or environment variable)
#                The root directory of the pantheios install prefix
#
#   PANTHEIOS_USE_DYNAMIC_RUNTIME
#   
# Possible Components for BackEnd:
# ACELogger
# COMErrorObject
# File
# FileCallback
# FPrintf
# FPrintfCallback
# Null
# Speech
# Syslog
# WindowsConsole
# WindowsConsoleCallback
# WindowsDebugger
# WindowsDebuggerCallback
# WindowsEventLog
# WindowsMessageBox
# WindowsSyslog
# WindowsSyslogCallback
#
# Possible components for FrontEnd:
# NoFrontEnd
# SimpleFrontEnd
# NFrontEnd
#
#


# Use FIND_PACKAGE( Pantheios COMPONENTS ... ) to enable modules
IF( Pantheios_FIND_COMPONENTS )
	SET(PANTHEIOS_WIDESTRING 0)
	SET(PANTHEIOS_HAVE_BACKEND 0)
	SET(PANTHEIOS_HAVE_FRONTEND 0)
	FOREACH( component ${Pantheios_FIND_COMPONENTS} )
		IF (${component} STREQUAL "WideString")
			message(STATUS "WideString set")
			SET(PANTHEIOS_WIDESTRING 1)
		ELSE()
			IF (component STREQUAL "ACELogger")
				message(STATUS "Pantheios: Settung BackEnd to ACELogger")
				SET(PANTHEIOS_BACKEND "ACE")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "COMErrorObject")
				message(STATUS "Pantheios: Settung BackEnd to COMErrorObject")
				SET(PANTHEIOS_BACKEND "COMErrorObject")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "File")
				message(STATUS "Pantheios: Settung BackEnd to File")
				SET(PANTHEIOS_BACKEND "file")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "FileCallback")
				message(STATUS "Pantheios: Settung BackEnd to FileCallback")
				SET(PANTHEIOS_BACKEND "file.WithCallback")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "FPrintf")
				message(STATUS "Pantheios: Settung BackEnd to FPrintf")
				SET(PANTHEIOS_BACKEND "fprintf")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "FPrintfCallback")
				message(STATUS "Pantheios: Settung BackEnd to FPrintfCallback")
				SET(PANTHEIOS_BACKEND "fprintf.WithCallback")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "Null")
				message(STATUS "Pantheios: Settung BackEnd to Null")
				SET(PANTHEIOS_BACKEND "null")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "Speech")
				message(STATUS "Pantheios: Settung BackEnd to Speech")
				SET(PANTHEIOS_BACKEND "speech")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "Syslog")
				message(STATUS "Pantheios: Settung BackEnd to Syslog")
				SET(PANTHEIOS_BACKEND "syslog")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "WindowsConsole")
				message(STATUS "Pantheios: Settung BackEnd to WindowsConsole")
				SET(PANTHEIOS_BACKEND "WindowsConsole")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "WindowsConsoleCallback")
				message(STATUS "Pantheios: Settung BackEnd to WindowsConsoleCallback")
				SET(PANTHEIOS_BACKEND "WindowsConsole.WithCallback")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "WindowsDebugger")
				message(STATUS "Pantheios: Settung BackEnd to WindowsDebugger")
				SET(PANTHEIOS_BACKEND "WindowsDebugger")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "WindowsDebuggerCallback")
				message(STATUS "Pantheios: Settung BackEnd to WindowsDebuggerCallback")
				SET(PANTHEIOS_BACKEND "WindowsDebugger.WithCallback")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "WindowsEventLog")
				message(STATUS "Pantheios: Settung BackEnd to WindowsEventLog")
				SET(PANTHEIOS_BACKEND "EventLog")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "WindowsMessageBox")
				message(STATUS "Pantheios: Settung BackEnd to WindowsMessageBox")
				SET(PANTHEIOS_BACKEND "MessageBox")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "WindowsSyslog")
				message(STATUS "Pantheios: Settung BackEnd to WindowsSyslog")
				SET(PANTHEIOS_BACKEND "WindowsSyslog")
				SET(PANTHEIOS_HAVE_BACKEND 1)
			ELSEIF (component STREQUAL "WindowsSyslogCallback")
				message(STATUS "Pantheios: Settung BackEnd to WindowsSyslogCallback")
				SET(PANTHEIOS_BACKEND "WindowsSyslog.WithCallback")
				SET(PANTHEIOS_HAVE_BACKEND 1)	
			
			ELSEIF (component STREQUAL "NoFrontEnd")
				message(STATUS "Pantheios: Settung FrontEnd to NoFrontEnd")
				SET(PANTHEIOS_FRONTEND "null")
				SET(PANTHEIOS_HAVE_FRONTEND 1)
			ELSEIF (component STREQUAL "SimpleFrontEnd")
				message(STATUS "Pantheios: Settung FrontEnd to SimpleFrontEnd")
				SET(PANTHEIOS_FRONTEND "simple")
				SET(PANTHEIOS_HAVE_FRONTEND 1)	
				
			ELSE ()
				message(FATAL_ERROR "Unknown Component: ${component}")
			ENDIF ()
		ENDIF()
	ENDFOREACH( component )
  

ELSE()
	SET(PANTHEIOS_WIDESTRING 0)
ENDIF(Pantheios_FIND_COMPONENTS)


IF (NOT PANTHEIOS_FRONTEND)
	message(STATUS "Pantheios: No FrontEnd selected, defaulting to fe.simple")
	SET(PANTHEIOS_FRONTEND "simple")
	SET(PANTHEIOS_HAVE_FRONTEND 1)	
ENDIF ()
IF (NOT PANTHEIOS_BACKEND)
	message(STATUS "Pantheios: No BackEnd selected, defaulting to be.file")
	SET(PANTHEIOS_BACKEND "file")
	SET(PANTHEIOS_HAVE_BACKEND 1)
ENDIF ()


IF (PANTHEIOS_USE_DYNAMIC_RUNTIME)
	SET(PANTHEIOS_LIB_LINKTYPE "dll")
ELSE ()
	SET(PANTHEIOS_LIB_LINKTYPE "mt")
ENDIF ()

IF (NOT PANTHEIOS_ROOT)
	IF (NOT PANTHEIOS_INCLUDE_DIR STREQUAL "")
		SET(PANTHEIOS_ROOT "${PANTHEIOS_INCLUDE_DIR}/..")
		# message(STATUS "setting PANTHEIOS_ROOT to ${PANTHEIOS_ROOT}")
	ENDIF()
ENDIF()
mark_as_advanced(PANTHEIOS_ROOT)

find_path(PANTHEIOS_INCLUDE_DIR pantheios/pantheios.h
    HINTS
        $ENV{PANTHEIOS_ROOT}/include
        ${PANTHEIOS_ROOT}/include
)

# Is this the right way?
SET(PANTHEIOS_INCLUDE_DIRS PANTHEIOS_INCLUDE_DIR)

IF (PANTHEIOS_INCLUDE_DIR STREQUAL "")
	message(STATUS "Could not find pantheios/pantheios.h in provided pathes, please set either PANTHEIOS_ROOT or PANTHEIOS_INCLUDE_DIR")
	SET(PANTHEIOS_LIBRARIES NOTFOUND)
ELSE ()
	IF (PANTHEIOS_LIBRARY_DIRS STREQUAL "" OR NOT EXISTS PANTHEIOS_LIBRARY_DIRS)
		SET(PANTHEIOS_LIBRARY_DIRS "${PANTHEIOS_INCLUDE_DIR}/../lib")
	ENDIF()

	IF (NOT EXISTS ${PANTHEIOS_LIBRARY_DIRS})
		message(STATUS "Could not find PANTHEIOS_LIBRARY_DIRS: ${PANTHEIOS_LIBRARY_DIRS}")
	ENDIF ()

	FILE(GLOB PANTHEIOS_L_CORE_DBG "${PANTHEIOS_LIBRARY_DIRS}/pantheios.1.core.*.${PANTHEIOS_LIB_LINKTYPE}.debug.lib")
	FILE(GLOB PANTHEIOS_L_CORE_RLS "${PANTHEIOS_LIBRARY_DIRS}/pantheios.1.core.*.${PANTHEIOS_LIB_LINKTYPE}.lib")

	FILE(GLOB PANTHEIOS_L_UTIL_DBG "${PANTHEIOS_LIBRARY_DIRS}/pantheios.1.util.*.${PANTHEIOS_LIB_LINKTYPE}.debug.lib")
	FILE(GLOB PANTHEIOS_L_UTIL_RLS "${PANTHEIOS_LIBRARY_DIRS}/pantheios.1.util.*.${PANTHEIOS_LIB_LINKTYPE}.lib")

	# Backend
	FILE(GLOB PANTHEIOS_L_BACK1_DBG "${PANTHEIOS_LIBRARY_DIRS}/pantheios.1.bec.${PANTHEIOS_BACKEND}.${PANTHEIOS_LIB_LINKTYPE}.debug.lib")
	FILE(GLOB PANTHEIOS_L_BACK1_RLS "${PANTHEIOS_LIBRARY_DIRS}/pantheios.1.bec.${PANTHEIOS_BACKEND}.${PANTHEIOS_LIB_LINKTYPE}.lib")
	FILE(GLOB PANTHEIOS_L_BACK2_DBG "${PANTHEIOS_LIBRARY_DIRS}/pantheios.1.be.${PANTHEIOS_BACKEND}.${PANTHEIOS_LIB_LINKTYPE}.debug.lib")
	FILE(GLOB PANTHEIOS_L_BACK2_RLS "${PANTHEIOS_LIBRARY_DIRS}/pantheios.1.be.${PANTHEIOS_BACKEND}.${PANTHEIOS_LIB_LINKTYPE}.lib")

	# Frontend
	IF (PANTHEIOS_FRONTEND STREQUAL "null")
		message(STATUS "Pantheios: Linking NO FrontEnd, you will have to add your own.")
		SET(PANTHEIOS_L_FRONT_DBG "")
		SET(PANTHEIOS_L_FRONT_RLS "")
	ELSE ()
		FILE(GLOB PANTHEIOS_L_FRONT_DBG "${PANTHEIOS_LIBRARY_DIRS}/pantheios.1.fe.${PANTHEIOS_FRONTEND}.${PANTHEIOS_LIB_LINKTYPE}.debug.lib")
		FILE(GLOB PANTHEIOS_L_FRONT_RLS "${PANTHEIOS_LIBRARY_DIRS}/pantheios.1.fe.${PANTHEIOS_FRONTEND}.${PANTHEIOS_LIB_LINKTYPE}.lib")
	ENDIF ()

	SET(PANTHEIOS_LIBRARIES optimized ${PANTHEIOS_L_CORE_RLS} ${PANTHEIOS_L_UTIL_RLS} ${PANTHEIOS_L_BACK1_RLS} ${PANTHEIOS_L_BACK2_RLS} ${PANTHEIOS_L_FRONT_RLS} debug ${PANTHEIOS_L_CORE_DBG} ${PANTHEIOS_L_UTIL_DBG} ${PANTHEIOS_L_BACK1_DBG} ${PANTHEIOS_L_BACK2_DBG} ${PANTHEIOS_L_FRONT_DBG})

ENDIF()
	

# handle the QUIETLY and REQUIRED arguments and set Pantheios_FOUND to TRUE if 
# all listed variables are TRUE
INCLUDE(${CMAKE_CURRENT_LIST_DIR}/FindPackageHandleStandardArgs.cmake)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Pantheios
                                  REQUIRED_VARS PANTHEIOS_LIBRARIES PANTHEIOS_INCLUDE_DIR
                                  VERSION_VAR PANTHEIOS_VERSION_STRING)
								  

mark_as_advanced(PANTHEIOS_INCLUDE_DIR PANTHEIOS_LIBRARIES PANTHEIOS_ROOT)



More information about the CMake mailing list