I have a cmake project for a third-party library which targets both Windows and macOS (let's call it Foo) which I hope to include with a cmake Find module. The library stashes its includes in ${CMAKE_SOURCE_DIR}/ThirdParty/include/Foo, and I'm calling find_path to define Foo_INCLUDE_DIR as follows:
find_path(Foo_INCLUDE_DIR
NAMES "Foo/version.hpp"
PATHS "${CMAKE_SOURCE_DIR}/ThirdParty/include"
NO_DEFAULT_PATH
)
Now, the problem is that even though the project has the same exact dir tree on both macOS and Windows, the above call sets Foo_INCLUDE_DIR as Foo_INCLUDE_DIR-NOTFOUND".
Does anyone have any idea why the above call to find_path only works on Windows?
Related
I made a project and tried to build it under GCC (Linux) and MinGW (Windows) using CMake. Now I'm trying to do the same under Visual Studio 2019 (for reasons) and it seems that CMake that is shipped with VS can't find libraries installed with MSVC.
I'm using a script which unfortunately I can't find again on the Net, so I can't give you a link to it. But I tried to isolate what is causing the problem. So, here is the code:
if(MY_LIB_PATH)
set(MYLIB_NO_DEFAULT_PATH_CMD NO_DEFAULT_PATH)
endif()
find_library(MY_LIBRARY
NAMES myLibrary
HINTS
ENV MY_ENV
${MYLIB_NO_DEFAULT_PATH_CMD}
PATH_SUFFIXES lib lib/x64
PATHS ${MY_LIB_PATH}
DOC ""
)
(the code is much complicated than that, but that is what it looks after all variable substitutions)
If I don't set the MY_LIB_PATH variable it can't find the library (which is located in the lib/x64 folder in the MSVC installation folder). But when I call CMake like this:
cmake "-DMY_LIB_PATH=C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.29.30133\lib\x64"
it "miraculously" finds it.
Yes it works but...wasn't CMake made to avoid writing all that path in the first place? Besides, there is yet another problem: there are many such libraries in my project, all of which use the same above code for finding, and I have to write all that path multiple times, so CMake can find them.
Either the authors of my CMake script did something wrong or I installed my libraries not where CMake is expecting them.
I'm trying to get a native Windows build working in which we depend on librsvg-2. It's correctly installed through vcpkg. We usually build with cmake and have made a custom module to find this library. This works great in the unix world, but not within Windows and targeting either a Debug build or a Release build (from visual studio). This is due to the fact the actual lib file gets suffixed with a d on Windows.
This is our FindLibRSVG.cmake
include(LibFindMacros)
libfind_package(LibRSVG Cairo)
libfind_package(LibRSVG GDK-PixBuf)
libfind_pkg_detect(LibRSVG librsvg-2.0
FIND_PATH librsvg/rsvg.h PATH_SUFFIXES librsvg-2 librsvg-2.0
FIND_LIBRARY rsvg-2
)
libfind_process(LibRSVG)
To get the build working on Windows i have to specify a flag to our cmake command like this:
cmake .. -DLibRSVG_LIBRARY=./vcpkg_installed/x64-windows/debug/lib/rsvg-2.40d.lib
Do note the d at the end of the library.
I know there is a cmake module SelectLibraryConfigurations available but i'm not quite sure how to use this properly.
What i'd like to achieve is to be able to build in debug mode without having to provide this flag.
Note: The LibFindMacros implementation can be found here
I've just started working with CMake and I noticed that they have both a find_package and a find_library. And this confuses me. Can somebody explain the difference between a package and a library in the world of programming? Or, in the world of CMake?
Appreciate it, guys!
Imagine you want to use zlib in your project, you need to find the header file zlib.h, and the library libz.so (on Linux). You can use the low-level cmake commands find_path and find_library to find them, or you can use find_package(ZLIB). The later command will try to find out all what is necessary to use zlib. It can be extra macro definitions, or dependencies.
Update, more detail about find_package: when the CMake command find_package(SomeThing) is called, as in the documentation, there are two possible modes that cmake can run:
the module mode (that searches for a file FindSomeThing.cmake)
or the config mode (that searches for a file named SomeThingConfig.cmake)
For ZLIB, there is a module named FindZLIB, shipped with CMake itself (on my Linux machine that is the file /usr/share/cmake/Modules/FindZLIB.cmake). That module is a CMake script that uses the CMake API to search for ZLIB files in default locations, or ask the user for the location if it cannot be found automatically.
I am using CMake to build a Qt5 project on OS X. I need to create a build process that is as simple as possible for others.
By default Qt5 installs to the home folder on OS X. However, it then places its files within a directory named after the exact version number, e.g. 5.2.1.
At the moment I am using these lines in my CMake file:
set(QT5_PATH $ENV{HOME}/Qt5.2.1/5.2.1/clang_64/ CACHE PATH "Path to Qt5")
set(QT5_MODULE_PATH ${QT5_PATH}/lib/cmake)
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} ${QT5_MODULE_PATH})
This works, but unfortunately breaks with each minor update of Qt as the 5.2.1 needs to be changed to 5.2.2, etc.
In Windows there are environment variables that can be used to find Qt. Is there anything similar in OS X that I can use within CMake to find a Qt installation?
Use find_package instead of juggling with the paths yourself. Then your users can rely on standard CMake mechanism instead of figuring out your own CMake code.
Use find_package(Qt5Widgets) to get targets like Qt::Widgets to link against and for the includes.
Similar for Qt5Core and whatever part of Qt 5 you need.
See Qt's documentation: http://doc.qt.io/qt-5/cmake-manual.html
Finally, after whole day spent, I've made my CMake based project to successfully compile project on Windows(I've been developing it in Linux) and it even links well together, perfect isn't it? Now I launch the program and boom, it's not able to find dll libraries.
So, The problem:
I have CMake project with library and executable inside, that executable is using project's library. I also have many third party libraries in project. It compiles and links well. When I try to launch it it prints error that project's library wasn't found. I've copied it to the executable's directory. Now it prints that 3rd party library wasn't found, I've copied all of them to exe's dir. Now it prints that gcc's library wasn't found, so I've added C:\MinGW\bin to the path and now it launches fine.
But I feel it's not the proper way. I'd like to spare my teammates(new) of that pain of launching.
Either link everything statically, or add necessary install() calls into your CMakeLists.txt. Install all needed libs into the same directory and run executable from there.
If you want to run executable from CMAKE_BINARY_DIR, you can
set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} )
set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} )
set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR} )
This would make CMake to put linked binaries into the same dir.
As for gcc runtime - there is no other way except copying dll or linking statically.