Set the directory for Intermediate files (like .obj) in CMake - cmake

I've seen that CMake put the intermediate files, like .obj in a directory like this :
project.dir/sort/of/copy/of/source/directory
Is there a way to have something like that :
project.dir/Debug/ myfiles.obj |--> for my debug
and
project.dir/Release/ myfiles.obj |--> for my release
For moment, I used 2 separate directory to generate each time my libraries or executable for the Debug and the release. And after I have also the platform...
Is there something similar to CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE or CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE...
for intermediate files.obj ?
I've try too the /Fo but when I used this FLAG, Cmake override with his configuration :
warning D9025 : overriding '/Fo;../x64/Debug/' with '/FoCMakeFiles\project.dir\src\project\main.cpp.obj'
Please, does someone have a solution ?

You can't - at least at the moment, see 0014999: Changing Intermediate Directory of Visual Studio 2012 feature request - change the intermediate directories in CMake and for makefile generators - like in your case NMake - you can have only one build configuration type per binary build output directory.
So as #usr1234567 has commented, using two build directories is the right thing to do.
Or - if this is an option - use the Visual Studio multi-configuration generator. It does exactly use the intermediate directories you have suggested:
project.dir/Debug/...
project.dir/Release/...
NMake vs. Visual Studio Solution on the Command Line
The differences can also be seen in the wrapper scripts I normally use to build my CMake based systems.
So NMake would look something like this:
#ECHO off
"\Program Files (x86)\Microsoft Visual Studio 14.0\vc\vcvarsall.bat" x64
IF NOT EXIST "x64\Debug\Makefile" (
cmake -H"." -B"x64/Debug" -DCMAKE_BUILD_TYPE=Debug -G"NMake Makefiles"
)
cmake --build "x64/Debug" --target "project"
IF NOT EXIST "x64\Release\Makefile" (
cmake -H"." -B"x64/Release" -DCMAKE_BUILD_TYPE=Release -G"NMake Makefiles"
)
cmake --build "x64/Release" --target "project"
And my prefered Visual Studio Solution variant something like this:
#ECHO off
IF NOT EXIST "x64\*.sln" (
cmake -H"." -B"x64" -G"Visual Studio 14 2015 Win64"
)
cmake --build "x64" --target "project" --config "Debug"
cmake --build "x64" --target "project" --config "Release"
Additional References
CMAKE_BUILD_TYPE is not being used in CMakeLists.txt
CMake build multiple targets in different build directories
CMake: how to specify the version of Visual C++ to work with?
The Architecture of Open Source Applications - CMake

Related

How do I use CMake with debugging information?

At the moment I'm compiling via
cmake --build . --config RelWithDebInfo
I'm not sure if this makes sense but it works. I would like to use the debugging of CMake which, afaik, can be set via DCMAKE_BUILD_TYPE=Debug. When I try to use this the compiling itself works:
cmake -DCMAKE_BUILD_TYPE=Debug .
but here I don't get an .exe file somewhere. I guess I miss the --build or --config option from before but how do I properly add them?
edit: Thanks to vre's input I'm coming along better. However, this is the output now:
C:\geant4\sim> cmake -DCMAKE_BUILD_TYPE=Debug .
-- Selecting Windows SDK version 10.0.22000.0 to target Windows 10.0.19042.
-- Configuring done
-- Generating done
CMake Warning:
Manually-specified variables were not used by the project:
CMAKE_BUILD_TYPE
-- Build files have been written to: C:/geant4/sim
why is the build type not used?

How do I build a CMake project?

I have just acquired an arbitrary CMake project from the internet and I am not sure how to compile it. What commands do I need to run to build it from the command line?
Basic steps
If you're on a Unix-y operating system, like Linux or macOS, then you would run:
$ cmake -DCMAKE_BUILD_TYPE=Release -S /path/to/source-dir -B /path/to/build-dir
$ cmake --build /path/to/build-dir
Here, /path/to/source-dir is the directory containing the root-level CMakeLists.txt, this is most commonly the root of a source control repository. Meanwhile, /path/to/build-dir is a distinct directory (that does not need to exist yet) that CMake will use to store the generated build system and its outputs. This is called an out-of-tree build. You should never attempt an in-tree build with CMake because of the possibility of name clashes and difficulty involved with cleaning up the generated files.
When building with a single-config generator (like Make, which is the default on Unix), you specify the build type by setting the CMAKE_BUILD_TYPE variable in the first command, known as the configure step. You must always set this variable when working with a single-config generator. The built-in configs are Debug, Release, RelWithDebInfo, and MinSizeRel. See this answer for more detail on this.
After the configure step, you may build the project by either calling the underlying build tool (in this case, make) or by calling CMake's generic build launcher command (cmake --build), as I do here.
If you're on Windows, then the default generator is Visual Studio, which is a multi-config generator. This means the build type is chosen during the build step rather than the configure step, and the commands must be adjusted accordingly:
$ cmake -S /path/to/source-dir -B /path/to/build-dir
$ cmake --build /path/to/build-dir --config Release
These steps assume that the CMake build you are looking at is well behaved. If a project fails to build with the above steps and you have all of its dependencies installed to system locations (and they are well behaved), then you should open an issue with the upstream project. The most common source of bad behavior in mature CMake builds is dependency handling. Too often you will have to read the build or its documentation to determine which variables need to be set (via -D, like we did with CMAKE_BUILD_TYPE above) for the project to find its dependencies.
Advanced topics
Setting options and cache variables
Some projects offer options to enable/disable tests, components, features, etc. These are typically done by writing entries to the CMake cache during the configure step. For example, a common way to disable building tests is to set BUILD_TESTING to NO at the command line:
$ cmake -S /path/to/source-dir -B /path/to/binary-dir [...] -DBUILD_TESTING=NO
This particular variable is a convention, but is not guaranteed to be honored. Check the project's documentation to see which options are available.
Selecting a generator and toolchain
When using the Visual Studio generators specifically, you can tell CMake which platform you wish to target and which version of the compiler you would like to use. The full form of the CMake configure command for this is:
$ cmake -G "Visual Studio 16 2019" -A <ARCH> -T<TOOLSET> [...]
Valid values of <ARCH> include Win32, x64, ARM, and ARM64. If <TOOLSET> is not specified, then the 32-bit MSVC compiler will be used. Typically, you will want this to be host=x64 to ensure that 64-bit MSVC is used, which can allocate more memory for large linking steps. You can also set <TOOLSET> to ClangCL to use the Visual Studio provided ClangCL tools.
On all generators, CMake sniffs the environment for which compiler to use. It checks the CC and CXX environment variables for the C and C++ compilers, respectively. If those are empty, it will look for cc and c++ executables in the PATH. You can manually override the compilers by setting the CMAKE_C_COMPILER and CMAKE_CXX_COMPILER CMake cache (not environment) variables at the CMake command line (using -D again).
Installing & using dependencies
Once a CMake project has been built, you may install it either systemwide or (preferably) to a local prefix by running:
$ cmake --install /path/to/build-dir --prefix /path/to/install-dir [--config Release]
Where --config is only required if a multi-config generator was used. Once installed to a local prefix, a project that depends on it may be configured by setting CMAKE_PREFIX_PATH to /path/to/install-dir.

Google GMOCK build libgmock.a under windows

I try to build the gmock library from google under windows, avialable on github from here:
https://github.com/google/googletest/tree/master/googlemock
I tried to use cmake in the cygwin console, but I could not build it.
cmake C:\Users\Username\Downloads\googlemock-master\googlemock-master\googlemock
"CMake Error: The source directory "C:UsersSETDownloadsgooglemock-mastergooglemock-mastergooglemock" does not exist.
Specify --help for usage, or press the help button on the CMake GUI."
Then I installed visual studio 2017 and opened the gmock.sln file, but also this build failed.
"Error C1083: "gtest/internal/gtest-linked_ptr.h": No such file or directory gmock C:\Users\Username\Downloads\googlemock-master\googlemock-master\googlemock\include\gmock\internal\gmock-port.h"
Does anyone have an idea how I could build this library under windows 10?
Edit: Ok, for cmake the path needs to have /../ and not ..\, but i still don't get which path I need to include in cmake
Very simple:
Under the googlemock folder, create a new folder, named build (for example);
cd build && cmake ..
Basically, you're creating a new folder for the build (preferably inside the project tree, but not necessary), cd into it, and run cmake <dir>, where <dir> is the path to CMakeLists.txt, which contains the recipe for generating the build.
That's it. Now you'll have a generated gmock.sln, which you could build with Visual Studio.
For CMake to generate Visual Studio projects, you should have the Visual Studio binaries and Windows SDK reachable from your PATH.
Finally, you need to specify a generator, using CMake's -G parameter, for telling CMake which Visual Studio version you'd like projects to be generated for.
Example of putting this together:
set PATH="C:\Program Files\Microsoft Visual Studio 14.0\VC\bin";"c:\Program Files\Windows Kits\8.1\bin\x86";%PATH%
cd build
cmake -G "Visual Studio 14 2015" ..
For additional instructions, you may refer to googletest github page:
https://github.com/google/googletest/blob/master/googletest/README.md#using-cmake

Is there a workaround that I can use so that I can test the build type when using CMake in combination with Visual Studio and multiple configurations?

I would like to work with 'Debug', 'Release', 'Debug_Unicode' and 'Release_Unicode'
I have been able to use the DEBUG_CONFIGURATIONS variable so that the 'Debug Unicode' configuration correctly gets used as debug
This is what I tried to do in the CmakeLists.txt file:
target_link_libraries(tests
optimized ${CMAKE_BINARY_DIR}/src/${CMAKE_BUILD_TYPE}/foo.lib
debug ${CMAKE_BINARY_DIR}/src/${CMAKE_BUILD_TYPE}/foo.lib
)
Clearly CMake is able to make a choice between debug and release at this point, as it has to choose the 'optimized' or 'debug' library.
However, CMAKE_BUILD_TYPE is an empty string.
The best that I have been able to come up with is to work with a separate solution file for each of the configurations,
passing in CMAKE_BUILD_TYPE myself:
cmake -G Visual Studio 11 2012 Win64 -DCMAKE_BUILD_TYPE=Debug_Unicode C:\foo
As Antonio was mentioning
target_link_libraries(tests foo)
or just
add_dependencies(tests foo)
would be sufficient to link the correct library from the same configuration.
If you want to do more advanced stuff, take a look at the generator expressions. They are configuration sensitive incl. in Visual Studio's multi-configuration environment and they would work also for the target_link_libraries() command.
So your example would look like:
target_link_libraries(tests ${CMAKE_BINARY_DIR}/src/$<CONFIG>/foo.lib)
I have used generator expression e.g. in custom commands that need to be aware of the output path of my DLL (if foo would be generating an MSTest DLL):
add_test(
NAME RunFooTest
WORKING_DIRECTORY $<TARGET_FILE_DIR:foo>
COMMAND vstest.console.exe /InIsolation /Platform:x86 $<TARGET_FILE:$foo>
)
And - just because you mentioned different solutions - you can use CMake to build a certain configuration from the command line. This would in your case look like e.g.
cmake --build C:\foo --target ALL_BUILD --config Debug_Unicode

CMake: How to build projects in a cross-platform manner?

I'm trying to build a project in a cross-platform manner.
I'm using CMake to generate project files on the fly, but it's not clear how to then compile those project files in a cross-platform way. I found try_compile but it's not clear whether this will do what I want. Any ideas?
For example, say I am using Visual Studio 2010 against project foo. I am expecting CMake to generate foo.sln, and then build it (generate the binaries). I know how to automate the first part, but how do I automate the second?
From the CMake docs:
"CMake is a cross-platform build system generator."
So in other words, once CMake has generated the project files, it's work is really done.
You can invoke the native build tool via CMake using the --build flag, e.g.
cmake --build . --config Release --target install -- /M:4
See here for further info.