Timmah339
Timmah339

Reputation: 37

CMake with multiple interdependent projects

My team is having a discussion about moving to CMake for our development environment. Our software consists (for the most part) of two main applications:

ProcessingHub - acquires information from sensors, processes it, and broadcasts it.

Client - Receives data broadcasts from ProcessingHub and provides a friendly API to retrieve the data.

Both pieces of software - in addition to many other projects - use a static library as an OS interface layer; I'll call it OsInterfaceLib.

ProcessingHub also uses two other static libraries which are considered independent libraries in that they are not solely for use with ProcessingHub. I'll call them ProcessingLib and SensorLib.

Our SVN structure is as follows:

Our on-disk workspaces exactly mirror SVN.

At the moment, we use checked-in Visual Studio and Eclipse projects for Windows and Linux, respectively. On Windows, ProcessingLib must be built with Clang. Windows is our main platform, and both ProcessingHub/Client have VS solutions which contain the necessary dependent projects, as all these projects are constantly evolving and being able to debug through the projects seamlessly is paramount.

I've spent an entire full-time work week researching CMake, and it seems the only way to get CMake to generate a VS solution that has all the proper dependent projects inside it is to use the add_subdirectory command for each dependency. This fails with ProcessingLib, as it must be built with a different tool chain than the others. To my knowledge, the tool chain can only be set at time of cmake invocation, so generating everything in one shot from the top-level ProcessingHub or Client CMakeLists.txt won't work.

My question is this: Is keeping our projects the way they are the better voice, or is there clean, simple way to have CMake:

  1. Generate ProcessingHub and Client solutions with necessary dependent projects already in the solution explorer
  2. Use the same source code and generated project files for OsInterfaceLib
  3. Not require a restructuring of our SVN/checked-out workspace

Upvotes: 1

Views: 1287

Answers (1)

rocambille
rocambille

Reputation: 15956

You may set C++ compiler through the variable CMAKE_CXX_COMPILER, but note that this must be done before any project() or enable_language() command.

A naive approach would be to call project() in subdirectories:

top-level CMakeLists.txt:

add_subdirectory(ProcessingLib)
add_subdirecdory(Others)

ProcessingLib CMakeLists.txt:

set(CMAKE_CXX_COMPILER /path/to/clang)
project(ProcessingLib)

...

Others CMakeLists.txt:

project(Others)

...

But, looking in documentation for project():

The top-level CMakeLists.txt file for a project must contain a literal, direct call to the project() command; loading one through the include() command is not sufficient. If no such call exists CMake will implicitly add one to the top that enables the default languages (C and CXX).

So AFAIK the best you can do is to build ProcessingLib as an external project instead of a subdirectory:

include(ExternalProject)
ExternalProject_Add(ProcessingLib
    SOURCE_DIR /path/to/ProcessingLib
    CMAKE_ARGS -DCMAKE_CXX_COMPILER=/path/to/clang
)

Upvotes: 1

Related Questions