[CMake] I'm confused with Find*.cmake and *-config.cmake

Benoit Thomas benoit.thomas at gameloft.com
Tue Apr 20 15:40:11 EDT 2010


On 2010-04-20 03:27, Michael Hertling wrote:
> On 04/19/2010 10:07 PM, Benoit Thomas wrote:
>
>    
>> I'm using an external library which is already compiled. I have wrapped
>> the library in a MyLib.cmake and use it in cmake as an imported library.
>> It works fine, but since the include line uses relative path, it changes
>> from projects to projects and in some case it looks just wrong.
>>      
> Just for my understanding: What exactly do you mean with "wrapped the
> library in a MyLib.cmake" and "use it in cmake as an imported library"?
>    
I'm migrating Visual Studio project to CMake. The Visual Studio projects 
use heavy configurations (20+). So, when I used a library which hasn't 
yet been converted to cmake, I usually only create a small 
CMakeLists.txt for it which look like this:

add_library (MyLib IMPORTED)
set_target_properties (MyLib PROPERTIES IMPORTED_LOCATION_CONFIG1 
"${MYLIB_ROOT_DIR}/bin/config1/MyLib.lib")
set_target_properties (MyLib PROPERTIES IMPORTED_LOCATION_CONFIG2 
"${MYLIB_ROOT_DIR}/bin/config2/MyLib.lib")
...
set_target_properties (MyLib PROPERTIES IMPORTED_LOCATION_CONFIG20 
"${MYLIB_ROOT_DIR}/bin/config20/MyLib.lib")

Then, in another project I'm doing (something like):

include (../../../somewhere/MyLib/CMakeLists.txt)

add_executable (MyExe)
target_link_libraries (MyExe MyLib)

But this line didn't feel right:
include (../../../somewhere/MyLib/CMakeLists.txt)

I renamed the CMakeLists.txt to MyLib.cmake as it's not really a project 
file on his own. Also, the path is never  the same for all projects so 
that's why I wanted to change the format to a find_package (it's 
cleaner, and doesn't change if projects are moved).

>> I want to change this to something more like:
>>
>> find_package (MyLib)
>> include (MYLIB_CMAKE_FILE)
>> # add_executable and stuff
>> target_link_libraries (MyExe MyLib)
>>      
> This is a possible approach which is also followed by FindQt4.cmake,
> but, for several reasons, you shouldn't explicitly refer to "MyLib"
> in TARGET_LINK_LIBRARIES(); use variables from FIND_PACKAGE(MyLib).
>
>    
I though about using variables, but target_link_libraries doesn't 
support configurations, and the other alternative I found was using 
LINK_FLAGS. However, using imported library and target_link_libraries 
gave me a clean solution.
>> In the book, there is an example which seems to do more what I want and
>> use *-config.cmake, which give something like
>>
>> find_package (MyLib)
>> # no include, since the MyLib-config.cmake already took care of the include
>> # add_executable and stuff
>> target_link_libraries (MyExe MyLib)
>>      
> What is meant with "took care of the include"? I don't have the book. ;)
>    
When I look at FindXXX.cmake, they create variables and macros, but they 
don't add any targets to your project (I assume this was standard). In 
the book, there's an example about creating XXX-config.cmake files. From 
my understanding, the XXX-config.cmake include a XXX-targets.cmake which 
create the imported target.

So I was a little confuse about the fact that if I write code like

find_package (MyLib)

# If MyLib is a FindMyLib.cmake, the following code should like
if (MyLib_FOUND)
     include (MyLib_USE_FILE) # which would do the add_library (MyLib 
IMPORTED)
else()
     # print some fatal error message...
endif()

# But if MyLib is a MyLib-config.cmake, there's nothing else to do; 
find_package will display an error message if MyLib isn't found, and if 
it's found, MyLib-config.cmake will include MyLib-target.cmake

>> Part of what I don't understand is when a user use the find_package
>> command, is he expecting to load a Find* file or a *-config file (or he
>> doesn't care?), [...]
>>      
> In general, he doesn't care; in particular, she can tell
> FIND_PACKAGE() to look for a config file exclusively.
>    
The more I'm reading about the subject, the more I'll go with a 
XXX-config.cmake file which will take care of importing the library. And 
as you mention, I'll try to use variables as much as possible, but in my 
context is a little hard :) I'll also use the NO_MODULE option to make 
it clear I'm looking for a config file and not a module.
>
> As for myself: Yes, absolutely. FIND_PACKAGE(MyLib) should try to find
> anything necessary to use Mylib, i.e. preprocessor definitions, include
> directories, libraries etc., and communicate the results as variables,
> e.g. MyLib_DEFINITIONS, MyLib_INCLUDE_DIRS, MyLib_LIBRARIES etc., but it
> should not have a direct, hard-coded impact on the configuration process
> as a target definition would be; this should be reserved for the calling
> CMake script. BTW, why would you need a target "MyLib" here? As you said
> before, the library is external and already compiled.
>    
The reason why I need a MyLib target is because of the 20+ 
configurations... Make my life more easy that way (Keeping the 20+ 
configurations in a single project is not really my call btw...)

> 'hope this helps a little bit, and to CMake experts: Feel free to beat
> me if I'm telling nonsense, but give some enlightenment afterward. ;-)
>    
Yeah, it helped a lot, thank you very much !!!
Ben.



More information about the CMake mailing list