<html>
<head>
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
</head>
<body text="#000000" bgcolor="#FFFFFF">
Hey all,<br>
<br>
Since I did not receive a reply to my previous mail, I decided to
write a minimal example explaining my problem, where I kept al the
names as I used in my previous mails. I hope that after seeing my
example, someone can explain me what I am doing wrong here. I
included a script that reproduces the problem.<br>
<br>
Cheers,<br>
Sven<br>
<br>
<div class="moz-cite-prefix">On 06/10/2016 01:34 PM, Sven Baars
wrote:<br>
</div>
<blockquote cite="mid:575AA5B7.7060408@rug.nl" type="cite">
<meta content="text/html; charset=utf-8" http-equiv="Content-Type">
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>
</blockquote>
<br>
</body>
</html>