Cmake rerun due to cuda generated files - c++

I have the following situation: I have a CMake file, which is supposed to compile few binary targets.
And I also have CUDA in my project
find_package(CUDA REQUIRED)
include_directories(${CUDA_INCLUDE_DIRS})
add_libraries_to_linker
When i run my cmake everything is fine.
First make target a command also runs smooth but second make command detects that cuda generated file older than Makefile and regenerated cmake that leads to project rebuilding.
How I can disable cmake regeneration?
Am I missing something?
Edit:
I think is should edit my question.
I have a Caffe framework, building from sources and binary that uses it.
When i'm enabling GPU - Cuda generates it's files due to compilation make target a, so when i run another make target i see something like
Re-run cmake file: Makefile older than:
Caffe/src/caffe/CMakeFiles/cuda_compile.dir/layers/cuda_compile_generated_cudnn_relu_layer.cu.o.depend
When GPU is off everything is ok - any make commands do not leads to regeneration

Answer have found in the link below:
Brief: Everything is normal. That's normal behaviour of FindCUDA.cmake.
After first make run .depend files will be included into CMake project and second make run will recompile without regeneration of .depend files.
After second make everything will be okay, and changes in one module will not lead to recompilation in whole project.
https://cmake.org/pipermail/cmake/2011-January/042173.html

Related

CMake Zero Check fails to detect updates in CMakeLists.txt files for Xcode generator

Background
I have big project which builds runs on windows perfectly.
When some changes are applied in CMakeLists.txt and project is build, Visual Studio project is properly updated.
Xcode version: 10.0 (10A255) or 10.1 (10B61) (tested on different machines).
CMake version: 3.12.2 or 3.13.1
Problem
Problem appears when same project is build on Mac OS for Xcode.
After configuring CMake:
cmake .. -G Xcode
Generated project works fine, everything builds properly and test are passing.
Now when CMakeLists.txt files are modified (when developing project or when fetching new changes from repository) and ZERO_CHECK or BUILD_ALL are selected, build doesn't lead to Xcode project update.
Invoking cmake . doesn't detect changes too.
Workaround
The best workaround I've found is deleting everything two files: cmake_install.cmake and CMakeCache.txt. Then rerun command which generates project cmake .. -G Xcode.
In this scenario whole detection is redone from scratch, but at least build doesn't start from zero (unchanged files are not recompiled).
This is painful, since lots of manual stuff must be done, and project have to be recreated and this consumes time.
Hints
In some previous project I had similar problem, but it was happening only if maven was detecting updates for dependencies, so it happened quite rarely. When it happened I just called touch CMakeLists.txt and build again and this workaround was fine. This solution doesn't applies since every build has this issue.
I was suspecting that protobuf generation procedure has something with it, but when I've disabled it problem still persists.
I've tried to provide complete minimal example, by creating simple project file, but I was not able to reproduce the issue. For all other projects it just works, so system configuration is not the issue.
Questions
How can I debug project generation process when running cmake to find source of this problem?
Is this a known problem?
Is there a better workaround which will not lead to full rebuild regenerating project file (which also involves detecting system capabilities)?
Is this a known problem?
Over on the CMake Discourse, Craig Scott (one of the CMake maintainers) has commented on a variant of this bug as a known architectural limitation of Xcode:
With the Xcode generator, targets have a dependency on the ZERO_CHECK target, which is what re-runs cmake for you automatically if something changed. But the problem is that the rest of the build in that run still uses the old details from before cmake . gets run. If you build again, that rebuilds anything whose details changed, but explicitly re-running cmake . first if you know something about the project changed will be more robust and probably avoid more unnecessary rebuilds.
-- https://discourse.cmake.org/t/documented-criteria-for-build-correctness/3087/2?u=alex
Your comment that "invoking cmake . doesn't detect changes" is strange in light of this, but it could be that old CMake versions, like 3.12 and 3.13 which you were using when this question was asked, had a bug that has since been fixed. It could also be something project-specific that we can only guess at. Missing a CMAKE_CONFIGURE_DEPENDS directory property? Have a bad set(... CACHE ... FORCE) call? Can't say...

Is it possible to force CMake generate Visual Studio project on other project type generation?

I have a CMake project. It is a crossplatform project developed by a team of developers. Visual Studio and other make files are inside version control for library release and external developers.
Each time a file is added we need to recompile all project files for all platforms. How do I force CMake to generate new project files for all systems at once (if possible from inside CMakeLists.txt, not as command line arguments)?
I think it doesn't make sense for this to be possible within the CMakeLists.txt file. CMake is a makefile generator. Everything in the CMakeLists.txt file is configuring the makefile, and it can also be repurposed to make project files.
If the CMakeLists.txt file could also request to generate a different kind of makefile... it would be different from every other command in the CMakeLists.txt file in that it isn't describing the currently selected makefile.
If I were you I would just make a shell script, or a simple makefile, separate from CMake, which rebuilds each of the project files, by invoking CMake from command line with appropriate parameters.
Is the goal of the versioned CMake produced build scripts to not force developers to install CMake?
In any case: it's best to use the right tool for the right job. CMake is for producing build-files and the little scripting necessary to do so. Use a scripting environment (Bash, cmd.exe) to run CMake as necessary for all your platforms.
This keeps the CMake files clean (and readable, CMake scripting is hard to read) and provides clean separation of concerns.

Is it justified to delete everything in the build folder before calling cmake?

I am now using cmake to compile and build a C++ project on multiple platforms. Every time the cmake script is called, everything in the building folder is deleted. For example, I use the following shell command to illustrate the way how cmake is called:
rm -rf build_folder
mkdir build_folder
cd build_folder
cmake ..
By doing so, we are sure that the library or binary produced by the project is updated with regard to the source code. However, it may take time as every time camke will call the compiler to build the project from scratch. The reason lies in the fact that we are concerned that cmake may keep some intermediate results from the previous build if we do not delete everything in the building folder. So my question is: are our concerns justified and if just call cmake .. in the previous building folder without deleting anything in the folder what kind of danger can we have?
A major point of using a build system is not having to rebuild everything every time. A correct build system correctly tracks which files have changed and what commands are therefore necessary to do a correct, minimal rebuild.
If that doesn't work for you, you have messed up your build system.
If you are worried about doing builds for different platforms, and the build system not recognizing the difference, that's just one way your build system is messed up. Specifically, the problem is that you are building different variants, sequentially, in the same directory. At least that's what I take from your description. That's stupid, don't do it. Use a different build folder for every platform, call cmake once in each folder with the correct configuration, and then leave it be.

What does cmake .. do?

I got the Box2D project source and want to compile the testbed portion of it.
The project folder contains folders like: freeglu glui testbed(a demo) helloword(a demo)
Box2D Build CMakeFiles
There are many CMakeLists.txt in all the different folders.
I was thinking that I should cmake all those files so that make files are created in all places required.
I read this (as instructions to do do want I want) :
wget http://box2d.googlecode.com/files/Box2D_v2.2.1.zip
unzip Box2D_v2.2.1.zip
cd Box2D_v2.2.1/Build
cmake ..
make
What does the cmake .. do?
There is no CMakeLists.txt in the build folder.
cmake is a Makefile generator.
When you call cmake [path], you ask it to generate a Makefile in the current directory following instructions given in [path]/CMakeLists.txt
Usually cmake output some messages while it is working, and after it is done without errors, you can type "make" to execute your newly created Makefile.
CMakeLists.txt files can reference other CMakeLists.txt file in sub-directories, so you are usually only interested by the CMakeLists.txt of the top directory, not the other ones.
Using an empty "build" directory is a technique called "out-of-source build", in which all your generated files (.o, executable, Makefile, .anything) are generated in the separate "build" directory and not mixed with source files. If you want to clean all, you can delete all the content of the build directory.
In fact, you can put your "build" directory in any place, as long as you give cmake the correct path of the top CMakeLists.txt. You can even have several build directories. It is very useful if you need several different builds at the same time (with different options, different versions of gcc, etc.)
In old programs, you generate the Makefile too, but using ./configure (this is called auto-tools. You may have encountered that already). cmake is considered a successor of the auto-tools.
cmake .. generates makefiles in the current directory, using ../CMakeLists.txt file as starting point. make command, executed after this, builds the program, using generated makefile(s) as an input. This is convenient to keep a source code and build results in different folders. General syntax is: cmake source-dir (of course, there are a lot of other switches).
Well, .. is shorthand for the parent folder, so it will presumably act upon whatever it finds in Box2D_v2.2.1.

Can CMake generate build scripts which do *not* use cmake?

Question: Can CMake generate build scripts that do not, in any way, use CMake? If not, how hard is it to gut a CMake generated automake script to not make any checks against CMake?
I am a big fan of CMake to the point where I am championing the idea that we transition to it in my current work environment. One thing that could ease this transition from our current build system to CMake would be if I could demonstrate that CMake can generate automake files that do not require cmake themselves.
Clearly, I would never want to do this for day to day use, but having the ability to easily create a branch of our code that can be built from source without requiring cmake would go a long way in helping me make my case.
The ability to do this depends on your OS, I'm presuming Unix/Makefile or Windows/MSVC. If you're using MSVC, the cmake dependency should be eliminated by declaring the CMAKE_SUPPRESS_REGENERATION option at the start of your cmake script.
SET(CMAKE_SUPPRESS_REGENERATION TRUE)
On Unix-based systems, however, the Makefiles are tied explicitly to the cmake build files (CMakeFiles, etc). I suspect that this dependency could be bypassed by the strategic commenting out of Makefile directives although, I cannot say what they might be.
No, CMake cannot do this. It doesn't really make sense, either, since without any CMake-support at build-time, there would be no way to check or update the makefiles/project-files themselves when the CMakeLists.txt files have changed.
If you are moving from Visual Studio to CMake, you may want to take a look at vcproj2cmake.
CMake generated files depend on cmake for various commands such as create / remove / etc... not just to regenerate the makefiles on a change so removing cmake is not going to work.
As someone who has taken a large complex piece of software and recently pulled out its existing build system, installing a new build system in its place. I can tell you that it's not easy, but I would definitely not want shell scripts as part of my build process, if they can be avoided. More and more systems will find themselves with CMake on them anyway, as more big name software packages like LLVM and KDE start using it—This is an area where it really accels, large projects.
One of the nice things about CMake is it builds things quicker. Resorting to have to fork shell instances to interpret a script really slows down the build process.
What about the 'atomic solution' ?
EX- auto-generate a "QT moc" file from CMakeLists.txt, then build project that depends on the .cpp file being generated
# inside project level CMakeLists.txt
# run shell script to create the "moc_GUICreator.cpp" auto-generated source file
if(UNIX)
execute_process(COMMAND "sh" ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_moc.sh WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scripts )
endif(UNIX)
Where the .sh file contains:
# generate_moc.sh
echo "generating moc file: moc ../include/GUICreator.h -o ../src/moc_GUICreator.cpp "
moc ../include/GUICreator.h -o ../src/moc_GUICreator.cpp
Equivalent windows batch file, "moc_creator_win.bat":
moc "GUICreator.h" -o "moc_GUICreator.cpp"
Haven't tried this last bit in windows, but it or something very close should work, just after the if(UNIX) block in CMakeLists.txt:
if(WIN32)
execute_process(COMMAND "cmd" ${CMAKE_CURRENT_SOURCE_DIR}/scripts/moc_creator_win.bat WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scripts )
endif(WIN32)
So, basically if you're clever you can do whatever you want from a script and use CMake variables as args to it, I'm not sure if you can ask for more...
the point is to avoid 'non-portable build types' unless you really need to hack it into a specialized compiler, or don't feel like using QT Designer to place the widgets ;-)