38

I need to compile different versions of a certain project by adding compiler switches. Usually I would do this by using add_definitions or something like

set_property( TARGET mylib PROPERTY COMPILE_DEFINITIONS _MYDEFINE=1 )

in the CMakeLists.txt file.

In this specific project however, I am not allowed to modify any sources, including the CMakeLists.txt file.

I was hoping that something like

cmake -D_MYDEFINE=1 <path to sources>

would generate a project file (Visual Studio 2008 in my case, but shouldn't matter) which includes _MYDEFINE=1 in its preprocessor definitions but in fact it won't.

What are my options here? Is there a different cmake command line option to achieve this? Feel free to suggest solutions not including the command line, as long as changing the project's CMakeLists.txt is not necessary.

Tim Meyer
  • 12,210
  • 8
  • 64
  • 97

3 Answers3

30

I managed to do it this way now:

I was able to convince everybody to add the following lines to the common CMakeLists.txt:

IF (NOT DEFINED _MYDEFINE)
    SET(_MYDEFINE <default value>)
ENDIF()
ADD_DEFINITIONS(-D_MYDEFINE=${_MYDEFINE})

(No it is not really called "MYDEFINE", and <default value> is just a placeholder, I just replaced all that for this example)

This does not change the current behaviour of compiling with no additional compiler flags and is thus a valid change.

And it allows you to do

cmake -D_MYDEFINE=<my value> <path to sources>

where this cmake definition will be mapped to a C++ precompiler definition when cmake creates the project file.

Tim Meyer
  • 12,210
  • 8
  • 64
  • 97
  • ADD_DEFINITIONS(-D_MYDEFINE) – parasrish Aug 10 '18 at 03:55
  • Instead of conditional setting of `_MYDEFINE` variable it is better to set CACHE variable: `SET(_MYDEFINE CACHE STRING "Additional definition" )`. This reflects the meaning of the variable: **user-provided parameter**. – Tsyvarev Jul 17 '21 at 09:41
11

Container CMakeLists.txt solution

Tricky solution:

Your read only CMakeList.txt path: ${path}/ReadOnlyProject/CMakeLists.txt

Create a new CMakeList.txt to upper to the read only library (${path}/CMakeLists.txt):

CMAKE_MINIMUM_REQUIRED(VERSION 2.8.0)
PROJECT (FAKE_PROJECT)

ADD_DEFINITIONS(-D_MYDEFINE=1)

ADD_SUBDIRECTORY(ReadOnlyProject)

Now use your new project (FAKE_PROJECT) to compile. If the ReadOnlyProject does not set compilers definitions directly, it could work.


On Visual Studio 2010:

Try to modify c:\Users\${username}\AppData\Local\Microsoft\MSBuild\v4.0\Microsoft.Cpp.Win32.user.props to add custom compiler settings.

You should add the followings:

<Project>
  ...
  <ItemDefinitionGroup>
    <ClCompile>
      <PreprocessorDefinitions>__MYDEFINE=1;%(PreprocessorDefinitions)</PreprocessorDefinitions>
    </ClCompile>
  </ItemDefinitionGroup>
</Project>
Naszta
  • 7,560
  • 2
  • 33
  • 49
6

To pass a C++ or C pre-processor define without modifying any CMake source files, use the environment variables CFLAGS for C or CXXFLAGS for C++ respectively, e.g.:

$ export CXXFLAGS="-D_MY_DEFINE=1 -D_MY_OTHER_DEFINE=1"
$ mkdir build
$ cd build
$ cmake ..
sakra
  • 62,199
  • 16
  • 168
  • 151