Using find_package fails to find related subprojects that are exported to the package registry

classic Classic list List threaded Threaded
2 messages Options
Reply | Threaded
Open this post in threaded view
|

Using find_package fails to find related subprojects that are exported to the package registry

Timothy Wrona
Hi fellow CMake programmers! I've got a bit of a tricky situation and I wonder if anyone has ever dealt with this before.

I am trying to configure a project that has a structure as follows

myproject/
    executable1/  <-- depends on common_lib1
    my_common_libs/
        common_lib1/
        common_lib2/

Note: Before I begin - this is a legacy system and is MUCH larger than what I am showing here so restructuring the whole project is not really an option. Let me begin by describing the CMakeLists.txt structure.

In myproject/CMakeLists.txt subdirectories are added as follows:

file(GLOB entries *)
foreach(entry ${entries})
  if (IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt)
    add_subdirectory(${entry})
  endif()
endforeach()

my_common_libs/CMakeLists.txt does the same...

Then my_common_libs/common_lib1/CMakeLists.txt does what is necessary to define the library and export the target to the local package registry:

add_library(common_lib1 ...)

export(TARGETS common_lib1 NAMESPACE common_lib1:: FILE common_lib1-targets.cmake)
file(COPY common_lib1-config.cmake DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
export(PACKAGE common_lib1)

my_common_libs/common_lib2/CMakeLists.txt does the same and both have "common_libx-config.cmake" files that properly load the corresponding "-targets.cmake" files.

In executable1/CMakeLists.text I do what is necessary to find the package and use it:

add_executable(executable1 ...)

find_package(common_lib1 REQUIRED) <-- this is where I am having the problem
target_link_libraries(executable1
    common_lib1::common_lib1
)

Now this is where things get hairy...

If I go into common_lib1 and manually build that first, it puts it in the package registry and then I can go to "executable1" and build that and it finds the package, and builds, and links fine.
BUT... if I clean the project and then try to build it from the top level it immediately fails and says it can't locate the package "common_lib1".

I understand I could probably replace the GLOB commands with explicit "add_subdirectory" calls and then carefully reorder all of the "add_subdirectory" commands to add things in dependency order, but that would be really tedious with how large the project is and is really not the way the whole rest of the system is done... It feels somewhat brittle because then I am essentially declaring the dependencies from outside of the modules themselves.

Is there any way to force CMake to do all of the "export" commands up front to essentially initialize the package registry so it will be aware of common_lib1 when I compile from the "myproject" level? Or is there another solution I haven't even considered that could solve this same problem?

Thanks,
Tim

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake
Reply | Threaded
Open this post in threaded view
|

Re: Using find_package fails to find related subprojects that are exported to the package registry

Rafael Vargas
I have a similarly organized project and it works without any of the find_package and the export commands.

If you do include all of the CMakeFiles.txt files using add_directory, then it should be enough to:

In my_common_libs/common_lib1/CMakeLists.txt:
    add_library(common_lib1 ...)

In executable1/CMakeLists.text:
    add_executable(executable1 ...)
    target_link_libraries(executable1 common_lib1 )

This way you don't need to worry about ordering your add_directory commands as all the link dependencies will be ordered by CMake.

--
Rafael Vargas


Em qua, 10 de abr de 2019 às 18:08, Timothy Wrona <[hidden email]> escreveu:
Hi fellow CMake programmers! I've got a bit of a tricky situation and I wonder if anyone has ever dealt with this before.

I am trying to configure a project that has a structure as follows

myproject/
    executable1/  <-- depends on common_lib1
    my_common_libs/
        common_lib1/
        common_lib2/

Note: Before I begin - this is a legacy system and is MUCH larger than what I am showing here so restructuring the whole project is not really an option. Let me begin by describing the CMakeLists.txt structure.

In myproject/CMakeLists.txt subdirectories are added as follows:

file(GLOB entries *)
foreach(entry ${entries})
  if (IS_DIRECTORY ${entry} AND EXISTS ${entry}/CMakeLists.txt)
    add_subdirectory(${entry})
  endif()
endforeach()

my_common_libs/CMakeLists.txt does the same...

Then my_common_libs/common_lib1/CMakeLists.txt does what is necessary to define the library and export the target to the local package registry:

add_library(common_lib1 ...)

export(TARGETS common_lib1 NAMESPACE common_lib1:: FILE common_lib1-targets.cmake)
file(COPY common_lib1-config.cmake DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
export(PACKAGE common_lib1)

my_common_libs/common_lib2/CMakeLists.txt does the same and both have "common_libx-config.cmake" files that properly load the corresponding "-targets.cmake" files.

In executable1/CMakeLists.text I do what is necessary to find the package and use it:

add_executable(executable1 ...)

find_package(common_lib1 REQUIRED) <-- this is where I am having the problem
target_link_libraries(executable1
    common_lib1::common_lib1
)

Now this is where things get hairy...

If I go into common_lib1 and manually build that first, it puts it in the package registry and then I can go to "executable1" and build that and it finds the package, and builds, and links fine.
BUT... if I clean the project and then try to build it from the top level it immediately fails and says it can't locate the package "common_lib1".

I understand I could probably replace the GLOB commands with explicit "add_subdirectory" calls and then carefully reorder all of the "add_subdirectory" commands to add things in dependency order, but that would be really tedious with how large the project is and is really not the way the whole rest of the system is done... It feels somewhat brittle because then I am essentially declaring the dependencies from outside of the modules themselves.

Is there any way to force CMake to do all of the "export" commands up front to essentially initialize the package registry so it will be aware of common_lib1 when I compile from the "myproject" level? Or is there another solution I haven't even considered that could solve this same problem?

Thanks,
Tim
--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake

--

Powered by www.kitware.com

Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ

Kitware offers various services to support the CMake community. For more information on each offering, please visit:

CMake Support: http://cmake.org/cmake/help/support.html
CMake Consulting: http://cmake.org/cmake/help/consulting.html
CMake Training Courses: http://cmake.org/cmake/help/training.html

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Follow this link to subscribe/unsubscribe:
https://cmake.org/mailman/listinfo/cmake