I am having trouble exporting a package correctly in CMake so that it can be imported using the find_package command, and no matter what I seem to do, it still doesn't work. I've recreated the simplest possible scenario that shows my process in terms of exporting, so it should be easier to diagnose.
I've setup two projects, which I've put in the same folder: foo and bar, where foo is a library and bar is an executable which depends on foo.
├───bar
│ bar.c
│ CMakeLists.txt
│
└───foo
CMakeLists.txt
foo.c
foo.h
Notice that these are two separate projects, and not subprojects of one overarching project.
Contents of foo/CMakeLists.txt:
cmake_minimum_required (VERSION 3.8)
project (Foo)
set (LIB_NAME foo)
add_library (${LIB_NAME} STATIC foo.c foo.h)
install (TARGETS ${LIB_NAME} EXPORT ${LIB_NAME}Targets
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include
)
install (FILES foo.h
DESTINATION include
)
install (EXPORT ${LIB_NAME}Targets
NAMESPACE foo::
DESTINATION lib/cmake
)
Contents of bar/CMakeLists.txt:
cmake_minimum_required (VERSION 3.8)
project (Bar)
set (EXE_NAME bar)
find_package (foo REQUIRED)
add_executable (${EXE_NAME} bar.c)
target_link_libraries (${EXE_NAME} PRIVATE foo::foo)
The sequence of commands that I use to build the two projects:
md foo_build
md bar_build
cd foo_build
cmake ..\foo -DCMAKE_INSTALL_PREFIX=..\install\foo
cmake --build . --target INSTALL
cd ..\bar_build
cmake ..\bar -DCMAKE_PREFIX_PATH=..\install\foo
When all of this was done, the resultant error was:
CMake Error at CMakeLists.txt:7 (find_package):
By not providing "Findfoo.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "foo", but
CMake did not find one.
Could not find a package configuration file provided by "foo" with any of
the following names:
fooConfig.cmake
foo-config.cmake
Add the installation prefix of "foo" to CMAKE_PREFIX_PATH or set "foo_DIR"
to a directory containing one of the above files. If "foo" provides a
separate development package or SDK, be sure it has been installed.
When I tried exporting with the Config suffix instead of the Target suffix for the package exports, there doesn't seem to be any difference to the output:
CMake Error at CMakeLists.txt:7 (find_package):
By not providing "Findfoo.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "foo", but
CMake did not find one.
Could not find a package configuration file provided by "foo" with any of
the following names:
fooConfig.cmake
foo-config.cmake
Add the installation prefix of "foo" to CMAKE_PREFIX_PATH or set "foo_DIR"
to a directory containing one of the above files. If "foo" provides a
separate development package or SDK, be sure it has been installed.
I've got no idea what I'm doing wrong, and the CMake Documentation doesn't seem to be helping me at all.
My CMake version, if it helps, is 3.17.3.
Thank you in advance.
Edit:
I've followed the advice that @Tsyvarev gave, and unfortunately, it did not seem to fix the problem. I read the documentation that he sent, and followed all the parts of it that were different from my current approach.
The main two differences in the approach was to create separate -Targets, -Config, and -ConfigVersion cmake files, with the following changes.
The new structure of the whole program:
├───bar
│ bar.c
│ CMakeLists.txt
│
└───foo
│ CMakeLists.txt
│ foo.c
│ foo.h
│
└───cmake
fooConfig.cmake
The lines I've added to foo's CMakeLists.txt file:
include (CMakePackageConfigHelpers)
write_basic_package_version_file (
${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}ConfigVersion.cmake
VERSION ${${PROJECT_NAME}_VERSION}
COMPATIBILITY AnyNewerVersion
)
install (
FILES
cmake/${LIB_NAME}Config.cmake
${CMAKE_CURRENT_BINARY_DIR}/${LIB_NAME}ConfigVersion.cmake
DESTINATION lib/cmake
)
The contents of fooConfig.cmake:
include ("${CMAKE_CURRENT_LIST_DIR}/fooTargets.cmake")
Just as a reference, the output of installing foo is as one may expect:
├───include
│ foo.h
│
└───lib
│ foo.lib
│
└───cmake
fooConfig.cmake
fooConfigVersion.cmake
fooTargets-debug.cmake
fooTargets.cmake
And when running cmake on the bar project, the same error occurs:
By not providing "Findfoo.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "foo", but
CMake did not find one.
Could not find a package configuration file provided by "foo" with any of
the following names:
fooConfig.cmake
foo-config.cmake
Add the installation prefix of "foo" to CMAKE_PREFIX_PATH or set "foo_DIR"
to a directory containing one of the above files. If "foo" provides a
separate development package or SDK, be sure it has been installed.
By the way, the CMAKE_PREFIX_PATH is being set, as much as the error message would beg to differ, and I can't seem to figure out what else I have to do to appease it.
Any help would be greatly appreciated.
After some very frustrating research, I finally found the answer to this question, which is in the way that find_package works. It turns out that the directory structure that I was giving it was not good enough, but as soon as I changed the "lib/cmake" installs into "lib/cmake/${LIB_NAME}", and changed the CMAKE_PREFIX_PATH to ..\install instead of ..\install\foo, everything seemed to work out okay, and I finally got this simple program to work.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With