[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