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

Marcel Loose loose at astron.nl
Fri Aug 28 04:16:10 EDT 2009


Hi Eike,

Comments are inline.

On Thu, 2009-08-27 at 14:55 +0200, Eike Kroemer wrote:
> Hi Marcel, Christian,
> 
> > Am 08/27/2009 01:30 PM Marcel Loose wrote:
> > I think the only safe and reliable way to do this is create several
> > build directories, e.g. build/type_1 and build/type_2.
> > When running cmake in build/type_1, you should add -D_TYPE1_ to the
> > preprocessor flags; same for build/type_2.
> By 'build directories' you mean to duplicate the library sourcecodes?
> 
> Using the approach sketched in the original post, I have tried to create
> different directories for holding objects and libs - so far without success.
> 
It should work, because this is the way it's done by many people.
But (see below)...
> ---------
> 
> > Am 08/27/2009 01:37 PM Christian Ehrlicher wrote:
> > Why? Does SET_TARGET_PROPERTIES() with COMPILE_FLAGS not work?
> I tried something with SET_TARGET_PROPERTIES but when used on the target
> sim_type1 the define-flag won't be inherited by the library the target
> depends on, thus I used add_definitions instead
> 
> --------
> 
> I think the problem comes with using
>    add_subdirectory(../../VEHICLE VEHICLE)
> and the subsequent
>    add_library(vehicle ${SRC})
> 
> While this sets up a binary directory local to the make-target, it also
> creates CMake*-files 'globally', for all targets.
> 
The problem is probably that you're using relative paths in
add_subdirectory(). Furthermore, if I remember your original mail
correctly, you have a CMakeLists.txt files in your so-called
build-directory. Don't do that, you don't need to.

Example project with directory layout:

source    # use add_subdirectory() to add sub1 and sub2
  sub1    # use add_library() to add libsub1
  sub2    # use add_library() to add libsub2 and
          # target_link_libraries() to make libsub2 depend on libsub1
  main    # use add_executable(prog) to add prog and
          # target_link_libraries() to make it link against the libs.
build
  type1   # build type-1 libs and binaries
  type2   # build type-2 libs and binaries

Only the source directory and its subdirectories contain CMakeLists.txt
files!

>From the directory build/type1, invoke cmake like 'cmake ../..' and add
-DTYPE1 to the preprocessor flags.
Do the same for the directory build/type2.

See tiny example below (hope this helps).

Best regards,
Marcel Loose.


$ pwd
/tmp/cmake/preproc
$ cat CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(demo C)
add_executable(preproc preproc.c)
$ cat preproc.c
#include <stdio.h>
int main()
{
#ifdef TYPE_1
  printf("I am TYPE_1\n");
#elif TYPE_2
  printf("I am TYPE_2\n");
#else
  printf("I don't know my type!\n");
#endif
  return 0;
}
$ mkdir -p build/type_1
$ mkdir -p build/type_2
$ mkdir -p build/no_type
$ cd build/type_1
$ cmake -DCMAKE_C_FLAGS="-DTYPE_1" ../..
-- The C compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/cmake/preproc/build/type_1
$ make
Scanning dependencies of target preproc
[100%] Building C object CMakeFiles/preproc.dir/preproc.c.o
Linking C executable preproc
[100%] Built target preproc
$ ./preproc
I am TYPE_1
$ cd ../type_2
$ cmake -DCMAKE_C_FLAGS="-DTYPE_2" ../..
-- The C compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/cmake/preproc/build/type_2
$ make
Scanning dependencies of target preproc
[100%] Building C object CMakeFiles/preproc.dir/preproc.c.o
Linking C executable preproc
[100%] Built target preproc
$ ./preproc
I am TYPE_2
$ cd ../no_type
cmake ../..
-- The C compiler identification is GNU
-- Check for working C compiler: /usr/bin/gcc
-- Check for working C compiler: /usr/bin/gcc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Configuring done
-- Generating done
-- Build files have been written to: /tmp/cmake/preproc/build/no_type
$ make
Scanning dependencies of target preproc
[100%] Building C object CMakeFiles/preproc.dir/preproc.c.o
Linking C executable preproc
[100%] Built target preproc
$ ./preproc
I don't know my type!





More information about the CMake mailing list