What is the right place for FindXXX.cmake files for locally compiled libs?
See the comments in the CMake documentation for the "find_package" command:
http://cmake.org/cmake/help/v2.8.8/cmake.html#command:find_package
It speaks of writing a "project-config" file, and where to install it, such that find_package(Eigen3) will work without having a FindEigen3.cmake find module... It is verbose, but the information is in there.
See also user contributed wiki pages such as this one:
https://gitlab.kitware.com/cmake/community/wikis/doc/tutorials/How-to-create-a-ProjectConfig.cmake-file
Custom path for my libraries for find_library
Use CMAKE_PREFIX_PATH
to indicate paths where find_library
, find_path
et al. should have a look (documentation)
Stuff like PNGDIR
should no longer be used and is considered legacy that is kept for backwards compatibility. Patches for FindXXX provided by CMake to add XXX_DIR
or XXX_ROOT
are rejected by the CMake developers.
What use is find_package() when you need to specify CMAKE_MODULE_PATH?
Command find_package
has two modes: Module
mode and Config
mode. You are trying to
use Module
mode when you actually need Config
mode.
Module mode
Find<package>.cmake
file located within your project. Something like this:
CMakeLists.txt
cmake/FindFoo.cmake
cmake/FindBoo.cmake
CMakeLists.txt
content:
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake")
find_package(Foo REQUIRED) # FOO_INCLUDE_DIR, FOO_LIBRARIES
find_package(Boo REQUIRED) # BOO_INCLUDE_DIR, BOO_LIBRARIES
include_directories("${FOO_INCLUDE_DIR}")
include_directories("${BOO_INCLUDE_DIR}")
add_executable(Bar Bar.hpp Bar.cpp)
target_link_libraries(Bar ${FOO_LIBRARIES} ${BOO_LIBRARIES})
Note that CMAKE_MODULE_PATH
has high priority and may be usefull when you need to rewrite standard Find<package>.cmake
file.
Config mode (install)
<package>Config.cmake
file located outside and produced by install
command of other project (Foo
for example).
foo
library:
> cat CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(Foo)
add_library(foo Foo.hpp Foo.cpp)
install(FILES Foo.hpp DESTINATION include)
install(TARGETS foo DESTINATION lib)
install(FILES FooConfig.cmake DESTINATION lib/cmake/Foo)
Simplified version of config file:
> cat FooConfig.cmake
add_library(foo STATIC IMPORTED)
find_library(FOO_LIBRARY_PATH foo HINTS "${CMAKE_CURRENT_LIST_DIR}/../../")
set_target_properties(foo PROPERTIES IMPORTED_LOCATION "${FOO_LIBRARY_PATH}")
By default project installed in CMAKE_INSTALL_PREFIX
directory:
> cmake -H. -B_builds
> cmake --build _builds --target install
-- Install configuration: ""
-- Installing: /usr/local/include/Foo.hpp
-- Installing: /usr/local/lib/libfoo.a
-- Installing: /usr/local/lib/cmake/Foo/FooConfig.cmake
Config mode (use)
Use find_package(... CONFIG)
to include FooConfig.cmake
with imported target foo
:
> cat CMakeLists.txt
cmake_minimum_required(VERSION 2.8)
project(Boo)
# import library target `foo`
find_package(Foo CONFIG REQUIRED)
add_executable(boo Boo.cpp Boo.hpp)
target_link_libraries(boo foo)
> cmake -H. -B_builds -DCMAKE_VERBOSE_MAKEFILE=ON
> cmake --build _builds
Linking CXX executable Boo
/usr/bin/c++ ... -o Boo /usr/local/lib/libfoo.a
Note that imported target is highly configurable. See my answer.
Update
- Example
Use CMake binares to build cpp projects without installing CMake
Just copied builded Modules and Templates directories from cmake-3.19.0
build directory to /usr/local/share/cmake-3.19
Cmake: find_library doesn't work but find_path does (same path)
Well, I found my problem. I feel stupid for not thinking about this sooner...
The problem was in the pre/suffixes, with some debugging output I realised that they were set for Linux instead of Windows, hence not founding the library file.
The reason for that is that in the CMakeLists.txt, the call to find_package was done before the call to project(), thus the MSVC variables was not set during the call to find_package, which led the script to believe it was called under Linux.
variable to change for finding OpenCV
As identify by Tsyvarev when you compile opencv and want to install opencv it in an different path the default one (e.g. /usr/local/ on linux) it is better to modify the variable CMAKE_INSTALL_PREFIX
in the CMakeFile.txt
rather than move everything after installation.
cannot find library under /usr/local/lib
Fist, Thanks @Kamil Cuk. The argument -VERBOSE=1 was so useful that I can get more detail messages that show me what happens when I use make.
The point is that when I use cmake under OSX system. It will generate a txt be named 'link.txt' which includes commands and part of it is as the following:-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk
when I delete this part, the commands will execute right. but when I add this line, the commands execute wrong. so the point is that this line maybe limited the search path of c++. Thanks @tsyvarev . You are right, -isysroot
limited the c++ linkers searches /usr/local/lib
.
Second, I did't find out how to remove the line -isysroot ...
generated by OSX cmake. So, I need to find another solution.
When I search more information about find_package/include_directories/target_link_libraries, I found out that find_package need a FindXXX.cmake file to help it to find out the header file and libraries of the target. So I googled a FindCyptoPP.cmake file. and in this file it find out tow vars, one hold the value of cryptopp's header directory path, and one hold the value of cryptopp's library path. Then I use include_directories/target_link_libraries as following, the problem
war solved.
find_package(CryptoPP)
include_directories(${CRYPTOPP_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${CRYPTOPP_LIBRARIES})
and then when I use make -VERBOSE = 1
, I fond that the output was a little different when I use the CMakeLists.txt as following:
target_link_libraries(${PROJECT_NAME} cryptopp)
When I use three lines, the output contains a line /usr/local/lib/libcryptopp.dylib
. When I use one line, the output contains a line -lcryptopp
.
So, with the command line -isysroot
, the command line -lcryptopp
will search library under the directory defined by -isysroot
, and under the directory, there is no library named cryptopp
but under /usr/local/lib
. But with command line /usr/local/lib/libcryptopp.dylib
, it gaves the absolute path of the library, so the linkes just do the linking task and need not search. Thanks @Kamil Cuk again.
Thrid, I knew include_directories/target_link_libraries are two separate steps which one is used for include header file and one is used for link libraries.
Still, there were some problems not soled:
- how to remove -isysroot?
- how to create a FindXXX.cmake file?
- how to make /usr/local/lib
as a default search directory and was it a practice way to do so?
I will continue working on them, and come back a few days or weeks later.
Related Topics
Arduino Upload Error "Stk500_Recv(): Programmer Is Not Responding" in Fedora
Copying Local Git Config into Docker Container
How to Efficiently Get 10% of Random Lines Out of The Large File in Linux
How to Decide How Much Stack I Can Use After a Call to Pthread_Attr_Setstacksize
How to Enable Spell Checker in Google Colab (Colab Operates on Linux Os)
Unexpected Eof While Looking for Matching '"'
Rmpi: Cannot Use Mpi_Comm_Spawn API
Count Total Number of Pattern Between Two Pattern (Using Sed If Possible) in Linux
Linux Kconfig Command Line Interface
Timeouting a While Loop in Linux Shell Script
Gitlab Ce Doesn't Add a Public Key to Authorized_Keys
Arm Linux ":Start_Kernel Is Not Calling After Decompressing UImage"
Container Running in Privileged Mode
How to Disable The Gnome Desktop Screen Lock