<div dir="ltr">(Includes earlier reply from me not sent to the list)<div><br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Jan 12, 2018 at 9:10 AM, Lucas Soltic <span dir="ltr"><<a href="mailto:lucas.soltic@orange.fr" target="_blank">lucas.soltic@orange.fr</a>></span> wrote:<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><span class=""><blockquote type="cite"><div><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div><div class="gmail_extra"><div class="gmail_quote">On Thu, Jan 11, 2018 at 10:09 AM, Lucas Soltic<span class="m_-4456960121019402337Apple-converted-space"> </span><span dir="ltr"><<a href="mailto:lucas.soltic@orange.fr" target="_blank">lucas.soltic@orange.fr</a><wbr>></span><span class="m_-4456960121019402337Apple-converted-space"> </span>wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space">Hello,<div><br></div><div>I'm trying to create a relocatable package configuration file but I'm having a hard time with absolute paths that are used during the build.</div><div>Note that I use CMake 3.10.0.</div><div><br></div><div>First of all for the include path I'm using this:</div><div><div><font face="Menlo">target_include_directories(MyS<wbr>taticTarget PUBLIC</font></div><div><font face="Menlo">                           $<BUILD_INTERFACE:${PROJECT_S<wbr>OURCE_DIR}/include></font></div><div><font face="Menlo">                           $<INSTALL_INTERFACE:include>)</font></div></div><div><br></div><div>This does work but according to the doc it should not : <a href="https://cmake.org/cmake/help/latest/manual/cmake-generator-expressions.7.html?highlight=build_interface#output-expressions" target="_blank">https://cmake.org/cmake/help<wbr>/latest/manual/cmake-generator<wbr>-expressions.7.html?highlight=<wbr>build_interface#output-express<wbr>ions</a></div><div>The doc of BUILD_INTERFACE says: "Content of ... when the property is exported using export(), or when the target is<span class="m_-4456960121019402337Apple-converted-space"> </span><u>used by another target in the same buildsystem</u>. Expands to the empty string otherwise."</div></div></blockquote><div><br></div><div>I'm with you to here.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div>So according to the doc, when compiling the target MyTarget, the include dir I gave should not be used. Which seems consistent with the other uses of INTERFACE wording in CMake language. But it actually behaves like PUBLIC rather than INTERFACE. This is fine to me but inconsistent… :)</div></div></blockquote><div><br></div><div>This part is less clear. What is MyTarget? Is it something you link to MyStaticTarget? If so, then the include dir<span class="m_-4456960121019402337Apple-converted-space"> </span><i>should</i><span class="m_-4456960121019402337Apple-converted-space"> </span>be used. In the target_include_directories() call above, the content of the generator expressions will both be treated as PUBLIC if they expand to something non-empty. Don't be confused by the word INTERFACE in the generator expressions, it is the PUBLIC before them that is controlling the visibility/transitivity of these include paths. Think of BUILD_INTERFACE as meaning "only when I'm building with this thing" and INSTALL_INTERFACE as "only when this thing is installed (i.e. put this in an export file but don't use it in the build I created it in)".</div></div></div></div></div></div></blockquote><div><br></div></span><div>Arg I messed up my original e-mail. "MyTarget" is the same as "MyStaticTarget". I just didn't rename everywhere…</div><div>I rather have a clear vision about what INTERFACE, PUBLIC and PRIVATE keywords mean when used in target_...() commands so I understand that my paths will be used both by MyStaticTarget and targets that depend on it. It's just that BUILD_INTERFACE's documentation is misleading. Apart from that I deduced the same as what you said :)</div><span class=""><br><blockquote type="cite"><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div><div class="gmail_extra"><div class="gmail_quote"><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div>The second point is about libraries to link when using my project. My project exports a<span class="m_-4456960121019402337Apple-converted-space"> </span><u>static</u><span class="m_-4456960121019402337Apple-converted-space"> </span>library that depends on other libraries. These libraries are found (when generating my project through cmake) through calls like find_package(OpenGL). This provides a variable that contains an absolute non-relocatable path.<br></div><div><br></div><div>I've tried doing things like this:</div><div><font face="Menlo">target_link_libraries(MyStatic<wbr>Target PRIVATE<br>                      $<BUILD_INTERFACE:${OpenGL_abs<wbr>olute_path}><br>                      $<INSTALL_INTERFACE:${OpenGL_r<wbr>elocatable_link_flag}>)</font></div><div><br></div><div>According to <a href="https://cmake.org/pipermail/cmake/2016-May/063400.html" target="_blank">https://cmake.org/pipermail<wbr>/cmake/2016-May/063400.html</a>, for static libraries, PRIVATE link dependencies become "PUBLIC", which is ok.</div></div></blockquote><div><br></div><div>They only sort-of become PUBLIC. Only the linking part gets promoted to PUBLIC, not things like include paths, compiler defines or compiler options.</div></div></div></div></div></blockquote><div><br></div></span><div>Indeed. So far so good :)</div><span class=""><br><blockquote type="cite"><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div>And I could see that the link flag for this "private" dependency got exported in the generated config.<span class="m_-4456960121019402337Apple-converted-space"> </span></div></div></blockquote><div><br></div><div><br></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div>Short version: I<span class="m_-4456960121019402337Apple-converted-space"> </span><i>think</i><span class="m_-4456960121019402337Apple-converted-space"> </span>if you use the import libraries that the FindOpenGL module provides rather than the variables, you will have more success.</div></div></div></div></div></blockquote></span><blockquote type="cite"><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div><div class="gmail_extra"><div class="gmail_quote"><div><br></div><div>Long version (this is going to get quite involved, sorry): If your static library relies on an external library and you want that external dependency to be part of the exported definition of your target, then you'll have to do some extra work in how you provide your installed package. If you are using install(EXPORT) to produce files that other projects pick up via find_package(), then you probably want to be using find_dependency() from the<span class="m_-4456960121019402337Apple-converted-space"> </span><a href="https://cmake.org/cmake/help/latest/module/CMakeFindDependencyMacro.html" target="_blank">CMakeFindDependencyMacro</a>mo<wbr>dule from inside your package's XXXConfig.cmake file. This will define the imported targets that your package's import target should, I believe, be expecting to exist and rely on as an interface dependency. Sketching it out, it might look something like this (untested, tired brain, so no guarantees!):</div><div><br></div></div></div><span class=""><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace"># Contents of XXXConfig.cmake:</font></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">include(CMakeFindDependencyMac<wbr>ro)</font></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">find_dependency(OpenGL)   # Makes sure the OpenGL::GL import target exists</font></div></div></div><div class="gmail_extra"><div class="gmail_quote"><div><font face="monospace, monospace">include(XXXexports)       # The file you are probably already creating now for your package</font></div></div></div><div class="gmail_extra"><div class="gmail_quote"><br></div></div></blockquote><div class="gmail_extra"><div class="gmail_quote"><div>I think the exported target will already have OpenGL::GL in the list of interface libraries for the MyStaticTarget import target created by XXXexports in the above, but if not it should be easy enough to add that to the end of the XXXConfig.cmake sample code (maybe a call to target_link_libraries() or set_property(TARGET MyStaticTarget...)).</div><div><br></div><div>Back in your original project, the target_link_libraries() call should be simplified down to:</div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><br></div></div></blockquote><div class="gmail_extra"><div class="gmail_quote"><div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><font face="monospace, monospace">find_package(OpenGL REQUIRED)</font></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div class="gmail_extra"><div class="gmail_quote"><font face="monospace, monospace">target_link_libraries(MyStatic<wbr>Target PRIVATE </font><span style="font-family:monospace,monospace">OpenGL::GL)</span></div></div></blockquote><font face="arial, helvetica, sans-serif"><br></font><div class="gmail_extra"><div class="gmail_quote"></div></div></div><div><font face="arial, helvetica, sans-serif">The MyStaticTarget will then have a link dependency on OpenGL::GL in both the build tree and when installed. It's very likely I've made errors in the above, but hopefully there's enough there for you to find your way to a solution.</font></div></div></div></span></div></div></blockquote><div><br></div><div>I like this solution, but I can't use it as is. For 2 reasons: OpenGL was one example, but I also have other dependencies that don't provide an imported target, and the second reason is that this imported target for OpenGL is only available since CMake 3.8 and I must support at least up to 3.5.</div><div><br></div><div>Also I said "as is" because this makes me think that I could potentially define, in my project, an IMPORTED or INTERFACE library for OpenGL that would be used in a target_link_libraries() in my project. And in <Project>Config.cmake it would allow me to make use of the find_dependency() you suggested to create again this target.</div></div></div></blockquote><div><br></div><div>Indeed. At the point where you call find_package(OpenGL), you could then test for the existence of the OpenGL::GL library and if it doesn't exist, you can define it yourself. This should allow you to use the import library with CMake versions earlier than the one where the OpenGL import library support was added.</div><div><br></div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><div><br></div><div>The only downside I can see with this is that the <Project>Config.cmake file will need to be kept synchronized with the dependencies that are used in various places in my project, instead of having this done automatically (and thus always synchronized).</div></div></div></blockquote><div><br></div><div>Pretty much. I think there have been some discussions in the issue tracker and/or merge requests over the past year related to how to propagate dependencies similar to this topic. It's a difficult area with no easy solution unfortunately.</div><div><br></div><div> </div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div><span class=""><blockquote type="cite"><div dir="ltr" style="font-family:Helvetica;font-size:12px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px"><div class="gmail_extra"><div class="gmail_quote"><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word;line-break:after-white-space"><div>But the problem is that whatever I put for INSTALL_INTERFACE, it is ignored and not written to the generated cmake config file. The generated CMake config file just takes into account what I put for BUILD_INTERFACE. Contrary to what happened with include directories.</div></div></blockquote><div><br></div><div>This sounds strange. Can you provide a simple, complete project that reproduces the problem? If so, please open an issue in the bug tracker and attach it.</div></div></div></div></blockquote><div><br></div></span><div>I reproduced it with a minimal example, and found out what is causing the issue.</div><div>At the beginning of the project, if I put cmake_minimum_required(<wbr>VERSION 2.8.3) (which is what the project I'm working in currently uses) then in the generated config, only what's specified in BUILD_INTERFACE generator expression is taken into account.</div><div><br></div><div>If I change the requirement to version 3.0, the generated config file contains what I specified for INSTALL_INTERFACE generator expression.</div><div>I never realized that this command had an effect on CMake policies. At least now everything makes sense :)</div></div></div></blockquote></div><br clear="all"><div><br></div><div><br></div>-- <br><div class="gmail_signature" data-smartmail="gmail_signature"><div dir="ltr"><div><div dir="ltr"><div><div dir="ltr">Craig Scott<br><div>Melbourne, Australia</div><div><a href="https://crascit.com" target="_blank">https://crascit.com</a><br></div></div></div></div></div></div></div>
</div></div></div>