[CMake] Contribute two new find package implementation.

Michael Hertling mhertling at online.de
Sun Oct 9 02:01:38 EDT 2011


On 10/07/2011 07:06 PM, Eric Noulard wrote:
> 2011/10/7 Mathias Fröhlich <M.Froehlich at science-computing.de>:
>> On Friday 07 October 2011, Eric Noulard wrote:

>>> Concerning 1516 and 1516e specific module may be it would be interesting
>>> to only have one module "FindRTI.cmake" .
>> Sure this is there and finds the rti13 libs.
>>
>>> I think we cannot really use the VERSION argument of find_package
>>> but may be
>>>
>>> find_package(RTI COMPONENTS HLA13 IEEE1516)
>>> would be nice?
>> Hmm, I have done seperate versions because I was willing to find all three
>> variants of rti libs. That means if all three are installed I would like to
>> find all of them and have them all available within the same applications
>> build system.
> 
> Yes.
> 
> find_package(RTI)
>    would find all of them 1.3, 1516 and 1516e (which is 1516-2010 right?)
>    This would define
>       RTI13_FOUND if 1.3 compliant RTI is found
>       RTI1516_FOUND if 1516 compliant RTI is found
>       RTI1516e_FOUND ...

Due to [1], the variables should ne named RTI_RTI{13,1516{,e}}_FOUND,
i.e. <PACKAGE>_<COMPONENT>_FOUND. However, there might be a problem
with the RTI_FOUND variable regarding backwards compatibility: Since
FIND_PACKAGE(RTI) - without specification of any components - should
behave the same with the current single-component FindRTI.cmake as
well as with a future multi-component one, RTI_FOUND must be FALSE
even if a 1516 implementation is detected, i.e. RTI_FOUND does not
indicate an 1516 package's presence if FIND_PACKAGE(RTI) is invoked
without components. This might be surprising at first glance, but is
a particular problem when a single-component find module is advanced
towards multiple components. A possible conceptual solution could be:

- FIND_PACKAGE(RTI ...) must never run into config mode so that the
  FindRTI.cmake module retains control of the RTI_FOUND variable; a
  config file would mean that RTI_FOUND is forcedly set to TRUE.
  Since the diverse RTI packages stem from different projects,
  this should be well feasible.
- Calling FIND_PACKAGE(RTI) without components mimics the current
  behavior, i.e. only a 1.3 package is searched, the variables are
  set up like the single-component FindRTI.cmake does it now, and
  RTI_FOUND just indicates the presence of a 1.3 package even if
  a 1516 package is available on the system.
- Calling FIND_PACKAGE(RTI COMPONENTS HLA13) basically does the same,
  but behaves as expected for a component-aware find module, i.e. it
  also looks for a 1.3 package only, but sets up the variables right
  in a multi-component manner: RTI_HLA13_{FOUND,LIBRARY,INCLUDE_DIR}.
  RTI_FOUND indicates whether anything about RTI has been detected;
  actually, this merely means that the component-specific *_*_FOUND
  variables have received defined values, possibly even limited to
  the components explicitly requested via the FIND_PACKAGE() call.

Anyway, a multi-component FindRTI.cmake is the way to go, IMO, and
should be strongly preferred to the addition of any further find
modules which are closely related and differ just slightly.

> find_package(RTI COMPONENT RTI1516)
> 
> would only search for 1516.
> 
> find_package(RTI COMPONENT RTI13 RTI1516)
> 
> search for 1.3 and 1516 only etc...
> 
>> Is this possible to implement this within a single find_package call?
> 
> This is possible as long as the resulting variables are separate.
> (in our case there is some RTIxxx prefix)

Note that there may be difficiulties w.r.t. possible prerequisites in
this way: The *_*_{LIBRARY,INCLUDE_DIR} variables contain information
about the related component only, i.e. without prerequisite libraries
and include directories. The full information is provided by the non-
cached component-unspecific *_{LIBRARIES,INCLUDE_DIRS} variables, i.e.

FIND_PACKAGE(RTI COMPONENTS HLA13 RTI1516 RTI1516E)

would return RTI_{LIBRARIES,INCLUDE_DIRS} suitable to use the HLA13
and RTI1516 and RTI1516E components in the same target, whereas the
RTI_*_{LIBRARY,INCLUDE_DIR} variables don't comprise the respective
component's possible prerequisites. Thus, in order to use one of the
required components separately from the others, one can rely neither
on RTI_{LIBRARIES,INCLUDE_DIRS} nor on RTI_*_{LIBRARY,INCLUDE_DIR}.
Instead, one should use multiple FIND_PACKAGE() calls and save
their results immediately:

FIND_PACKAGE(RTI COMPONENTS HLA13)
SET(HLA13_LIBRARIES ${RTI_LIBRARIES})
SET(HLA13_INCLUDE_DIRS ${RTI_INCLUDE_DIRS})

FIND_PACKAGE(RTI COMPONENTS RTI1516)
SET(RTI1516_LIBRARIES ${RTI_LIBRARIES})
SET(RTI1516_INCLUDE_DIRS ${RTI_INCLUDE_DIRS})

FIND_PACKAGE(RTI COMPONENTS RTI1516E)
SET(RTI1516E_LIBRARIES ${RTI_LIBRARIES})
SET(RTI1516E_INCLUDE_DIRS ${RTI_INCLUDE_DIRS})

In other words: A multi-component FIND_PACKAGE() possibly needs to be
called multiple times, each time with the set of components you intend
to use collectively. BTW, this is one of the reasons why I am strongly
in favor of FIND_PACKAGE() not accumulating results, i.e. the results/
effects of a FIND_PACKAGE() call should not depend on the results/
effects of a previous call in the same scope, cf. FindQt4.cmake.

>> I am fine with anything that allows me to build an application that uses all
>> of these libraries at the same time.
>> ... Think of a bridge that translates from one rti version to an other one. Or
>> may be an object browser that allows to connect to different rti's.
> 
> I think I understand the need.

>>> I'll help to review and test the module (at least on Linux).

FindRTI1516{,E}.cmake's quick review has drawn my attention to the
invocations of CHECK_CXX_SOURCE_COMPILES() used to distinguish the
1516{,E} libraries: IMO, one should be prepared that FIND_PACKAGE()
isn't called for the usual purposes; perhaps, the results are to be
used just for documentation or a textual analysis of a header file
or whatever. Thus, one should not rely on the assumption that FIND_
PACKAGE() is called from within a setup that allows the compilation
of anything; rather, CHECK_CXX_SOURCE_COMPILES() or another command/
function that executes a program is quite critical in a find module.
At least, such checks should be protected by a variable, i.e. they
are performed solely with the user's agreement, or implemented as
supplementary functions, e.g. CHECK_RTI1516{,E}_SOURCE_COMPILES().

Regards,

Michael

[1] ${CMAKE_ROOT}/Modules/readme.txt


More information about the CMake mailing list