[CMake] Making cmake automatically pick up changes to directory contents.

billw at billw.mail1.co.uk billw at billw.mail1.co.uk
Tue Dec 3 08:15:43 EST 2013


> On 2013-12-02 12:58,
> billw at billw.mail1.co.uk wrote:
>> I just finished converting a large project from VC project files to
>> Cmake
>> generated ones and am using file GLOBing to generate the file lists for
>> builds. This is working fine and I don't see the benefit to explicitly
>> specifying every file.
>>
>> I know the docs recommend not using GLOB, but the only reason given is
>> that cmake won't do a rebuild when new files are added. This seems like
>> a
>> limitation of the build system not a good reason.
>
> More like a design choice made for various reasons; a major one (as Bill
> alludes to) being performance.
>
>> So is there any good way to cause a CMake rebuild of a project when the
>> contents of the directory change? I am thinking something like
>> outputting
>> the directory listing to a file (i.e. dir /b/s > filelist.txt) and
>> adding
>> that file as some sort of dependency to the project. But I don't know
>> exactly how this would be done in practice.
>>
>> Any ideas or canonical methods?
>
> Idea: don't do that :-).
>
> Besides what Bill mentioned, if you're working on a project with more
> than one instance of the source tree (i.e. you are using VCS¹ and/or
> have more than one developer), explicitly listing files helps with
> 'forgot to add' errors since other builds will explicitly try to build a
> file that doesn't exist, thus making such mistakes obvious, rather than
> failing at some other point because a source file is missing.
>
> (¹ I recommend to - and do - use VCS even for personal projects. With
> most DVCS's e.g. git, it's really easy to do so, and having a history is
> invaluable, especially if the project later grows. Plus it's ever so
> much easier to work on a project from multiple machines :-).)
>
> --
> Matthew
>
> --
>
> Powered by www.kitware.com
>
> Please keep messages on-topic and check the CMake FAQ at:
> http://www.cmake.org/Wiki/CMake_FAQ
>
> Kitware offers various services to support the CMake community. For more
> information on each offering, please visit:
>
> CMake Support: http://cmake.org/cmake/help/support.html
> CMake Consulting: http://cmake.org/cmake/help/consulting.html
> CMake Training Courses: http://cmake.org/cmake/help/training.html
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Follow this link to subscribe/unsubscribe:
> http://www.cmake.org/mailman/listinfo/cmake

I am primarily using CMake because Visual Studio project management is
clunky and broken (I won't go in to the many issues here), my team is
still using Visual Studio only for all their work. I am trying to make the
transition as painless as possible for them, and it doesn't seem
reasonable to expect them to manage enormous (1800+) file lists when we
already have a directory structure in place the designates project file
lists. Hence the GLOBing (my various Googlings for the issue shows that
I'm definitely not the only one trying to work like this).

I still haven't seen a good reason why this is a bad idea other than that
CMake doesn't support treating GLOBs as a dependency that requires
re-evaluating on each run.

Regardless I am at a partial solution now that I will share for posterity,
and follow up with a couple more questions if you don't mind:

cmake_compare_files.bat:

-------------------------------------------------------------------------------
rem *** list ALL source, Qt UI and header files into a file
dir /B/S *.cpp;*.ui;*.h;*.inl > all_files2.txt
rem *** compare with the old list
fc all_files.txt all_files2.txt > nul
if errorlevel 1 goto files_different
echo Files lists have not changed.
goto complete
:files_different
echo Files lists have changed! Running CMake...
rem *** update the list
copy all_files2.txt all_files.txt
rem *** touch the solution CMakeLists file to cause cmake to rebuild
everything
copy CMakeLists.txt /B+ ,,/Y
-------------------------------------------------------------------------------

Solution CMakeLists.txt:
-------------------------------------------------------------------------------
add_custom_target(CHECK_FILE_LISTS ALL "cmake_compare_files.bat")

# add_project_with_file_list_checks(<dir with another CMakeLists.txt in
it> <subfolder under build to generate to, NOT a string>)
function(add_project_with_file_list_checks src_loc name)
	add_subdirectory(${src_loc} "${name}")
	add_dependencies(${projectPrefix}${name} CHECK_FILE_LISTS)
endfunction()

# add projects below here using add_project_with_file_list_checks
-------------------------------------------------------------------------------

This is rough and not quite there yet so I have a couple more questions
that might help me improve it:

* Firstly:
How can I inject CHECK_FILE_LISTS as a dependency of ZERO_CHECK? I tried
this already:

add_custom_target(ZERO_CHECK)
add_custom_target(CHECK_FILE_LISTS ALL "cmake_compare_files.bat")
add_dependencies(ZERO_CHECK CHECK_FILE_LISTS)

But that just results in a circular dependency of course.

* Secondly, issues with the CMake VS2010 Macro integration:
a) If CMake fails when auto running in Visual Studio 2010 it seems to just
freeze and I have to kill it from Process Explorer.
b) The CMake Visual Studio 2010 macros seem incapable of killing the in
progress build to reload the solution, the build just carries on. I have
taken to just manually building ZERO_CHECK when I make a change, as
anything else causes a wasted build.

Are these known, are there fixes?


Thanks for the help so far!




More information about the CMake mailing list