[CMake] Forcing /MDd using externalproject_add

Brian Davis bitminer at gmail.com
Wed Jan 22 13:04:47 EST 2014


Thanks Brad for replying.  Comments below.


On Wed, Jan 22, 2014 at 11:09 AM, Brad King <brad.king at kitware.com> wrote:

> On 01/22/2014 11:27 AM, Brian Davis wrote:
> >
> http://cmake.org/gitweb?p=cmake.git;a=blob;f=Help/manual/cmake-language.7.rst;hb=1b395813#l393
> >
> > This document does not state any persistence a variable should have
> > when terms INTERNAL or FORCE are used.
>
> It does link to the set() command documentation
>
>  http://www.cmake.org/cmake/help/v2.8.12/cmake.html#command:set
>
> which does explain INTERNAL and FORCE.  (The reason I posted a
> link to the version control viewer instead of published docs is
> because that cmake-languages.7 manual has not yet been in a
> release so it is not published anywhere persistent yet.)
>
> However, your problem has nothing to do with setting the cache
> value, or FORCE, or INTERNAL.  See below.
>
> On 01/17/2014 03:14 PM, Brian Davis wrote:
> > finding the offending file and there the following lines are found:
> >
> >  # these settings never change even for C or C++
> > SET(CMAKE_C_FLAGS_DEBUG "/MTd /Z7 /Od")
>
> This is the fundamental problem.  This is setting a normal variable
> in the *directory scope* of the project.  The document I linked
> explains how variable value lookup occurs, and that directory scope
> bindings are preferred before cache entries.  Therefore this line
> of code in the project *tells CMake to ignore the cache entry* so
> it doesn't matter how you try to set it with ExternalProject_Add.
>
> ***This restriction is a bug in that project and not in CMake.***
>
> Apparently directory scope even overrides if INTERNAL which implies FORCE
is used when specified from external interfaces such as command prompt and
ExternalProject_Add.  If you are saying it should work this way then ... I
guess it should work this way... though I really really which it did not.

But lets analyze the statement "is a bug in the project" for a moment.
Said project is DCMTK, but really does not matter.  Lets think of it as a
Stand Alone Project (SAP).  Now SAP can be compiled on its own... or
through the magic of ExternalProject_Add included in the build of a Super
Build Project (SBP).

For what ever reason they (SAP) fliped to using /MTd when it was /MDd.  If
compiled stand alone it is desired to work out of the box so the developers
of SAP needed to specify CMAKE_C*_FLAGS* and friends to get it to compile
right?.  They needed to specify something. Now some poor sap (me - not SAP)
wants to build SAP in SBP along with some other SAP that uses /MDd and not
/MTd... you seeing the problem here?  And thanks to the wonders on how
CMake should/does work I can't seemingly reach in there and override (flip
those bits) SAP from SBP.

Imagine that you are trying to get VTK, and DCMTK to compile.  VTK uses
/MDd and DCMTK uses /MTd.  You try to get them to play nice in SBP along
with boost .... and.... well I am in for a world-o-hurt.

So let's not refer to this as a "bug in project" (SAP), but rather a
necessary setting that when used in a SBP with ExternalProject_Add appears
to point to a use case which CMake simply appears not to handle all that
well (at all).  Am I correct/incorrect on this assessment?  Unless you are
saying that they should not have specified CMAKE_C*_FLAGS and friends in
this way and should have use some unbeknownst to me and clearly them method.



> > Then I think ok let's force it.  Where I think my options are:
> >
> > 1) patch
>
> This would work but your arguments against it are valid.
> Having "cmake -E patch" would be nice but it it non-trivial
> to implement as discussed in
>
>  http://thread.gmane.org/gmane.comp.programming.tools.cmake.user/48648
>
>
Oh no I have already gone through this pain and I have it working as I
posted earlier using gnuwin32 utils and my patch macro.


> You could also write a .cmake script to edit the code using
> file(READ), string(REPLACE), and file(WRITE) and run that script
> as the ExternalProject patch step.
>
> Man I don't even want to go there. As using git at patch is much easier
having non-trivially implemented it. It is also more flexible.  Hack Hack
Hack... git diff > patch_file.patch.

For those reading this and looking for an alternate to above.  From
ExternalProject_Add
#--Custom targets-------------
    [STEP_TARGETS st1 st2 ...]  # Generate custom targets for these steps

where one of the st[N] targets you specify could also do the trick (patch).



> > 2) pass the following into ExternalProject_Add and hope that the
> > documentation for cmake is correct (more on this later):
> >  -DCMAKE_C_FLAGS_DEBUG:INTERNAL="/MDd /Z7 /Od"
>
> The documentation is correct and this does set the cache entry, but
> since *the project tells CMake to ignore the cache entry* it doesn't
> matter how you set it.
>
> > 3) use -C to cache string force the variables in as specified
> > http://cmake.org/Wiki/CMake_FAQ#Make_Override_Files
>
> Ditto #2.
>
> Man this was going to be my next try, but from what I am reading that wont
work either.


> > 4) Something I had not thought of. Recommendations welcome
>
> Apply the patch manually and create a new tarball to publish at
> a URL you control and give that to ExternalProject_Add.  Using
> a URL you control also allows you to ensure that it persists
> into the future as long as you need it.
>

Ouch.   err less disk space in my git repo (though I have done this) if I
ExternalProject_Add and patch.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.cmake.org/pipermail/cmake/attachments/20140122/25f6b356/attachment-0001.html>


More information about the CMake mailing list