Is it possible to use CMake with and without a compile value?

I don’t know how to title this…

We have a C code base foo that defaults to creating foo with networking but if the preprocessor flag NO_NETWORKING is defined it creates foo no networking.

We use Visual Studio.

What the team wants is to run Cmake once and have a solution with the targets:

  1. foo
  2. fooNoNetwork

Is this possible? And if so how?

The first solution I tried was having a top level CMakeLists.txt file that basically does

# invoke default
add_subdirectory(foo)

# build no-network
set(NO_NETWORK 1)
add_subdirectory(foo)

Where the CMakeLists.txt in foo already has appropriate logic such it will create targets and compile defines based on the existence of NO_NETWORK.

This works on a single basis.

# invoke default
add_subdirectory(foo)

gives the desired results for foo

and

# build no-network
set(NO_NETWORK 1)
add_subdirectory(foo)

gives the desired results for fooNoNetwork.

However, when I do them combined as indicated above, CMake fails stating the subdirectory has already been added.


Is what I want possible? If so can you please teach me? If it’s not possible, are there suggestions you can share for how to achieve this?

One thought I have is to break the networking logic out into two sub libraries.

foo-with-networking.lib
foo-no-networking.lib

and then the executables are achieve by linking with the appropriate sub libraries.

However, the team would prefer to keep the existing solution as is without this library re-write. So I’m exploring that first.

Thanks in advance.

You can pass an explicit build directory as a second argument. This should work:

add_subdirectory(foo)

set(NO_NETWORK 1)
add_subdirectory(foo "${CMAKE_CURRENT_BINARY_DIR}/foo-no-network")