Hi Andreas,
On 11.11.08 14:12:39, Fernando Cacciola wrote:
Hi Andreas,
On 10.11.08 12:01:13, Fernando Cacciola wrote:
The CGAL library (www.cgal.org) uses cmake as build system. Thus, our
users do:
find_package(CGAL REQUIRED)
include( ${CGAL_USE_FILE} )
...
UseCGAL.cmake, as all such files, call include_directories,
add_definitions and overrides (under certain circumstances) the
compiler/linker flags that were used to build the CGAL library.
These are all settings that affect any target added after the
inclusion of UseCGAL.cmake.
However, following the recommended practice (according to the
documentation of the deprecated link_libraries command), UseCGAL DOES
NOT call link_libraries. Instead, it realies on the user calling
target_link_libraries himself.
Well, I'm questioning this recommended practice because it's half
baked: It makes sense to allow users to control which targets are
linked against CGAL, but NOT if OTOH they cannot control which
targets are given the CGAL include directories, definitions and
flags.
That is, IMO, target_link_libraries makes little sense in the absence
of target_include_directories, target_add_definitions and
target_*_FLAGS.
What it's so special about linking that only that command can be made
target specific???
Or am I missing something?
There are projects that have headers that are usable without linking
against any library. There are also projects installing their headers into
a common place, that have multiple libraries. In that latter case you'd
have include_directories() point to the common place for the headers, but
obviously you can't know which of the libraries needs to be linked in.
Who is you in your sentence?
The UseXYZ modules which depends on the parameters to find_package(XYZ)
certainly knows it.
No it doesn't. UseXXX is a "global" thing, so it can't know which of the
targets in a project need which files.
Right, but the again a typical UseXYZ would do:
include_directories( ${XYZ_INCLUDE_DIR} )
add_definitions( ${XYZ_DEFINITIOS} )
set( CMAKE_CXX_FLAGS "$XYZ_CXX_FLAGS") )
So it doesn't know which of your targets need the include dirs, the
definitions and the flags.. and it doesn't care.
Boost is a good example (albeit it doesn't use cmake to build itself).
There are various libraries shipped with it, they all install their headers
into <includedir>/boost/<libraryname>/ and the libs are of course directly
in <libdir>. And its common practice to have only <includedir>/boost in the
include-directories.
And BOOST_LIBRARIES is defined as a list of all libraries indicated by
the user as boost components.
Right, but those are all I'm going to use in my project, which might or
might not be different from those that I want on target A and B.
Right.
So, if there where a UseBoost.cmake file
which would do
include_directories( ${BOOST_INCLUDE_DIR} )
add_definitions( ${BOOST_DEFINITIONS} )
then wouldn't it make sense for it to do
link_libraries( ${BOOST_LIBRARIES} )
as well?
That would mean _all_ my targets link against those libraries, which is
completely wrong.
Right.
In fact I don't understand why include_directories and
add_definitions are not deprecated as well
Which is precisely my point!! :)
target_link_libraries, which is GREAT, is actually pretty useless
without target_include_directories, target_add_definitions and
<TARGET>_CMAKE_CXX_FLAGS.
Yet OTOH given that those do not exists, it is just plain silly to
recommend not using link_libraries, because it gets less than half the
story right.
And IMO is equally silly to follow the recomendation and end up doing
what most Use files typically do: to set so much that affects all
subsequent targets, even compiler and linker flags, BUT simply define a
variable XYZ_LIBRARY so a user can decide which target to link againt
XYZ_LIBRARY.
I mean, being able to control this is cool, sure, but why can I only
control that and not the other equally critical settings???
IMO, if a user won't have real control over which targets actually use
XYZ (in all the extent to which using XYZ, as defined by
find_package(XYZ), means) then I rather don't bother them requiring
users to call target_link_libraries by hand (while everything else is
setup by the Use file itself). It's just silly.
So to restat my point, if a UseFile does this:
include_directories( ${XYZ_INCLUDE_DIR} )
add_definitions( ${XYZ_DEFINITIOS} )
set( CMAKE_CXX_FLAGS "$XYZ_CXX_FLAGS") )
which shouldn't under the argument of "what if I don't want that for all
my targets", then it should do this as well:
link_libraries( ${XYZ_LIBRARIES} )
Best
Fernando
_______________________________________________
CMake mailing list
CMake@cmake.org
http://www.cmake.org/mailman/listinfo/cmake