[CMake] How to build 2 targets from the same source, differing in -D_SWITCHES_ only

Eike Kroemer eike-michael.kroemer at atlas-elektronik.com
Thu Aug 27 06:28:19 EDT 2009


Hi there,

in the hope of achieving platform independence of my plain-C project
I have started looking into CMake, trying to duplicate what my
manually created makefiles do.

A minimalistic description of my problem is the following:

* I have 2 executable targets
* both having the same main program source MAIN/main.c
* both linking to a library libvehicle.a that is built from the same
  set of sources, e.g. VEHICLE/read_hydrodynamic_coeffs.c

The difference between both targets is a compiler definition
-D_TYPE1_ or -D_TYPE2_ that is used in the sourcecode, e.g.

  hydro_par_t read_hydrodynamic_coeffs(sys_par_t sys_par)
  {
  #if defined(_TYPE1_)
  return(read_hydrodynamic_coeffs_type1(sys_par));
  #elif defined(_TYPE2_)
  return(read_hydrodynamic_coeffs_type2(sys_par));
  #endif
  }

So the in both cases the library libvehicle.a will contain a
function read_hydrodynamic_coeffs but the actual content of this
function will be different.

[
 In realiter it's more complicated because there are more
 executables and combinations of several switches, so I really don't
 want to change the sources.
]

What I've done so far is

* in the main CMakeLists.txt:
  add_subdirectory(CMakeTargets/sim_type1)

* in CMakeTargets/sim_type1/CMakeLists.txt:
  add_definitions(-D_TYPE1_)
  include_directories("../../VEHICLE/INCLUDE")
  add_subdirectory(../../VEHICLE VEHICLE)
  add_executable(sim_type1 ../../MAIN/main)
  target_link_libraries(sim_type1 vehicle)

* in CMakeTargets/VEHICLE/CMakeLists.txt:
  set(SRC "read_hydrodynamic_coeffs")
  set(SRC "${SRC} read_hydrodynamic_coeffs_type1")
  set(SRC "${SRC} read_hydrodynamic_coeffs_type2")
  add_library(vehicle ${SRC})

For one target only this gives a executable
CMakeTargets/sim_type1/sim_type1 that is working as expected.

As specified by
  add_subdirectory(../../VEHICLE VEHICLE),
object file and library are created locally:
./CMakeTargets/sim_type1/VEHICLE/CMakeFiles/vehicle.dir/read_hydrodynamic_coeffs.c.o
./CMakeTargets/sim_type1/VEHICLE/libvehicle.a

But as soon as I try to
 add_subdirectory(CMakeTargets/sim_type2)
 [rest as above, only 1->2]
I get an error message
  add_library cannot create target "vehicle" because another target with the
  same name already exists.  The existing target is a static library created
  in source directory "./VEHICLE".  See documentation
  for policy CMP0002 for more details.

Trying to cheat with cmake_policy(SET CMP0002 OLD) I can compile
both executables but they are messed up, obviously trying to execute
read_hydrodynamic_coeffs for the wrong type.

So, how do I define a set of executable make targets, differing only
in the -D_defines_ that are used to build all of the source needed?


Thanks in advance,
   Eike


More information about the CMake mailing list