Skip to content

Best practices for using CMake in OpenEmbedded/Yocto

I’ve already written about using autotools and qmake in OE.  With recent projects, we’re using CMake to build most C/C++ components.  Like any good tool, CMake has a learning curve, but it seems to do its job quite well.  Below are examples of a CMake build file, and corresponding OE recipe.

————————–

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)
project(MyApp)
file(GLOB_RECURSE src/*.cpp)
add_executable(MyAPP ${src_files})
target_link_libraries(MyApp pthread)
install(TARGETS MyApp DESTINATION bin)

————————–

myapp.bb (OE recipe)

DESCRIPTION = “My xyz app” LICENSE = “CLOSED” inherit cmake SRCREV = “${AUTOREV}” PV = “1.1+gitr${SRCPV}” SRC_URI = “git://my-git-server/myapp.git;branch=master;protocol=ssh;user=git” S = “${WORKDIR}/git” BBCLASSEXTEND = “native”

————————–

Notice the OE recipe above has no build/install logic other than “inherit cmake”.

Below are some tips on using CMake.

  1. put your source files in a src directory.  This allows you to easily build a list by using GLOB patterns.  If you put the source files in the root directory of your application source, then the GLOB pattern will also find temporary C files that CMake generates, and you’ll get multiple “main” errors.  Some recommend against using GLOB patterns for finding source files because it may miss additions, but in practice I find the benefits of this pattern outweigh the negatives.
  2. do all install operations in CMake if possible (vs do_install in the OE recipe).  The reason for this is its much easier to debug install in CMake then OE.  You can build the app for x86 on your workstation, run “make install” and easily verify the files get installed correctly.  Typically, things get installed in /usr/local when building on your workstation, and /usr when built in the context of OE.
  3. do most of your development on your workstation.  Most of the time, you can test 99% of an application’s functionality on your workstation.  Do what you can there with unit tests where development is much faster and easier.
  4. change ownership of /usr/local by running “sudo chown -R $USER /usr/local“.  This allows you to run “make install” of the CMake project during development without sudo.  It also helps ensure you are not accidentally installing stuff outside /usr/local.
  5. you don’t need to add header files to the target sources.  CMake automatically figures out include dependencies.
  6. you can run “make VERBOSE=1″ to see the commands make is running during a compile.
  7. cmake -DCMAKE_BUILD_TYPE=Debug can be used to add debugging information (essentially -g).
  8. When developing on your workstation, do the following to build: mkdir build; cd build; cmake ../; make The advantage of running cmake inside a build directory is you can simply wipe the entire build dir to completely reset the build.  Otherwise, the cmake files are mixed up with your source files.
  9. The following is the CMake version of printf — very useful for debugging: message(some_var: ${some_var})
  10. ccmake and cmake-gui are useful tools for examining the state of various CMake variables.

Most of these tips are general and have nothing to do with OE, but that is the entire point — using CMake with OE rarely requires you to do anything beyond what you normally do with CMake.  So, if you use CMake correctly, there is usually not a lot more required to cross compile and package your apps in OE.