<html>
  <head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
  </head>
  <body text="#000000" bgcolor="#FFFFFF">
    Hey Cfyz,<br>
    <br>
    After reading your post to the list, it does indeed seem like we
    have the same problem. I also wrote a lot of homebrew code you
    mentioned at the end of the post, but it indeed always seems to
    always break something for some user of the code, even though it
    seems to work for everyone else. Hence my question if there is some
    "right" way of doing this with CMake, without all of the code I
    wrote to work around the problem.<br>
    <br>
    In the mean time I'll have a look at the code you wrote, but it
    seems very similar to something I already had, which broke for some
    users.<br>
    <br>
    Sven<br>
    <br>
    <div class="moz-cite-prefix">On 06/28/2016 02:35 PM, Cfyz wrote:<br>
    </div>
    <blockquote
cite="mid:CAEVjpKsjdj-XQxgD5M0QX-P3Vd-2ghNZ3rG5ho1NNWw9uZ7Ucg@mail.gmail.com"
      type="cite">
      <div dir="ltr">
        <div>
          <div>
            <div>
              <div>
                <div>
                  <div>
                    <div>
                      <div>
                        <div>
                          <div>
                            <div>Hello.<br>
                              <br>
                            </div>
                            I've posted a message a few days ago on a
                            very similar subject. Didn't know there was
                            a discussion already.<br>
                            <br>
                          </div>
                          The main problem in my opinion is that CMake
                          target exporting system does not handle
                          transitive dependencies at all. CMake handles
                          them correctly at the build step, but not at
                          the export. As I've noted in my message there
                          is a small hint on that being a conscious
                          decision: documentation about
                          target_link_libraries and relevant target
                          properties advises not to include paths to
                          dependencies into the target interface as it
                          would hard-code dependencies' locations.
                          Personally I do not agree with that as I see
                          neither any way around specifying paths to
                          dependencies not any substantial harm in that.
                          Maybe I am missing something but as far as
                          I've found there was not discussion about this
                          matter before.<br>
                          <br>
                        </div>
                        With that there are some ways to make transitive
                        dependencies work. Though you'll have to forsake
                        most of CMake's export machinery. Probably the
                        easiest way is to make each library export it's
                        full interface in the Foo_INCLUDE_DIRS /
                        Foo_LIBRARIES variables. By writing the
                        AConfig.cmake by hand you can figure out and
                        export the full path to the A. Therefore
                        AConfig.cmake will essentially be:<br>
                      </div>
                      <br>
                        get_filename_component(A_CONFIG_DIR
                      "${CMAKE_CURRENT_LIST_FILE}" PATH)<br>
                        find_library(A_LIB "A" HINTS
                      ${A_CONFIG_DIR}/../../../lib)<br>
                        set(A_INCLUDE_DIRS
                      ${A_CONFIG_DIR}/../../../include)<br>
                        set(A_LIBRARIES ${A_LIB})<br>
                        set(A_FOUND TRUE)<br>
                      <br>
                    </div>
                    From here on, every other library which care about
                    its dependencies will have to export its interface
                    in a similar way. However, since BConfig.cmake
                    cannot find A by itself, it will need some help from
                    the project configuration step. B project will need
                    to gather its interface and do a configure_file()
                    fixing B's interface dependencies in it:<br>
                    <br>
                  </div>
                    find_package(A)<br>
                </div>
                <div>  list(APPEND B_INTERFACE_INCLUDE_DIRS
                  ${A_INCLUDE_DIRS})<br>
                </div>
                  list(APPEND B_INTERFACE_LIBRARIES ${A_LIBRARIES}) #
                here comes the full path to A library<br>
                  ...<br>
              </div>
                configure_file(<a moz-do-not-send="true"
                href="http://BConfig.cmake.in">BConfig.cmake.in</a>
              ${CMAKE_CURRENT_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/BConfig.cmake
              @ONLY)<br>
              <br>
            </div>
            Where <a moz-do-not-send="true"
              href="http://BConfig.cmake.in">BConfig.cmake.in</a> may
            look like:<br>
            <br>
              get_filename_component(B_CONFIG_DIR
            "${CMAKE_CURRENT_LIST_FILE}" PATH)<br>
              find_library(B_LIB "B" HINTS ${B_CONFIG_DIR}/../../../lib)<br>
              set(B_INCLUDE_DIRS ${B_CONFIG_DIR}/../../../include
            @B_INTERFACE_INCLUDE_DIRS@)<br>
          </div>
            set(B_LIBRARIES ${B_LIB} @B_INTERFACE_LIBRARIES@)<br>
        </div>
          set(B_FOUND TRUE)<br>
        <div>
          <div><br>
          </div>
          <div>Now find_package(B) will export B_INCLUDE_DIRS /
            B_LIBRARIES which will list full paths to everything
            necessary to build against it.<br>
            <br>
          </div>
          <div>At my company we usually use static libraries so that
            it's rarely a problem but with dynamic libraries (.so) this
            approach will not be enough to run the app. Searching for
            dynamic libraries is not exactly the build system
            responsibility, though and greatly depends on the platform
            and the way you distribute the resulting application. If
            anything it always possible to make another transitive
            Foo_RPATHS property.<br>
            <br>
          </div>
          <div>This 'simple' approach does not work with libraries that
            export 'imported targets' only (if I recall correctly, the
            Qt find module exports Qt::XYZ targets but not Qt_LIBRARIES)
            so that there is no interface variables to merge. In this
            case one would need to iterate over imported targets and
            merge their INTERFACE_xxx properties in a similar way.<br>
            <br>
          </div>
          <div>I believe this to be an oversight. Everything should be
            fine if there was an option to resolve and export transitive
            dependencies along the targets in CMake export() command.
            Probably this may be fixed by an external helper script
            (similar to CMakePackageConfigHelpers module) providing some
            function that takes a list of targets, analyzes them and
            writes a config file complete with targets and their
            dependencies.<br>
          </div>
        </div>
      </div>
      <div class="gmail_extra"><br>
        <div class="gmail_quote">On 28 June 2016 at 13:35, 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">Hey Ray,<br>
            <br>
            Project A is used by many projects, and so is project B. So<br>
            ExternalProject is not the right solution. I just want to be
            able to fix<br>
            project B in such a way that people, including myself, can
            easily use it<br>
            without knowledge of where project A is located. The
            packages will all<br>
            be used mostly on supercomputers, where users never have
            rights to<br>
            install anything, and even if they install them as a module,
            it is still<br>
            in a non-standard path. As you can see from the example,
            this works fine<br>
            for project B which depends on A, but not for project C
            which depends on<br>
            B. Even if you set the PATH correctly.<br>
            <span class="HOEnZb"><font color="#888888"><br>
                Sven<br>
              </font></span>
            <div class="HOEnZb">
              <div class="h5"><br>
                On 06/28/2016 12:25 PM, Raymond Wan wrote:<br>
                > Hi Sven,<br>
                ><br>
                ><br>
                > On Tue, Jun 28, 2016 at 6:03 PM, Sven Baars <<a
                  moz-do-not-send="true" href="mailto:s.baars@rug.nl"><a class="moz-txt-link-abbreviated" href="mailto:s.baars@rug.nl">s.baars@rug.nl</a></a>>
                wrote:<br>
                >> The packages I use are installed in a
                non-standard path, because I don't<br>
                >> have access to the system directories on most
                systems I work on, but are<br>
                >> used by many other libraries. They are also all
                separate packages, not<br>
                >> packages in the same source tree. I did not see
                my attachment on the<br>
                >> mailing list archive, so instead I just put it
                on Github. It can be<br>
                >> found here:<br>
                >><br>
                >> <a moz-do-not-send="true"
                  href="https://github.com/Sbte/cmake-example"
                  rel="noreferrer" target="_blank">https://github.com/Sbte/cmake-example</a><br>
                >><br>
                >> I hope the example shows my workflow, and also
                what doesn't work for me.<br>
                ><br>
                > Hmmmm, in that case, I should probably remain quiet
                as this is not<br>
                > quite something I've had to do.<br>
                ><br>
                > Maybe the only advice I can give is, if you plan to
                distribute your<br>
                > work to others, what are your expectations in terms
                of where do you<br>
                > think users should install these dependencies.<br>
                ><br>
                > For example, if it's a system-level directory, then
                maybe you can<br>
                > consider a FIND_PACKAGE solution which has a list
                of default paths to<br>
                > search.  When you're developing on your own
                computer, you just change<br>
                > the default path to include paths in your home
                directory.<br>
                ><br>
                > There is also the ExternalProject () directive
                which you could<br>
                > consider [<a moz-do-not-send="true"
                  href="https://cmake.org/cmake/help/v3.3/module/ExternalProject.html"
                  rel="noreferrer" target="_blank">https://cmake.org/cmake/help/v3.3/module/ExternalProject.html</a>]<br>
                > .  This would retrieve the dependencies from
                outside sources (i.e.,<br>
                > repositories) and build them.  This would keep
                everything within the<br>
                > same build/ path and I haven't done that (and
                didn't mention it<br>
                > before) because all of my packages are within the
                same source tree.<br>
                ><br>
                > So, still not quite your situation, though.<br>
                ><br>
                > I hope this helps!  Perhaps others can chime in and
                help you with<br>
                > exactly what you're stuck with...<br>
                ><br>
                > Ray<br>
                <br>
                --<br>
                <br>
                Powered by <a moz-do-not-send="true"
                  href="http://www.kitware.com" rel="noreferrer"
                  target="_blank">www.kitware.com</a><br>
                <br>
                Please keep messages on-topic and check the CMake FAQ
                at: <a moz-do-not-send="true"
                  href="http://www.cmake.org/Wiki/CMake_FAQ"
                  rel="noreferrer" target="_blank">http://www.cmake.org/Wiki/CMake_FAQ</a><br>
                <br>
                Kitware offers various services to support the CMake
                community. For more information on each offering, please
                visit:<br>
                <br>
                CMake Support: <a moz-do-not-send="true"
                  href="http://cmake.org/cmake/help/support.html"
                  rel="noreferrer" target="_blank">http://cmake.org/cmake/help/support.html</a><br>
                CMake Consulting: <a moz-do-not-send="true"
                  href="http://cmake.org/cmake/help/consulting.html"
                  rel="noreferrer" target="_blank">http://cmake.org/cmake/help/consulting.html</a><br>
                CMake Training Courses: <a moz-do-not-send="true"
                  href="http://cmake.org/cmake/help/training.html"
                  rel="noreferrer" target="_blank">http://cmake.org/cmake/help/training.html</a><br>
                <br>
                Visit other Kitware open-source projects at <a
                  moz-do-not-send="true"
                  href="http://www.kitware.com/opensource/opensource.html"
                  rel="noreferrer" target="_blank"><a class="moz-txt-link-freetext" href="http://www.kitware.com/opensource/opensource.html">http://www.kitware.com/opensource/opensource.html</a></a><br>
                <br>
                Follow this link to subscribe/unsubscribe:<br>
                <a moz-do-not-send="true"
                  href="http://public.kitware.com/mailman/listinfo/cmake"
                  rel="noreferrer" target="_blank">http://public.kitware.com/mailman/listinfo/cmake</a><br>
              </div>
            </div>
          </blockquote>
        </div>
        <br>
      </div>
    </blockquote>
    <br>
  </body>
</html>