How to import LLVM on a cmake based bitbake recipe? - cmake

I have a CMake project that needs LLVM to build, so I have: Find_Package(LLVM REQUIRED) on my CMakeLists.txt file.
This works fine when building on my system, but if I try to build this project using bitbake, then LLVM is not found by cmake:
| Could not find a package configuration file provided by "LLVM" with any of
| the following names:
|
| LLVMConfig.cmake
| llvm-config.cmake
I have already included llvm and llvm-common on my recipe's DEPENDS, and llvm libraries seems to be installed on the sysroot, but I couldn't find the CMake files anywhere. On the llvm recipe there are two suspicious lines, but there is probably a reason they are there:
# Remove unnecessary cmake files
rm -rf ${D}${libdir}/${LLVM_DIR}/cmake
So what is the proper way to use LLVM from CMake? I'd be really thankful if the proposed solution doesn't involve hacking the original llvm recipe.

Related

Cmake: using conan pybind11 package

I'm having trouble understanding how to use pybind11 conan package. I can use some others, but pybind11 is giving me hard time.
My starting point is as follows:
conanfile.txt:
[requires]
pybind11/2.7.1
[generators]
cmake
main.cpp:
#include <pybind11/pybind11.h>
int add(int i, int j) {return i + j;}
PYBIND11_MODULE(cobind, m) {m.def("add", &add);}
CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project(cobind11 VERSION 1.0 LANGUAGES CXX)
include(${CMAKE_BINARY_DIR}/conanbuildinfo.cmake)
conan_basic_setup()
pybind11_add_module(cobind main.cpp)
The log of my suffering trying to make this work:
💀 Starting point
If I try to build as above the project I get the following error:
CMake Error at CMakeLists.txt:10 (pybind11_add_module):
Unknown CMake command "pybind11_add_module".
-- Configuring incomplete, errors occurred!
💀💀 Adding find_package(pybind11 REQUIRED)
If I add a line find_package(pybind11 REQUIRED) I get the following error:
CMake Error at CMakeLists.txt:16 (find_package):
By not providing "Findpybind11.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "pybind11",
but CMake did not find one.
💀💀💀 Adding include([...]/pybind11Tools.cmake)
If I add a line #include(${CONAN_PYBIND11_ROOT}/lib/cmake/pybind11/pybind11Tools.cmake) I get the following error:
CMake Error at /home/[...]/pybind11Tools.cmake:100 (set_property):
set_property could not find TARGET pybind11::pybind11. Perhaps it has not yet been created.
like in this issue https://github.com/pybind/pybind11/issues/3388. Maybe it is fixed in the new release?
💀💀💀💀 Upgrading to 2.8.1
The fresh pybind11 is 2.8.1, let's upgrade
pybind11/2.8.1: Not found in local cache, looking in remotes...
pybind11/2.8.1: Trying with 'conancenter'...
ERROR: Unable to find 'pybind11/2.8.1' in remotes
OK. One can read between the lines, that it used to work, so maybe let's downgrade?
💀💀💀💀💀 Downgrading to 2.4.3
If I require pybind/2.4.3 instead of pybind/2.7.1 in conanfile.txt I get
fatal error: Python.h: No such file or directory
112 | #include <Python.h>
| ^~~~~~~~~
like in this issue https://github.com/pybind/pybind11/issues/1781. Differently from that issue, installing python*-dev does not help. But whatever, I don't want to use old pybind anyway.
💀💀💀💀💀💀 Trying a conanfile from test package
The conancentral recipes contain a test package (https://github.com/conan-io/conan-center-index/tree/master/recipes/pybind11/all/test_package), which is tested automatically when the package is created. Let's try that instead!
CMake Error at CMakeLists.txt:13 (find_package):
By not providing "Findpybind11.cmake" in CMAKE_MODULE_PATH this project has
asked CMake to find a package configuration file provided by "pybind11",
but CMake did not find one.
Am I just hopeless???
Maybe, but! I can:
💪 Build the https://github.com/pybind/cmake_example
💪 Build the https://github.com/pybind/python_example
💪 Build the conancentral pybind11 recipe! The same that fails when I extract the test package to a separate folder. Whaaat?? 😱
I have used pybind in the past (two or three years ago) and it worked without problems with conan. However, I tried to install it now and faced similar problems. This might be related to the evolution of conan towards conan 2.0 (an alpha version was released today) and that the recipe was not updated to account changes.
An alternative that you might consider, is to install pybind with conan using a different generator. More specifically, the CMakeDeps generator. With the CMakeDeps generator conan will create a pybind11-config.cmake file for you and you just need to use find_package(pybind11 REQUIRED) in CMakeLists.txt. That is, there is no "conan specific stuff" in your CMakeLists.txt file.
conanfile.txt
[requires]
pybind11/2.7.1
[generators]
CMakeDeps
CMakeLists.txt
cmake_minimum_required(VERSION 3.21)
project(cobind11 VERSION 1.0 LANGUAGES CXX)
# Tell cmake to also search in the buld folder for the "<library>-config.cmake"
# files
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}")
find_package(pybind11 REQUIRED)
pybind11_add_module(cobind main.cpp)
main.cpp
#include <pybind11/pybind11.h>
int add(int i, int j) { return i + j; }
PYBIND11_MODULE(cobind, m) { m.def("add", &add); }
With this I was able to build the library and use it in Python.
Conan deeper integration with CMake
You can also use the CMakeToolchain generator in addition to the CMakeDeps generator. It generates a conan_toolchain.cmake file that you pass to the cmake command with --toolchain conan_toolchain.cmake. If you use it, there is no need to add the list(APPEND CMAKE_PREFIX_PATH "${CMAKE_BINARY_DIR}") line to your CMakeLists.txt file. Furthermore, the settings you specify in conan, such as build type and compiler, will impact cmake. That is, you don't need to specify these things in both conan and cmake. This seems to be where conan is going, regarding cmake integration, in the comming 2.0 release.

How to deploy a Find*.cmake file for an Autotools library in the correct place for Yocto?

I created a new layer over an existing Yocto git for my company project.
In this layer I added a few external autotools based libraries.
A few applications need to link against this libraries and the application projects are all cmake based.
Taking one of this libraries (e.g. libcoap) I could easily find some FindCoAP.cmake to add to my library recipe.
Now if I was running on PC, it would simply be a matter of placing this FindCoAP.cmake file in cmake's ${CMAKE_ROOT}/Modules dir, but how should I, from inside a bitbake recipe (do_install hook), proceed to make my Find*.cmake modules available to anyone's dependent projects?
Should I try to get Yocto's cmake CMAKE_ROOT variable from system-information like this or is it a safer and more reliable way?
do_install_append() {
cmake --system-information | grep CMAKE_ROOT | cut -d \" -f2
install -d ${D}/$CMAKE_ROOT}/Modules
install ${S}/FindCoAP.cmake ${D}/$CMAKE_ROOT}/Modules
}
Thanks in advance.
To ship FindFoo.cmake with non-yet-cmake project
The ideal way is to update upstream project itself. So you will update your recipe and package FindFoo.cmake appropriately.
If you want to do it right now:
Add FindFoo.cmake to your layer (into the files directory next to your recipe).
Add that cmake file to SRC_URI (i.e. SRC_URI += "file://FindFoo.cmake").
Install it in do_install into the directory ${D}${datadir}/cmake/Modules/ for example.
Package it to the dev package by FILES_${PN}-dev variable (see example recipes below).
To use that cmake by other recipe
The usual way is to package .cmake files into the ${PN}-dev package. In your case, your application (which depends on the libcoap) will just set DEPENDS = "libcoap" and all the needed files (like headers, libraries and cmake file) will be copied (well, hardlinked) to the sysroot of your application.
CMake modules are packaged in various recipes for example:
libeigen
opencv
json-spirit
Your application is cmake based, so you will use inherit cmake in the recipe. Native module search path is set in cmake.bbclass.
(BTW, I do a build test of libcoap recipe from homeassistant layer and it worked, but obviously there is no cmake shipped.)

CMake find protobuf compiled from source

I am trying to build a project that depends on Google Protocol Buffers compiled from source. My project should be platform independent and also should support cross-compilation, which is the reason that i prefer to use a locally built protobuf. However I would prefer not to include the whole library as a subproject as it would take too much to build.
My simplified CMakeLists.txt is:
cmake_minimum_required(VERSION 3.5)
project(sample-protobuf)
# find a boost install with the libraries filesystem and system
find_package(Protobuf REQUIRED)
set(SOURCES
main.cpp
)
add_executable(sample
${SOURCES}
)
target_link_libraries(sample
PRIVATE
protobuf::libprotobuf
)
I invoke CMake on Linux as:
cmake -DCMAKE_PREFIX_PATH=/path/to/built/protobuf/ ..
but it does not find the library and I get the following message:
Could not find a package configuration file provided by "Protobuf" with any
of the following names:
ProtobufConfig.cmake
protobuf-config.cmake
Add the installation prefix of "Protobuf" to CMAKE_PREFIX_PATH or set
"Protobuf_DIR" to a directory containing one of the above files. If
"Protobuf" provides a separate development package or SDK, be sure it has
been installed.
On Windows this procedure works.
I built the library on Linux using the suggested approach, which is not with CMake but with autotools.
What should I do differently?
cd protobuf/cmake
mkdir build
cd build
cmake....
make...
sudo make install

Why -DCMAKE_EXPORT_COMPILE_COMMANDS does not create compile_commands.json file

My cmake --version is 2.8.12.2.
I configure my project build with these commands:
cmake ../klein/ -DBUILD_KLEIN_DEPS=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=1
cmake ../klein/ -DBUILD_KLEIN_DEPS=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
cmake ../klein/ -DBUILD_KLEIN_DEPS=1 -DCMAKE_EXPORT_COMPILE_COMMANDS=on
CMAKE_EXPORT_COMPILE_COMMANDS=1 cmake ../klein/ -DBUILD_KLEIN_DEPS=1
From a clean build, and from a directory with an existing successful build. And want to see the compiler_commands.json file, but it does not appear.
At which moment should it be created: after cmake, or after make command? Where should it be in ./, or in ../klein directory? My cmake does not say anything about this option while it always complains about unused build variables.
Should it work from in a "dirty" directory, where I've performed one successful build, or does it work only on a fresh run in an empty folder?
Edit:
I use a default generator "Unix Makefiles" on my ubuntu linux machine
Edit2:
I'm not an author of the project under the question (I just want to explore it with rtags which requires compile_commands.json file), and I'm not very familiar with CMake mechanics. However, the CMakeLists.txt is probably configured as a super-build (it indeed downloads and builds dependencies - like llvm, z3, ...), and it includes ExternalProject, however it also builds the project itself (klein) from sources. So it's a mix, as I would say.
Can you specify what generator your using? A quick scan of the cmake source from version 3.1.0 suggests that this command is still only available in the following 2 cases.
if(CMAKE_GENERATOR MATCHES "Unix Makefiles")
and
if(CMAKE_GENERATOR MATCHES "Ninja")
if you're using Visual Studio directly you're out of luck unless you want to add a patch to CMake. Otherwise, I know many Windows developers who've gone to Ninja. One advantage is that it's vastly faster than Visual Studio for building. If you are, in fact using Ninja or Unix Makefiles, then it's worth digging deeper.

Linking GLEW with CMake

How can you link GLEW to a project with CMake?
We've been trying to link GLEW to our project using CMake for at least 3 hours without any success so any help is accepted.
I'm using the FindGLEW.cmake which comes with CMake 3.1.0
CMakeLists.txt
find_package(GLEW REQUIRED)
if (GLEW_FOUND)
include_directories($(GLEW_INCLUDE_DIRS))
endif()
Environment Variables
I'm using MinGW w64 to compile the sources and we successfully linked GLFW and GLM just by copying the includes and libs to their respective folders, but after doing the same with GLEW, CMake still couldn't find it.
Sorry if I wasn't clear enough while formulating the question. I will provide any additional information required.
Edit: I've managed to link the header files by specifying their location in the CMake Cache file, though I'm getting undefined reference to glew functions like glewInit().
Typical CMake scripts like FindGLEW will define variables that specify the paths and files that your project needs. If the script can't automatically identify the correct paths (usually because of nonstandard install location, which is fine), then it leaves these variables up to you to fill in.
With command line CMake, you use the -D flag to define and set the value of a given variable. Other CMake interfaces, like CMake-gui or an IDE integration, give you this ability some other way.
However you do it, you can also modify the cache directly (CMakeCache.txt) and see what CMake is using in there or just clear the cache altogether. You'll have to rerun CMake for it to pick up your changes.
When it comes to linking, that's when you need to tell CMake which libs to link. Use the link_libraries command with what the automated script gives you.
find_package(GLEW REQUIRED)
include_directories(${GLEW_INCLUDE_DIRS})
link_libraries(${GLEW_LIBRARIES})
Other answers do obviously work, but the target based style of cmake makes it even easier since the GLEW find module defines the imported target GLEW::GLEW. All you need is:
find_package(GLEW REQUIRED)
target_link_libraries(YourTarget GLEW::GLEW)
YourTarget is the target that you created with add_executable or add_library. No need to explicitly add include directories, they are added automatically by linking the targets.
The secret of find_package(GLEW) is in FindGLEW.cmake file with cmake install.
find_path(GLEW_INCLUDE_DIR GL/glew.h)
find_library(GLEW_LIBRARY NAMES GLEW glew32 glew glew32s PATH_SUFFIXES lib64)
The find_path and find_library commands find paths in standard system paths. If you want them to find paths in user defined directories, you should tell them.
For example:
set(CMAKE_PREFIX_PATH "d:/libs/glew-1.10.0")
set(CMAKE_LIBRARY_PATH "d:/libs/glew-1.10.0/lib/Release/Win32/")
find_package(GLEW REQUIRED)
Reference:
http://www.cmake.org/cmake/help/v3.0/command/find_path.html
http://www.cmake.org/cmake/help/v3.0/command/find_library.html
I was struggling hard to link glew to cmake through command line on mac. This might be helpful but I am not sure :) I will walk you through step by step of what I have done.
I installed Cmake source from the web.
Then I went inside the cmake folder in terminal and typed
./bootstrap && make && make install
(this will install cmake command line tools on our OS platform)
I have some exercise files. I want cmake to generate xcode files for me for all those exercise files (ex. triangles.cpp, shader.cpp etc) So i made a directory inside exercise files folder.
$ mkdir xcode
$ cd xcode
$ cmake -G "Xcode" ..
At this point, Cmake suppose to install all xcode files that included correct libraries. But there was an error :
$ cmake -G "Xcode" ..
CMake Warning (dev) at CMakeLists.txt:3 (cmake_minimum_required):
Compatibility with CMake < 2.4 is not supported by CMake >= 3.0.
This warning is for project developers. Use -Wno-dev to suppress it.
system name is: Darwin-14.1.0
system processor is: x86_64
-- Could NOT find GLEW (missing: GLEW_INCLUDE_DIR GLEW_LIBRARY)
-- Could NOT find Doxygen (missing: DOXYGEN_EXECUTABLE)
-- Using Cocoa for window creation
-- Using NSGL for context creation
-- Building GLFW only for the native architecture
CMake Error: The following variables are used in this project, but they are set to NOTFOUND.
Please set them or make sure they are set and tested correctly in the CMake files:
GLEW_LIBRARY
linked by target "TextureLoader" in directory /Users/Mydir/Desktop/Exercise/Exercise Files
-- Configuring incomplete, errors occurred!
Then to make sure I have installed GLEW and all its libraries correctly, I ran
$brew install glew
Yes, I have installed glew already but it was NOT linked. See the Warning below:
Warning: glew-1.12.0 already installed, it's just not linked
Then I ran the following commands:
$ brew unlink glew
$ brew link glew
And I have solved the error. So just make sure that you have linked glew. Hope this helps.
Happy Coding :)
Finally I found a simple and short CMakeLists which works if you have installed everything in default paths.(openGL, glfw and glew)
cmake_minimum_required(VERSION 3.3)
project(openGL_tutorial)
find_package(OpenGL REQUIRED)
if(NOT OPENGL_FOUND)
message("ERROR: OpenGL not found")
endif(NOT OPENGL_FOUND)
set(GL_LIBRARY GL GLU X11)
add_executable(openGL_tutorial main.cpp)
target_link_libraries(openGL_tutorial glfw GLEW libGLEW.so libGLU.so libGL.so)
For what it is worth, in 2023, this works for me, on macOS, with GLEW, GLFW, and CMake installed using Homebrew:
cmake_minimum_required(VERSION 3.10)
project(Project)
add_executable(Project main.cpp)
find_package(glfw3 REQUIRED)
find_package(GLEW REQUIRED)
target_link_libraries(Project glfw GLEW::glew)