Cmake : Dependency to run if there's any change - visual-studio

I'm new to Cmake and I have a main output named TARGET. I'm trying to add custom target named _COPY_ASSETS_TARGET as a dependency to main TARGET. I want TARGET to rebuild _COPY_ASSETS_TARGET automatically if there's any change in _COPY_ASSETS_TARGET. _COPY_ASSETS_TARGET should depend on change in folders.
Here's the code I tried to implement:
if (NOT TARGET ${_COPY_ASSETS_TARGET})
add_custom_target(${_COPY_ASSETS_TARGET})
add_dependencies(${_ARGS_PROJECT_TARGET} ${_COPY_ASSETS_TARGET})
set_property(TARGET ${_COPY_ASSETS_TARGET} PROPERTY FOLDER "Targets")
endif()
add_custom_command(TARGET ${_COPY_ASSETS_TARGET}
${_COMMANDS}
VERBATIM
)
I'm trying visual studio to debug and if I rebuild _COPY_ASSETS_TARGET then only I can see the updated output. I would like to know how I can link my folders to _COPY_ASSETS_TARGET so that TARGET automatically builds new code

add_custom_command(OUTPUT ${OUTPUT_DIRECTORY} ${_COMMANDS}
DEPENDS ${DEPENDENT_DIRECTORY}
VERBATIM
)
add_custom_target(${_COPY_ASSETS_TARGET} ALL
DEPENDS ${OUTPUT_DIRECTORY}
)
add_dependencies(${_ARGS_PROJECT_TARGET} ${_COPY_ASSETS_TARGET})
set_property(TARGET ${_COPY_ASSETS_TARGET} PROPERTY FOLDER "Targets")
I found this to be working for my project

Related

Have Intermediate CMake Files Appear in the IDE

I am developing a system of build scripts for CMake and have an issue with wanting to have intermediate CMakeLists.txt files appear in the IDE for easier search and edit.
I have a main CMake file that includes a directory that includes several subdirectories for libraries.
CMakeLists.txt
--- SubProjects:
-------CMakeLists.txt
-------ProjectAFolder:
----------CMakeLists.txt
-------ProjectBFolder:
----------CMakeLists.txt
-------ProjectCFolder:
----------CMakeLists.txt
In the SubProjects folder, the CMakeLists.txt is very simple and just includes the subproject folders one after the other:
SET(SUBDIRECTORIES ProjectAFolder
ProjectBFolder
ProjectCFolder )
foreach (subdirectory ${SUBDIRECTORIES})
add_subdirectory(${subdirectory})
endforeach ()
However, when I generate this in XCode or Visual Studio, the IDE does not include the intermediate CMakeLists.txt file anywhere because it does not belong to any individual library or executable target. What is the best way to include this somewhere so it appears in an IDE?
Depends on where you want the file to show up, since it doesn't belong to any target. You can simply add it to any existing target (just as you do with source files) or you can create a new custom target.
add_library(AnyExistingTarget <other source files> SubProjects/CMakeLists.txt)
Or create a custom target:
add_custom_target(MyIntermediateCMakeFiles SubProjects/CMakeLists.txt)
For Visual Studio, you could also use the built-in support for cmake. It will display the source tree in the IDE without any extra work.

Can't have CMake property ADDITIONAL_CLEAN_FILES delete a simple file

My build system manually generates some files from others. It's using Visual Studio 2015 with CMake 3.11.4. It uses ADD_CUSTOM_TARGET to invoke some internal scripts. Those scripts end up creating a file containing the timestamp when files where generated and this file is later used to only generate what needs to be.
I want this file containing the timestamp to be deleted when we clean the solution (In Visual Studio, "Build" -> "Clean solution"). I tried to add some CMake instruction:
SET_TARGET_PROPERTIES( MY_TARGET PROPERTIES ADDITIONAL_CLEAN_FILES "C:/dev/build/generated.timestamp" )
SET_PROPERTY( TARGET MY_TARGET APPEND PROPERTY ADDITIONAL_CLEAN_FILES "C:/dev/build/generated.timestamp" )
SET_PROPERTY( GLOBAL APPEND PROPERTY ADDITIONAL_CLEAN_FILES "C:/dev/build/generated.timestamp" )
SET_DIRECTORY_PROPERTIES( PROPERTIES ADDITIONAL_CLEAN_FILES "C:/dev/build/generated.timestamp" )
But none of them makes the file be deleted when I clean.
Is this doable and if so, what am I doing wrong?

Change cmake generated project files directory

I could not find any question that was helpful concerning my question, so here it is (or prove me wrong).
First: I do everything under Windows and build only for Visual Studio.
My Situation: I have my main directory which contains a "main" CMakeLists. So here is were to make the cmake call and it does not much itself:
cmake_minimum_required(VERSION 3.13.1)
project (EulerAdventureReinvented)
if (CMAKE_GENERATOR MATCHES Win64)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/Win64/")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/Win64/")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/bin/Win64/")
else()
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/Win32/")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/lib/Win32/")
set(EXECUTABLE_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/bin/Win32/")
endif()
add_subdirectory(source)
But it adds another CMakeLists in the source directory which does the setup for the "main" project. So it contains the add_executable call and I wanna keep it that way. But the problem is that it does write the vcxproj files, CMakeFiles dir into that source directory, but I want them in the root directory or... well just somewhere else.
Final Question: What do I need to set for this? I mean which variable is the one I want to change. I searched and found so many that I came to a point of trial and error and even then did not find my files somewhere else.
EDIT: I changed the title a bit to avoid confusion between build and generated files. I do not want to set the build path, since that is already done by the above code.
In CMake 3.13.2 the following switches are available:
cmake [<options>] -S <path-to-source> -B <path-to-build>
So in the case you described above it would be something like:
cmake -S . -B .\build
Now, there is no variable for setting <path-to-build> but you can get it's information from CMAKE_BINARY_DIR. The variables you are setting control where artifacts wind up but not where project files are created or intermediate files are located.

Customize building VC++ in VS2010

I have a big C++ project and I need to do many steps in the building phase because I am building an application that is compatible with both 64 and 32, I have three projects:
proj1,Porj2,Proj3
and I need to do the following:
Exclude a cpp File from proj1 (32bit version)
Include a cpp file to proj1 (64bit version)
build proj1
build proj2
Execute output of proj2
Exclude a cpp File from proj3 (32bit version)
Include a cpp file to proj3 (64bit version)
Build proj3
Rename the exe that was built from proj3
Exclude a cpp File from proj1 (64bit version)
Include a cpp file to proj1 (32bit version)
still there are some other steps ... I was doing that manually and its frustrating, I found the I need to use MSBUILD but is it used for building native code ? and how can I perfrom these tasks ?
-Excluding and Including cpp files into projects
-Building proj
In Visual Studio 2010 and later, C++ projects use MSBuild.
Rather than excluding or including files based on the configuration, it would be simpler to use a preprocessor directive to conditionally compile the contents of the file. E.g., wrap the entire contents of the file in:
#ifdef MY_32BIT_BUILD_MACRO
// Source file contents here
#endif
And likewise with a macro for 64-bit builds. When using Visual C++, you can use the _M_IX86 and _M_X64 predefined macros to detect whether you are compiling for x86 or x64, respectively.
Alternatively, you could add a Condition property to the ClCompile item for the particular source file in the project file, and have it only included in the build when certain properties are set. I think that conditional compilation within the source file is a better option, though, unless you have complex rules that you need to use to determine whether to include a file or not.
In your solution, you can set project dependencies to ensure that one project is built before another. Right-click the solution, select Properties, and browse to Common Properties -> Project Dependencies. Dependencies can also be specified in a project file.
You can execute the output of a build by using a post-build task. Right-click the project, select Properties, and browse to Configuration Properties -> Build Events. The Post-Build event can be used to execute a command when the build has completed.
Rather than renaming an executable after build, it's easier to just have the build produce an executable with the right name. In the Project properties, under Configuration Properties -> General, the Target Name property can be used to set the name of the primary build output.

Disabling a Visual Studio project for building using cmake

I'm generating a VS2010 solution with a few projects (currently 4, will be up to 10-20 in the end). I only want one of them to build; the rest should be disabled. I can do this manually by going into the configuration manager and unchecking the boxes I don't want, but obviously this isn't a good solution.
Is there something I can add to the CMakeLists.txt file for a project that will cause it to do this? Searching through the docs, google and SO yielded nothing.
Update: Here is my root CMakeLists.txt in case that helps:
cmake_minimum_required(VERSION 2.8)
add_definitions(-DCOMPILER_MSVC)
project (PDEngine)
set(LINKER_LANGUAGE CXX)
add_subdirectory (units/platform)
add_subdirectory (units/render_api)
add_subdirectory (units/memory)
add_subdirectory (units/game)
set(custom_exe "${CMAKE_CURRENT_BINARY_DIR}/units/Platform/Debug/Platform.lib2")
add_custom_command(OUTPUT ${custom_exe}
COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/local/msvc/bam.bat -j $ENV{NUMBER_OF_PROCESSORS}
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/local/msvc/bam.bat
)
#add_custom_command(OUTPUT ${custom_exe_clean}
#COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/local/msvc/bam.bat -c
#DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/local/msvc/bam.bat
#)
add_custom_target(bam ALL DEPENDS ${custom_exe})
#add_custom_target(bamclean ALL DEPENDS ${custom_exe_clean}})
(The bam.bat stuff is based off of the answer I got here: How do I configure CMake to make the VS solution use a specific build commandline? )
And here's the CMakeLists.txt for the "platform" project:
cmake_minimum_required (VERSION 2.8)
project (Platform)
set (COMPILER_MSVC 1)
include_directories(${Platform_SOURCE_DIR}/include)
file(GLOB Project_HEADERS ${Platform_SOURCE_DIR}/include/platform/*.h)
source_group("Headers" FILES ${Project_HEADERS})
add_library(Platform STATIC EXCLUDE_FROM_ALL src/*.cpp ${Project_HEADERS})
So if what you want to do is not build something by default, you can remove it from the "ALL" target (which shows up in Visual Studio as ALL_BUILD). The way you do this is with the target property EXCLUDE_FROM_ALL, or by passing EXCLUDE_FROM_ALL to add_executable and add_library. (Custom targets default to EXCLUDE_FROM_ALL, so there, to do the reverse, you add ALL to the arguments to add_custom_target).
Then, all your targets will show up, but when clicking "build solution", only the ones you want will build. Others can be built by right clicking them and choosing "Build", like the built-in INSTALL project/target.
There is a EXCLUDE_FROM_DEFAULT_BUILD target property for that purpose.
See https://stackoverflow.com/a/14911387/594456.

Resources