[CMake] Best practices/preferred methods for linking external libraries

Michael Jackson mike.jackson at bluequartz.net
Tue Dec 6 11:08:16 EST 2011



On Dec 6, 2011, at 9:56 AM, Matthew LeRoy wrote:

> On Dec 5, 2011, at 5:57 PM, Michael Jackson wrote:
> 
>> On Dec 5, 2011, at 5:36 PM, Matthew LeRoy wrote:
>> 
>>> On Dec 4, 2011, at 11:59 AM, Michael Jackson wrote:
>>> 
>>>> On Dec 1, 2011, at 4:56 PM, Matthew LeRoy wrote:
>>>> 
>>>>> We began using CMake a few months ago for a couple of small cross-
>> platform projects, and we're still
>>>>> learning all the ins and outs and capabilities CMake has to offer, as
>> well as how to get the most
>>>>> out of CMake by using it "The Right Way". Right now, we're trying to
>> figure out how to link
>>>>> to external libraries that don't have "find" modules or CMake config-mode
>> files. After lots of
>>>>> reading in the wiki, mailing list, etc, it seems like there are several
>> different ways to do
>>>>> this, like writing "find" modules and/or config-mode files ourselves,
>> using the LINK_DIRECTORIES()
>>>>> command, importing/exporting targets, and others. What we're unsure of
>> is, what is the "preferred"
>>>>> or "officially supported" method?
>>>>> 
>>>>> To be a little more specific, we have two different library projects
>> (call them ProjectA and
>>>>> ProjectB) that both use CMake, but are developed independently. Further,
>> ProjectB depends (or will
>>>>> depend) on ProjectA; we've just recently gotten to the point on ProjectB
>> where we want to use some
>>>>> of the functionality in ProjectA, so we need to link to the ProjectA
>> library(ies). At first we
>>>>> thought we needed to write a "find" module for ProjectA -- but we really
>> have very little idea how
>>>>> to go about doing that. Other than the wiki page for finding libraries
>> that talks a little about
>>>>> writing "find" modules
>> (http://www.vtk.org/Wiki/CMake:How_To_Find_Libraries), is there any other
>>>>> documentation for writing a proper "find" module? Is there a particular
>> module that ships with CMake
>>>>> that is well-written that we should look at as a guide?
>>>> 
>>>> I had a project that I developed a few years back which was very close to
>> your situation. My project, call it "MXA", was the base library that got used
>> in a number of other projects. What I ended up doing was creating a
>> "FindMXA.cmake" file that got configured during the actual build of MXA to
>> make sure all the proper library names and location of resource files were
>> set correctly. Then I would install the MXA project into an external location
>> on my system, say /Users/Shared/Toolkits (OS X). I would manually copy the
>> FindMXA.cmake file to the other projects so that they could have the find
>> module available. In the beginning this made for a lot of manual copying when
>> MXA was changing a bunch but once MXA settled down to a consistent naming
>> scheme the "FindMXA.cmake" file never changed and so I found I did not have
>> to update the "FindMXA.cmake" file in the other projects that depended on
>> MXA.
>>>> I think in more recent years the CMake developers would rather see people
>> create the CMake Export files instead of developing the Find* module for my
>> project. In the end I just didn't have the time to properly investigate and
>> implement the CMake Export file so I never did it.
>>>> 
>>>> I think if the CMake community took a vote we could probably come up with
>> an "Exemplar" Find*.cmake file that is good for someone trying to develop a
>> new one. The issues that arise are that each of the projects that have a
>> "Find*.cmake" file are usually different in subtle ways which leads to issues
>> when you try to simply "copy/paste" from an existing module to create a new
>> module. It really just depends on what your "ProjectA" has installed. I am
>> going to provide my current "FindMXA.cmake" file at the end of this email and
>> leave it open for criticism/corrections. Maybe it will spur a conversation
>> that we can all benefit from.
>>> 
>>> Believe it or not, I've already been using your MXADataModel project as my
>> main 'exemplar' CMake-based project. I had read several messages from you in
>> the archives when I was first getting started with CMake, and I think at
>> least one of them also mentioned MXA, so I went to your website and saw that
>> the source was available so I thought I'd take a peek.
>>> 
>>> Anyway, let me clarify a little bit what we're trying to accomplish. We are
>> indeed trying to treat ProjectA and ProjectB as completely independent
>> projects (as Alan has suggested), and our plan is to version ProjectA and do
>> drops at specific milestones. ProjectB will use only the binary distribution
>> of ProjectA. We would like to make it so that ProjectB's source tree in
>> version control is entirely self-contained, so that we can simply sync down a
>> local copy in a fresh development environment and compile without having to
>> 'install' ProjectA first. Better yet, we may want to sync multiple copies of
>> ProjectB's source tree in separate locations on the same system, from
>> different instances in time where the version of ProjectA in use is
>> different, and be able to build and debug both separate copies of ProjectB
>> without having to worry about having multiple versions of ProjectA
>> 'installed'. Our thought here is to have part of ProjectA's source tree be a
>> collection of binary distributions of the various independent components that
>> is uses - one of which is ProjectA.
>>> 
>>> That being said, we are traditionally a Windows development shop and have
>> little experience setting up source trees in anything other than the "Visual
>> Studio" style of one root folder for the solution and subfolders for each
>> "project" in the solution, where everything is somewhat idiot-proof. I
>> realize that it's a bit beyond the scope of the CMake mailing list to be
>> discussing the finer points of source tree structure for general C++
>> programming, but we're open to whatever suggestions (or pointers to other
>> references) anyone may have as to the best way to go about accomplishing what
>> we're after, CMake-related or otherwise.
>>> 
>>> For the time being, I'll take a look at the FindMXA.cmake file to get an
>> idea of how I might write a Find* module for our ProjectA, since it sounds
>> like using CMake EXPORT files to accomplish what I described above may not be
>> possible. Your comments regarding the recent preference of using CMake EXPORT
>> files instead of Find* modules are exactly the kind of info I was looking for
>> originally, however.
>>> 
>>> Matt
>> 
>> What version control system are you using? Does it support "submodules" or
>> sub projects? I still think having a binary distribution is a bad thing but
>> in your case it may just work out ok.
>> 
>> The other fleeting thought I had was in ProjectB's Main CMakeLists.txt file
>> get the location of ProjectA and then do a
>> "add_subdirectory(${ProjectA_SOURCE_DIR})" and just plain build ProjectA
>> inside of ProjectB. Assuming of course ProjectA is small enough that
>> including it in a build will not overly slow things down. I have done that in
>> some other projects and it has turned out to work just fine.
>>  There are lots of examples where "add_external_project()" is used in this
>> way to bring in a build things like Zip, Tiff, Jpeg or other small projects.
>> 
>> Hope that helps
>> --
>> Mike Jackson <www.bluequartz.net>
> 
> We're using Perforce, which I'm fairly certain doesn't have anything like submodules
> or subprojects.
> 
> I'm curious, why is it your opinion that a binary distribution is a bad thing?
> How is using a binary distribution of our own ProjectA different/worse than
> a binary distribution of any of the libraries for which CMake ships a Find*.cmake
> module?

I have to remind myself that your product is not open but in fact closed to your company and development team. So have a binary distribution for _your_ particular circumstance probably isn't a bad thing because the development environment is very controlled.
 
 Sorry for the confusion. 

Mike Jackson


More information about the CMake mailing list