<div dir="ltr"><div class="gmail_extra">Continuing on here from results of bug submittal at <a href="http://public.kitware.com/Bug/view.php?id=14705" target="_blank">http://public.kitware.com/Bug/view.php?id=14705</a> I will try to post whatever necessary bits from that here in hopes of making this cohesive discussion.<br>
<br>The bug report example has two CMakeLists.txt files:<br><br>external_project/CMakeLists.txt<br><br>referred to here as TOP and<br><br>external_project/some_external_project/CMakeLists.txt<br><br>referred to here as SUB, sets some CMAKE_C*_FLAGS (not using CACHE FORCE). TOP ExternalProject_Adds SUB and tries to set CMAKE_C*_FLAGS* and friends vars by using -DVAR_NAME:VAR_TYPE="VAR_VALUE" with VAR_TYPE as INTERNAL in hopes of FORCING subproject vars, which IMHO should not be this difficult.<br>
<br></div><div class="gmail_extra">From Bug Report Brad responds with:<br><br></div><div class="gmail_extra">"FORCE tells set() to overwrite an existing non-INTERNAL cache entry and
ignore whatever the user may have manually configured. An INTERNAL
cache entry means it belongs to the project and should not be edited by
the user manually."<br>
<br></div><div class="gmail_extra">Yes force will overwrite and existing non-INTERNAL cache entry. I am passing the values as INTERNAL so why is a non forced value overriding it in the subproject? There are various CMAKE_* variables some are specified as INTERNAL such as *maybe*<br>
<br><b><code>CMAKE_<LANG>_COMPILER_ABI</code></b>: An internal variable subject to change.<br><b><code>CMAKE_<LANG>_PLATFORM_ID</code></b>: An internal variable subject to change.<br><b><code>CMAKE_INTERNAL_PLATFORM_ABI</code></b>: An internal variable subject to change.<br>
<br></div><div class="gmail_extra">as I am not *sure* if internal == INTERNAL<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">but not <br><br></div><div class="gmail_extra">CMAKE_C*_FLAGS* and friends.<br>
<br></div><div class="gmail_extra">At least that's my probably incorrect understanding.<br></div><div class="gmail_extra"><br>From Bug Report Brad also responds with:<br><br>
"The code in your ExternalProject_Add call correctly sets the cache entry
values for the build tree of the inner project. However, as I
explained in <a href="http://public.kitware.com/Bug/view.php?id=14705#c34966" title="0014705: [2014-01-20 09:17] Brad King" target="_blank">0014705:0034966</a>
the code in your inner-project's CMakeLists.txt hides those values by
setting normal variables of the same name. Therefore the cache values
are not visible and are ignored regardless of their type or value. This
is explained in the documentation linked in <a href="http://public.kitware.com/Bug/view.php?id=14705#c34968" title="0014705: [2014-01-20 09:22] Brad King" target="_blank">0014705:0034968</a>."<br>
<br>Document Brad referred to is:<br><br><a href="http://cmake.org/gitweb?p=cmake.git;a=blob;f=Help/manual/cmake-language.7.rst;hb=1b395813#l393" target="_blank">http://cmake.org/gitweb?p=cmake.git;a=blob;f=Help/manual/cmake-language.7.rst;hb=1b395813#l393</a><br>
<br>This document does not state any
persistence a variable should have when terms INTERNAL or FORCE are
used. From my reading documentation "INTERNAL implies FORCE". So while
the document has a wonderful discussion on variables it says nothing as
to how variables persist or can be overridden. If it is explained there I certainly do not see where. I almost wonder if the wrong link was posted in his reply.<br><br><br></div><div class="gmail_extra">Yes the inner project does specify the values. However should passing in the variable type as INTERNAL imply FORCE and override the internal setting of the subproject as INTERNAL implies FORCE? Clearly it does not, but should it? I really wish I could get a direct answer to this simple question. It's as though the documentation implies a certain functionality, but CMake does not operate this way. <br>
<br>The referenced document makes no reference to FORCE or INTERNAL. If this is the holy grail of CMake internal operation then shouldn't it? The document references a persistent cache, but I do not glean from this how it promptly ignores types as he states such as INTERNAL. I don't see or understand how it is explained here and I am probably thick headed on this and just not seeing it. It appears to expalin some of the internal workings of the language, but not how external interfaces affect it such as -D at the command prompt or when using ExternalProject_Add. This document is "aware" of -D option (Paragraph beginning "To support legacy CMake code"), but does not reference how it is interpreted and how variables are ignored or stored in the CACHE.<br>
<br></div><div class="gmail_extra">I also enjoy reading the grammar definition for CMake in order to determine how CMake should work. I had never see this doc before this post. It also looks as though it refrences CMake 3.0 so maybe 3.0 will have a better gramar parser? Not sure how this document helps me in 2.8 if this is gramar spec for 3.0, but likely backwards compatible?<br>
</div><div class="gmail_extra"><br></div><div class="gmail_extra">This doc may need section such as<br><br></div><div class="gmail_extra">"ExternalProject_Add and Command Line Scope<br></div><div class="gmail_extra">
CMake promptly ignores all attempts you the take to set or force variables in project if variables are set in project even if said variables are not CACHE FORCE in sub project. Thinking about using -DVAR_NAME:INTERNAL="VAR_VALUE" thinking that INTERNAL implies FORCE... don't bother CMake will ignore that too. What's FORCE mean?... certainly not what you think. Ha Ha programmer jokes on you :-)!"<br>
</div><div class="gmail_extra"><br></div><div class="gmail_extra">Or something to that effect :-)<br></div><div class="gmail_extra"><br>These variables in the sub project are set, but are not forced so should not be setting of these variables be overridden by parent project when -DCMAKE_C_FLAGS_DEBUG:INTERNAL="/MDd /Z7 /Od" is specified to ExternalProject_Add.<br>
<br></div><div class="gmail_extra">Or maybe a better question is what should I expect from specifying INTERNAL as clearly it is not what I expect from reading the documentation... really any documentation so far.<br></div>
<div class="gmail_extra">
<br>Also above document referenced following doument which was also no help.<br><a href="http://www.cmake.org/cmake/help/git-master/manual/cmake-variables.7.html">http://www.cmake.org/cmake/help/git-master/manual/cmake-variables.7.html</a><br>
<br><br><br>From documentation <a href="http://www.cmake.org/cmake/help/v2.8.12/cmake.html">http://www.cmake.org/cmake/help/v2.8.12/cmake.html</a>: <br><br></div><div class="gmail_extra"><snip><br></div><div class="gmail_extra">
INTERNAL = No GUI entry (used for persistent variables).<br><br>If <type> is INTERNAL, the cache variable is marked as internal, and will not be shown to the user in tools like cmake-gui. This is intended for values that should be persisted in the cache, but which users should not normally change. INTERNAL implies FORCE.<br>
</div><div class="gmail_extra"><end snip><br></div><div class="gmail_extra"><br>Now either:<br><br></div><div class="gmail_extra">1) Above statement is a lie<br></div><div class="gmail_extra">2) It is correct and INTERNAL does not work in all use cases of CMake including ExternalProject_Add and and the command prompt using -D option.<br>
</div><div class="gmail_extra">3) It is correct and CMake has a bug or is not correctly implemented for all use cases.<br></div><div class="gmail_extra"><br><br></div><div class="gmail_extra">From Command prompt calling into the subproject(SUB above): <br>
<br>c:\projects\CMakeTesting\external_project_test\some_external_project\build> del *.* && cmake -DCMAKE_C_FLAGS_DEBUG="=====SOME_OTHER_VARIABLE =====" ..\<br>CMAKE_CXX_FLAGS_INIT=/DWIN32 /D_WINDOWS /W3 /Zm1000 /EHsc /GR<br>
Following line for CXX DEBUG should contain /MDd<br>CMAKE_CXX_FLAGS_DEBUG=/D_DEBUG /MTd /Zi /Ob0 /Od /Gm<br>CMAKE_CXX_FLAGS_DEBUG_INIT=/D_DEBUG /MTd /Zi /Ob0 /Od<br>CMAKE_C_FLAGS_DEBUG=CHILD_PROJECT_DEBUG<br>CMAKE_C_FLAGS_DEBUG_INIT=/D_DEBUG /MTd /Zi /Ob0 /Od<br>
CMAKE_C_FLAGS_RELEASE=CHILD_PROJECT_RELEASE<br>SOME_VAR=ChildProjectSomeValue<br>ANOTHER_VAR=<br>-- Configuring done<br>-- Generating done<br>-- Build files have been written to: C:/projects/CMakeTesting/external_project_test/some_external_project/build<br>
</div><br><br><div class="gmail_extra">So CMAKE_C_FLAGS_DEBUG is not changed to "=====SOME_OTHER_VARIABLE====="<br></div><div class="gmail_extra">and remains CHILD_PROJECT_DEBUG. I have slightly modified my version of the example I posted to bug report and changed flags to a simple string argument. So CMake appears to promptly ignore -DVAR_NAME=VAL_VALUE if set in sub project which I guess is normal.<br>
<br></div><div class="gmail_extra">Lets add -LA to opts see what happens, but still not specify INTERNAL:<br><br>c:\projects\CMakeTesting\external_project_test\some_external_project\build> del *.* && cmake -LA -DCMAKE_C_FLAGS_DEBUG="=====SOME_OTHER_VARIABLE =====" ..\<br>
CMAKE_CXX_FLAGS_INIT=/DWIN32 /D_WINDOWS /W3 /Zm1000 /EHsc /GR<br>Following line for CXX DEBUG should contain /MDd<br>CMAKE_CXX_FLAGS_DEBUG=/D_DEBUG /MTd /Zi /Ob0 /Od /Gm<br>CMAKE_CXX_FLAGS_DEBUG_INIT=/D_DEBUG /MTd /Zi /Ob0 /Od<br>
CMAKE_C_FLAGS_DEBUG=CHILD_PROJECT_DEBUG<br>CMAKE_C_FLAGS_DEBUG_INIT=/D_DEBUG /MTd /Zi /Ob0 /Od<br>CMAKE_C_FLAGS_RELEASE=CHILD_PROJECT_RELEASE<br>SOME_VAR=ChildProjectSomeValue<br>ANOTHER_VAR=<br>-- Configuring done<br>-- Generating done<br>
-- Build files have been written to: C:/projects/CMakeTesting/external_project_test/some_external_project/build<br>-- Cache values<br>CMAKE_BACKWARDS_COMPATIBILITY:STRING=2.4<br>CMAKE_CONFIGURATION_TYPES:STRING=Debug;Release;MinSizeRel;RelWithDebInfo<br>
CMAKE_CXX_FLAGS:STRING= /DWIN32 /D_WINDOWS /W3 /GR /EHsc<br>CMAKE_CXX_FLAGS_DEBUG:STRING=/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1<br>CMAKE_CXX_FLAGS_MINSIZEREL:STRING=/MD /O1 /Ob1 /D NDEBUG<br>CMAKE_CXX_FLAGS_RELEASE:STRING=/MD /O2 /Ob2 /D NDEBUG<br>
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=/MD /Zi /O2 /Ob1 /D NDEBUG<br>CMAKE_CXX_STANDARD_LIBRARIES:STRING=kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uu<br>id.lib comdlg32.lib advapi32.lib<br>
CMAKE_C_FLAGS:STRING= /DWIN32 /D_WINDOWS /W3<br>CMAKE_C_FLAGS_DEBUG:STRING======SOME_OTHER_VARIABLE =====<br>CMAKE_C_FLAGS_MINSIZEREL:STRING=/MD /O1 /Ob1 /D NDEBUG<br>CMAKE_C_FLAGS_RELEASE:STRING=/MD /O2 /Ob2 /D NDEBUG<br>
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=/MD /Zi /O2 /Ob1 /D NDEBUG<br>CMAKE_C_STANDARD_LIBRARIES:STRING=kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid<br>.lib comdlg32.lib advapi32.lib<br>
CMAKE_EXE_LINKER_FLAGS:STRING= /machine:X86<br>CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=/debug /INCREMENTAL<br>CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=/INCREMENTAL:NO<br>CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=/INCREMENTAL:NO<br>
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=/debug /INCREMENTAL<br>CMAKE_INSTALL_PREFIX:PATH=C:/Program Files (x86)/Project<br>CMAKE_LINKER:FILEPATH=C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/link.exe<br>
CMAKE_MAKE_PROGRAM:FILEPATH=C:/PROGRA~2/MICROS~4.0/Common7/IDE/<a href="http://devenv.com">devenv.com</a><br>CMAKE_MODULE_LINKER_FLAGS:STRING= /machine:X86<br>CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=/debug /INCREMENTAL<br>
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=/INCREMENTAL:NO<br>CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=/INCREMENTAL:NO<br>CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=/debug /INCREMENTAL<br>CMAKE_RC_COMPILER:FILEPATH=rc<br>
CMAKE_RC_FLAGS:STRING=<br>CMAKE_SHARED_LINKER_FLAGS:STRING= /machine:X86<br>CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=/debug /INCREMENTAL<br>CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=/INCREMENTAL:NO<br>CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=/INCREMENTAL:NO<br>
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=/debug /INCREMENTAL<br>CMAKE_SKIP_INSTALL_RPATH:BOOL=NO<br>CMAKE_SKIP_RPATH:BOOL=NO<br>CMAKE_STATIC_LINKER_FLAGS:STRING=<br>CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=<br>CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=<br>
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=<br>CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=<br>CMAKE_USE_RELATIVE_PATHS:BOOL=OFF<br>CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE<br>EXECUTABLE_OUTPUT_PATH:PATH=<br>LIBRARY_OUTPUT_PATH:PATH=<br>
<br></div><div class="gmail_extra">Ok so there's a lot of goop there, but the important bits are the line <br></div><div class="gmail_extra"><br>CMAKE_C_FLAGS_DEBUG=CHILD_PROJECT_DEBUG<br><br></div><div class="gmail_extra">
before the line <br><br>-- Configuring done<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">and the line <br><br></div><div class="gmail_extra">CMAKE_C_FLAGS_DEBUG:STRING======SOME_OTHER_VARIABLE =====<br>
<br></div><div class="gmail_extra">Which means CMake sees it and promplty ignores it in subproject. Why this is standard operating procedure I am not sure, but I am familiar with it operating this way.<br></div><div class="gmail_extra">
<br></div><div class="gmail_extra">Hey I know maybe we can pass it in as INTERNAL as that implies FORCE. Which I understand to mean FORCE in the CACHE.<br></div><div class="gmail_extra"><br><br>c:\projects\CMakeTesting\external_project_test\some_external_project\build>cmake -LA -DCMAKE_C_FLAGS_DEBUG:INTERNAL="===<br>
==SOME_OTHER_VARIABLE =====" ..\<br>CMAKE_CXX_FLAGS_INIT=/DWIN32 /D_WINDOWS /W3 /Zm1000 /EHsc /GR<br>Following line for CXX DEBUG should contain /MDd<br>CMAKE_CXX_FLAGS_DEBUG=/D_DEBUG /MTd /Zi /Ob0 /Od /Gm<br>CMAKE_CXX_FLAGS_DEBUG_INIT=/D_DEBUG /MTd /Zi /Ob0 /Od<br>
CMAKE_C_FLAGS_DEBUG=CHILD_PROJECT_DEBUG<br>CMAKE_C_FLAGS_DEBUG_INIT=/D_DEBUG /MTd /Zi /Ob0 /Od<br>CMAKE_C_FLAGS_RELEASE=CHILD_PROJECT_RELEASE<br>SOME_VAR=ChildProjectSomeValue<br>ANOTHER_VAR=<br>-- Configuring done<br>-- Generating done<br>
-- Build files have been written to: C:/projects/CMakeTesting/external_project_test/some_external_project/build<br>-- Cache values<br>CMAKE_BACKWARDS_COMPATIBILITY:STRING=2.4<br>CMAKE_CONFIGURATION_TYPES:STRING=Debug;Release;MinSizeRel;RelWithDebInfo<br>
CMAKE_CXX_FLAGS:STRING= /DWIN32 /D_WINDOWS /W3 /GR /EHsc<br>CMAKE_CXX_FLAGS_DEBUG:STRING=/D_DEBUG /MDd /Zi /Ob0 /Od /RTC1<br>CMAKE_CXX_FLAGS_MINSIZEREL:STRING=/MD /O1 /Ob1 /D NDEBUG<br>CMAKE_CXX_FLAGS_RELEASE:STRING=/MD /O2 /Ob2 /D NDEBUG<br>
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=/MD /Zi /O2 /Ob1 /D NDEBUG<br>CMAKE_CXX_STANDARD_LIBRARIES:STRING=kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uu<br>id.lib comdlg32.lib advapi32.lib<br>
CMAKE_C_FLAGS:STRING= /DWIN32 /D_WINDOWS /W3<br>CMAKE_C_FLAGS_MINSIZEREL:STRING=/MD /O1 /Ob1 /D NDEBUG<br>CMAKE_C_FLAGS_RELEASE:STRING=/MD /O2 /Ob2 /D NDEBUG<br>CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=/MD /Zi /O2 /Ob1 /D NDEBUG<br>
CMAKE_C_STANDARD_LIBRARIES:STRING=kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid<br>.lib comdlg32.lib advapi32.lib<br>CMAKE_EXE_LINKER_FLAGS:STRING= /machine:X86<br>CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=/debug /INCREMENTAL<br>
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=/INCREMENTAL:NO<br>CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=/INCREMENTAL:NO<br>CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=/debug /INCREMENTAL<br>CMAKE_INSTALL_PREFIX:PATH=C:/Program Files (x86)/Project<br>
CMAKE_LINKER:FILEPATH=C:/Program Files (x86)/Microsoft Visual Studio 11.0/VC/bin/link.exe<br>CMAKE_MAKE_PROGRAM:FILEPATH=C:/PROGRA~2/MICROS~4.0/Common7/IDE/<a href="http://devenv.com">devenv.com</a><br>CMAKE_MODULE_LINKER_FLAGS:STRING= /machine:X86<br>
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=/debug /INCREMENTAL<br>CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=/INCREMENTAL:NO<br>CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=/INCREMENTAL:NO<br>CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=/debug /INCREMENTAL<br>
CMAKE_RC_COMPILER:FILEPATH=rc<br>CMAKE_RC_FLAGS:STRING=<br>CMAKE_SHARED_LINKER_FLAGS:STRING= /machine:X86<br>CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=/debug /INCREMENTAL<br>CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=/INCREMENTAL:NO<br>
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=/INCREMENTAL:NO<br>CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=/debug /INCREMENTAL<br>CMAKE_SKIP_INSTALL_RPATH:BOOL=NO<br>CMAKE_SKIP_RPATH:BOOL=NO<br>CMAKE_STATIC_LINKER_FLAGS:STRING=<br>
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=<br>CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=<br>CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=<br>CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=<br>CMAKE_USE_RELATIVE_PATHS:BOOL=OFF<br>
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE<br>EXECUTABLE_OUTPUT_PATH:PATH=<br>LIBRARY_OUTPUT_PATH:PATH=<br></div><div class="gmail_extra"><br></div><div class="gmail_extra">So the line following line is still unchanged<br></div><div class="gmail_extra">
<br></div><div class="gmail_extra">CMAKE_C_FLAGS_RELEASE=CHILD_PROJECT_RELEASE<br><br>before the line<br><br>-- Configuring done</div><div class="gmail_extra"><br></div><div class="gmail_extra">and the line <br><br>CMAKE_C_FLAGS_DEBUG:STRING======SOME_OTHER_VARIABLE =====<br>
<br></div><div class="gmail_extra">has disappeared whch it should. So it ran away and hid and still did nothing. Clearly did not FORCE. INTERNAL implies RUN AWAY HIDE DO NOTHING when used from external interfaces such as command prompt and ExternalProject_Add at least from my experience.<br>
<br></div><div class="gmail_extra">I am sure I have all this wrong.<br></div></div>