[CMake] debug/optimized include directories

Michael Hertling mhertling at online.de
Sat Nov 5 16:59:56 EDT 2011


On 11/02/2011 05:36 PM, Michael Wild wrote:
> Thanks ;-)
> 
> Michael

Just an additional remark: Instead of generating the proxy headers
in CMakeLists.txt, i.e. at configuration time, one might also have
them generated by a custom command, i.e. at build time, which has
the $<CONFIGURATION> expression available. E.g., one might use a
CMake script invoked by the custom command via -P with -DCONFIG=
$<CONFIGURATION>, and within this script, one could do arbitrary
things based on the CONFIG parameter, i.e. linking/copying real
headers, generating proxy headers with or without #ifdefs etc.
In this way, one can gather the entire machinery in the script
and does not need to do the case differentiation in the header
itself, triggered via COMPILE_DEFINITIONS_<CONFIG> properties.
Besides, with the custom command's DEPENDS clause, the actions
can be set up to re-take place if any prerequisite has changed.

Regards,

Michael

> On 11/02/2011 05:33 PM, Robert Dailey wrote:
>> Awesome idea, +1
>>
>> This is probably the best work-around until includes get a target property.
>>
>> ---------
>> Robert Dailey
>>
>>
>> On Wed, Nov 2, 2011 at 2:43 AM, Michael Wild <themiwi at gmail.com
>> <mailto:themiwi at gmail.com>> wrote:
>>
>>     On 11/01/2011 09:49 PM, Robert Dailey wrote:
>>     > Well if you need any help coding the feature let me know. I'm already
>>     > liking the idea of adding features I want myself into CMake :)
>>     >
>>     > Thanks!
>>     >
>>     > ---------
>>     > Robert Dailey
>>     >
>>     >
>>     > On Tue, Nov 1, 2011 at 3:47 PM, David Cole <david.cole at kitware.com
>>     <mailto:david.cole at kitware.com>
>>     > <mailto:david.cole at kitware.com <mailto:david.cole at kitware.com>>>
>>     wrote:
>>     >
>>     >     On Tue, Nov 1, 2011 at 4:33 PM, Robert Dailey
>>     <rcdailey at gmail.com <mailto:rcdailey at gmail.com>
>>     >     <mailto:rcdailey at gmail.com <mailto:rcdailey at gmail.com>>> wrote:
>>     >     > On Tue, Nov 1, 2011 at 3:32 PM, David Cole
>>     <david.cole at kitware.com <mailto:david.cole at kitware.com>
>>     >     <mailto:david.cole at kitware.com
>>     <mailto:david.cole at kitware.com>>> wrote:
>>     >     >>
>>     >     >> Not yet
>>     >     >
>>     >     > Meaning there are plans in the works to add such
>>     functionality in
>>     >     the near
>>     >     > future?
>>     >     > For now I guess I could actually hard code VS environment
>>     >     variables in my
>>     >     > include directory strings, such as $(Configuration).
>>     >
>>     >     There is a feature planned to add per-target include
>>     directories (as a
>>     >     target property). As part of that work, we will probably naturally
>>     >     also add per-configuration values of that new target property.
>>     It is
>>     >     not yet added as a feature request in the bug tracker, but
>>     there are
>>     >     related ones that I may "borrow" for the purpose. Stay tuned
>>     for more
>>     >     info, but it is not coming in the next week or two. Hopefully,
>>     in time
>>     >     for 2.8.7, but it depends on timing at this point.... so no
>>     promises.
>>     >
>>     >     For now, your $(Configuration) idea is probably your best bet.
>>     (And
>>     >     would continue to work even after we implement this feature...)
>>     >
>>     >
>>     >     HTH,
>>     >     David
>>
>>     Alternatively, if you want to keep it cross-platform and generator
>>     independent, you could use a proxy header which #include's the correct
>>     header using relative or absolute paths using #ifdef's. Probably that
>>     proxy header would need to be generated by configure_file(). You then
>>     would pass the configuration name by setting the
>>     COMPILE_DEFINITIONS_<CONFIG> property on the directory, target or source
>>     file affected.
>>
>>
>>     Say you have the following layout:
>>
>>     project/
>>     |-- CMakeLists.txt
>>     |-- src/
>>     |   |-- frobnicate.c
>>     `-- include/
>>        |-- Debug/
>>        |   |-- foo.h
>>        |   `-- bar.h
>>        `-- Optimized/
>>            |-- foo.h
>>            `-- bar.h
>>
>>     Now, you want to include the configuration dependent foo.h and bar.h in
>>     frobnicate.c without having to change frobnicate.c itself and might look
>>     like this:
>>
>>     frobnicate.c
>>     <<<<<<<<<<<<
>>     #include "foo.h"
>>     #include "bar.h"
>>
>>     int main(int argc, char** argv)
>>     {
>>      foo();
>>      bar();
>>      return 0;
>>     }
>>     >>>>>>>>>>>>
>>
>>     To get around the issue of needing a configuration-dependent include
>>     path, you could do the following in your CMakeLists.txt file:
>>
>>     CMakeLists.txt:
>>     <<<<<<<<<<<<<<<
>>     cmake_minimum_required(VERSION 2.6)
>>     project(frobnicate C)
>>
>>     # loads of stuff ....
>>
>>     # generate wrapper headers for foo.h and bar.h
>>     foreach(hdr foo.h bar.h)
>>      # find a good include guard name
>>      string(TOUPPER "${hdr}" incguard)
>>      string(REGEX REPLACE "[^a-zA-Z0-9_]" "_" incguard
>>        "PROXY_HDR_${incguard}")
>>      # write the proxy header
>>      file(WRITE "${PROJECT_BINARY_DIR}/include/${hdr}"
>>     "
>>     /* AUTOMATICALLY GENERATED BY CMAKE -- DO NOT EDIT! */
>>     #pragma once
>>     #ifndef ${incguard}
>>     #define ${incguard}
>>
>>     /* if building debug configuration, include Debug/${hdr},
>>       otherwise Optimized/${hdr} */
>>     #if defined(CONFIG_DEBUG)
>>     #  include \"Debug/${hdr}\"
>>     #else
>>     #  include \"Optimized/${hdr}\"
>>     #endif
>>
>>     #endif
>>     ")
>>     endforeach()
>>
>>     # set up the definitions for the switch yard
>>     set_directory_properties(PROPERTIES
>>      COMPILE_DEFINITIONS_DEBUG CONFIG_DEBUG
>>      COMPILE_DEFINITIONS_RELEASE CONFIG_RELEASE
>>      COMPILE_DEFINITIONS_RELWITHDEBINFO CONFIG_RELWITHDEBINFO
>>      COMPILE_DEFINITIONS_MINSIZEREL CONFIG_MINSIZE_REL)
>>
>>     # set up the include directories so our proxy headers and the actual
>>     # headers can be found by the preprocessor
>>     include_directories(
>>      ${PROJECT_BINARY_DIR}/include
>>      ${PROJECT_SOURCE_DIR}/include)
>>
>>     add_executable(frobnicate frobnicate.c)
>>
>>     >>>>>>>>>>>>>>>
>>
>>
>>     HTH
>>
>>     Michael


More information about the CMake mailing list