<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body bgcolor="#FFFFFF" text="#000000">
Hey Chuck,<br>
<br>
In ATargets.cmake it says<br>
<br>
add_library(a SHARED IMPORTED)<br>
<br>
and in BTargets.cmake it says<br>
<br>
add_library(b SHARED IMPORTED)<br>
<br>
However, if I build C it will say<br>
<br>
/usr/bin/ld: cannot find -la<br>
<br>
when I do<br>
<br>
find_package(B)<br>
target_link_libraries(c b)<br>
add_executable(main main.cpp)<br>
target_link_libraries(main c)<br>
<br>
This, I think, because the 'b' target depends on 'a' but doesn't
know where 'a' is located, because this is not described in
BTargets.cmake.<br>
<br>
Sven<br>
<br>
<div class="moz-cite-prefix">On 06/08/2016 06:07 PM, Chuck Atkins
wrote:<br>
</div>
<blockquote
cite="mid:CAOXZzG6KV1ocxq7a_nc_9YU2qgtX+5UmkO8J6U6AFL0CkoTT7A@mail.gmail.com"
type="cite">
<div dir="ltr">If the projects are each providing their own
Config.cmake file then you probably will want to use those
instead of Find modules. Instead of using the Foo_Bar_LIBRARIES
variable though, try using the actual imported targets from the
config files. Those should have the appropriate dependency
information. If you're not sure what they are you should be able
to dig through the provided Config.cmake and Targets.cmake files
for FooBar and see which targets are created bu
"add_library(FooBar::Foo ... IMPORTED)".<br>
</div>
<div class="gmail_extra"><br clear="all">
<div>
<div class="gmail_signature" data-smartmail="gmail_signature">
<div dir="ltr">- Chuck<br>
</div>
</div>
</div>
<br>
<div class="gmail_quote">On Wed, Jun 8, 2016 at 11:31 AM, Sven
Baars <span dir="ltr"><<a moz-do-not-send="true"
href="mailto:s.baars@rug.nl" target="_blank">s.baars@rug.nl</a>></span>
wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0
.8ex;border-left:1px #ccc solid;padding-left:1ex">
<div bgcolor="#FFFFFF" text="#000000"> In my case all
projects provide their own FooBarConfig.cmake, but not a
FindFooBar.cmake. For this reason I wanted to use those,
because I thought it saves me the effort of writing a lot
of FindFooBar.cmake files, and it also seemed like the
right way to do it, because it provides things like
FooBar_LIBRARIES, which is what I need. The reason I said
that I create my own FooBarConfig.cmake, is because I want
to use CMake properly in my own project, so I also want to
provide a FoorBarConfig.cmake file for my users. So even
if the projects I use don't do everything properly, I
still want to do it properly myself. The problem in this
case is that I'm not sure what the proper way is. If the
FoorBarConfig.cmake file is not enough to handle the
dependencies I encounter, should I provide a
FindFooBar.cmake file or something, instead of just the
FooBarConfig.cmake? And meanwhile also write a
FindFooBar.cmake file for all my dependencies?<br>
<br>
Another reason why this seems odd to me, is because if N
different projects use FooBar, then also possibly N
different versions of FindFooBar.cmake are created by all
the different projects (I have actually already seen this
a lot). That is the case, because the FindFooBar.cmake
file is not provided by the FooBar project, unlike the
FooBarConfig.cmake.<br>
<br>
Cheers,<br>
Sven
<div>
<div class="h5"><br>
<br>
<div>On 06/08/2016 03:11 PM, Chuck Atkins wrote:<br>
</div>
<blockquote type="cite">
<div dir="ltr">
<div>
<div>
<div>
<div>
<div>
<div>The FooBarConfig.cmake is something
that should be generated by FooBar's
build. The reason you don't get
absolute paths for the "libraries"
from a package config file is that
they're not actually libraries but
imported targets. The imported target
let's you treat "foo" as though it
were a library built by your project.
It then has the appropriate target
properties set on it ti define the
full path to it's library, etc. That
being said, if you're manually
creating the FooBarConfig.cmake that's
not really the right approach. If the
FooBar buil;d doesn't actually
generate it's own FooBarConfig.cmake
file then you'll want to create you're
own FindFooBar.cmake. A bare bones
find module that creates an imported
target would look something like this:<br>
<span
style="font-family:monospace,monospace"><br>
if(NOT FooBar_FOUND AND NOT TARGET
FooBar::FooBar)<br>
find_path(FooBar_INCLUDE_DIR
FooBar.h)<br>
find_library(FooBar_LIBRARY
FooBar)<br>
<br>
include(FindPackageHandleStandardArgs)<br>
find_package_handle_standard_args(FooBar<br>
FOUND_VAR FooBar_FOUND<br>
REQUIRED_VARS FooBar_INCLUDE_DIR
FooBar_LIBRARY<br>
)<br>
endif()<br>
<br>
if(FooBar_FOUND AND NOT TARGET
FooBar::FooBar)<br>
add_library(FooBar::FooBar UNKNOWN
IMPORTED)<br>
set_target_properties(FooBar::FooBar
PROPERTIES<br>
IMPORTED_LOCATION
${FooBar_LIBRARY}<br>
INTERFACE_INCLUDE_DIRECTORIES
${FooBar_INCLUDE_DIR}<br>
)<br>
endif()</span><br>
<br>
</div>
Then in your project you can use:<br>
<br>
</div>
<span
style="font-family:monospace,monospace">find_package(FooBar)<br>
</span></div>
<span
style="font-family:monospace,monospace">add_library(MyLib
supercoolfiles.cxx)<br>
</span></div>
<span style="font-family:monospace,monospace">target_libkLibraries(MyLib
FooBar::FooBar)<br>
</span><br>
</div>
Where this starts to get really helpful in your
situation is if you have an imported target for
A, B, and C, then you can create the appropriate
dependencies. Say, for example, you have a
FindA.cmake that follows the pattern above and
generates an A::A target. Then in your
FindB.cmake you can have:<br>
<br>
<span style="font-family:monospace,monospace">if(NOT
B_FOUND AND NOT TARGET B::B)<br>
find_path(B_INCLUDE_DIR B.h) <br>
find_library(B_LIBRARY B)<br>
<br>
include(FindPackageHandleStandardArgs)<br>
find_package_handle_standard_args(B<br>
FOUND_VAR B_FOUND<br>
REQUIRED_VARS B_INCLUDE_DIR B_LIBRARY<br>
)<br>
<br>
<b> find_package(A QUIET)<br>
if(A_FOUND)<br>
set(B_Extra_Deps A::A)<br>
endif()</b><br>
endif()<br>
<br>
if(B_FOUND AND NOT TARGET B::B)<br>
add_library(B::B UNKNOWN IMPORTED) <br>
set_target_properties(B::B PROPERTIES<br>
IMPORTED_LOCATION ${B_LIBRARY}<br>
INTERFACE_INCLUDE_DIRECTORIES
${B_INCLUDE_DIR}<br>
)<br>
<b> if(B_Extra_Deps)<br>
set_target_properties(B::B PROPERTIES<br>
INTERFACE_LINK_LIBRARIES
${B_Extra_Deps}<br>
)<br>
endif()</b><br>
endif()</span><br>
<br>
</div>
and similarly for FindC.cmake. Since A::A, B::B,
and C::C are actual proper CMake targets and not
just library files then they carry with them
associated target dependency information. In
CMake vernacular we refer this as "target usage
requirements" since the target caries with it all
the necessary information for something to
actually use it, whether that's just extra link
libraries or also extra include directories and
compile definitions needed. The <span
style="font-family:monospace,monospace">Package::Target</span>
naming convention is the idea that each package
has it's own namespace where you may define
multiple targets.<br>
</div>
</blockquote>
<br>
</div>
</div>
</div>
</blockquote>
</div>
<br>
</div>
</blockquote>
<br>
</body>
</html>