force refresh of cmake script in subsequent runs of 'make' - c++

In my cmake script I determine the current date and hand it to my c++ program source, so that the build date is compiled into the program. The problem is, that in subsequent runs of make, in which cmake is acutally not run at all, the date is not updated.
How can I force cmake to refresh it's variables and recompile the program by using make only? Alternatively: What is the best way to compile the build date into the binary?
The cmake script contains this:
INCLUDE(Today)
TODAY(DATE)
ADD_DEFINITIONS(
...
-DBUILD_DATE=\"${DATE}\"
)

you could use a custom target to execute whatever you want. custom targets are always considered out of date and run on every build.
add_custom_target(RerunCmake ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR})
add_dependencies(YourTarget RerunCmake)
this works fine with makefiles. but visual studio for example will nag you after every build asking to reload the project because the project files changed on disk.
maybe it would be better to make a custom target that just updates a header file with the correct date so cmake doesn't rerun on every build

Related

Automate CMake build using C++ script

I would like to automate the build of CMake using an MSVC C++ script instead of using CMake-gui to generate the build or CMake terminal or using the CMake integrated on MSVC 2017 by right click on the CMakeLists.txt to build it manually. Assume we have a project (name it: initialize) that includes the CMakeLists.txt and initialize.cpp, so my question is how I can convert these commands into a C++ code, assume build_initialize.cpp:
mkdir build
cd build/
cmake ..
So, the requirement of this tiny C++ code is to
Set the path to this project
Create build folder
Run CMake
At the end if I execute build_initialize.exe, the job is just to build the initialize.cpp using CMake. The goal is to test if the build is success or not as a test case within another project that has several test cases.
You may ask, why I didnot include it to the top CMakelists.txt, and then build it from the beginning using CMake. If I am going to do that, I will get an executable file. As a result, by running the ctest of CMake, the initialize.exe will require a pace of hardware. This is not the goal. My goal is just to build it. If I run build_initialize.exe, just repeat the build using CMake without initialize.exe execution.
Sorry, it could be very simple, but I lack the good experience either in C++ or CMake. Two days have been lost without success.
Thanks to all of you for the comments. The answer has been given by #Fred. To run cmake from C++ script, simply the system() can be used such as: System(cmake -S path_to_src -B path_to_bld).
Useful link: https://faq.cprogramming.com/cgi-bin/smartfaq.cgi?id=1043284392&answer=1044654269

Cmake rerun due to cuda generated files

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

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.

Update option (of Make file) in CMake

I have a big project that uses CMake to create Make file. Sometimes, I add one small project and then have to run the CMake script for whole project (like delete previous, and create newer CMake with this project included).
I was wondering, whehter there is some option in CMake whereby I can only "update" the Make script (created by CMake) to include newly added project (rather than above option).
Thanks,
You can only do
cmake .
in directory which contains CMakeCache.txt. This will trigger whole reconfiguration, but save your options.

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 ;-)