CMake "RUN_TESTS" or "test" target - testing

In my "plange_superbuild" CMakeLists.txt, I have:
add_test(plange_test ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/prefix/src/plange-build --target test)
which should invoke the "plange" sub-project's test target, and works fine when using the Makefile generator. However, the CMake Testing documentation explains:
[ enable_testing() ] adds another build target, which is test for Makefile generators,
or RUN_TESTS for integrated development environments (like Visual
Studio).
So, my snippet doesn't work on builds with an IDE because I'm just saying "test". How can I make the command also work in IDE builds?
I've thought of some possible workaround options. One is to use an existing CMake variable, should it exist, to get the name of the test target. That is a variable (lets call it CMAKE_TEST_TARGET) that would be equal to test except in IDE builds where it would be equal to RUN_TESTS, allowing the following:
add_test(plange_test ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/prefix/src/plange-build --target ${CMAKE_TEST_TARGET})
I'm not aware of such a variable though. Perhaps I could detect IDE based builds via the CMAKE_GENERATOR variable (or MSVC and similar) and manually set the so-called CMAKE_TEST_TARGET variable. That would require knowing (and maintaining) the exact logic that CMake uses to determine "test" or "RUN_TESTS" in my CMakeLists.txt, which would be unreliable.
My other thought is to invoke ctest directly using a variable (let's call is CTEST_COMMAND) that's similar to CMAKE_COMMAND, but points to the ctest executable. Again, I'm not aware of such a variable.
Edit: There is CMAKE_CTEST_COMMAND See https://stackoverflow.com/a/736838/395029 and my comment therein
I derived this variable from CMAKE_COMMAND, using get_filename_component() to extract the bin directory, but this depends on CMAKE_COMMAND not having any embedded arguments. Is that a safe assumption? This works with the Makefile generator, but not with VC++2017 generator. The error message in VC++ is not clear, but here's what I tried:
get_filename_component(CMAKE_EXECUTABLES_DIR ${CMAKE_COMMAND} DIRECTORY)
set(CTEST_COMMAND "${CMAKE_EXECUTABLES_DIR}/ctest${CMAKE_EXECUTABLE_SUFFIX}")
add_test(NAME plange_test COMMAND ${CTEST_COMMAND} WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/prefix/src/plange-build)
The error message in VC++2017 in the superbuild project:
1>The following tests FAILED:
1> 1 - plange_test (Failed)
1>Errors while running CTest
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: The command "setlocal
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: "C:\Program Files\CMake\bin\ctest.exe" --force-new-ctest-process -C Debug
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: if %errorlevel% neq 0 goto :cmEnd
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: :cmEnd
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: :cmErrorLevel
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: exit /b %1
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: :cmDone
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: if %errorlevel% neq 0 goto :VCEnd
1>C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\Common7\IDE\VC\VCTargets\Microsoft.CppCommon.targets(133,5): error MSB3073: :VCEnd" exited with code 8.
1>Done building project "RUN_TESTS.vcxproj" -- FAILED.
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========
I was able to run the command from that error output successully:
C:\...\plange.build\prefix\src\plange-build>ctest --force-new-ctest-process -C Debug
but:
C:\...\plange.build>ctest --force-new-ctest-process -C Debug
fails, so that makes the failure even more confusing. Are one of these common practice? Is there some superior (working) approach that I haven't considered?
Edit: with CMAKE_CTEST_COMMAND I learned that "-C Debug" isn't passed, which makes it fail in IDE. See my comments

In cmake source you can find a variable that is undocummented but may serve your purpose if you are using include(CTest) instead of enable_testing()
Check out this commit: https://github.com/Kitware/CMake/commit/816c9d1aa1f2b42d40c81a991b68c96eb12b6d26#diff-73eaa76f278a4e8afe41a9ffb838ccc4:
# If requested, add an alias that is the equivalent of the built-in "test"
# or "RUN_TESTS" target:
if(CTEST_TEST_TARGET_ALIAS)
add_custom_target(${CTEST_TEST_TARGET_ALIAS}
${CMAKE_CTEST_COMMAND} ${__conf_types}
USES_TERMINAL
)
endif()
endif()
Meaning that if in your Cmakelist.txt you call set(CTEST_TEST_TARGET_ALIAS my_name_for_target_test) and then include(CTest), you can use reliably the my_name_for_target_test acording to this comment (I did not check myself if this really does the trick). Since this alias is created via add_custom_target, this is not a builtins target and you dont have the (really annoying) limitations of thoses, including not being able to add a dependency on it / from it.

Related

Can cmake --build use msbuild instead of devenv

I'm using CMake 3.23 with Visual Studio 2022. From everything I found about cmake --build command it should be running msbuild, but evidently it's running devenv instead. Is there some setting I'm not aware of? How do I get it to run msbuild so I can pass options to it?
This is my generator command:
cmake -G "Visual Studio 17" -A x64 -T v143 ..
And then cmake --build is running devenv instead of msbuild:
cmake --build . --config Release -- /verbosity:detailed
Microsoft Visual Studio 2022 Version 17.2.3.
Copyright (C) Microsoft Corp. All rights reserved.
Invalid Command Line. Unknown Switch : verbosity:detailed.
Use:
devenv [solutionfile | projectfile | folder | anyfile.ext] [switches]
CMake by default is using MSBuild and falls back to devenv if you either requested it deliberately (with CMAKE_MAKE_PROGRAM) or you have an Intel Fortran project in which case it has to use devenv.
You can check if it found MSBuild by checking the CMAKE_VS_MSBUILD_COMMAND variable. And you can force CMake to use MSBuild by setting CMAKE_MAKE_PROGRAM to the MSBuild path (although I don't know how it will behave if you have a Fortran project).

CMake --build verbosity

I run cmake to generate a VS2019 project:
> cmake -B Debug -S . --log-level=TRACE -G "Visual Studio 16 2019" -A Win32
I build it with:
> cmake --build Debug
Microsoft (R) Build Engine version 16.11.2+f32259642 for .NET Framework
Copyright (C) Microsoft Corporation. All rights reserved.
Checking Build System
<snip>
I'd like to see the exact command line CMake is executing to actually start the build engine.
using cmake --build Debug -v outputs more information but still doesn't show how the Build Engine was launched.
I have also tried this, which failed:
>cmake --debug-output --trace --build Debug
Running with debug output on.
Running with trace output on.
CMake Error: Unknown argument --build
CMake Error: Run 'cmake --help' for all supported options.
putting --debug-output and --trace after --build also fails:
>cmake --build Debug --debug-output --trace
Unknown argument --debug-output
Usage: cmake --build <dir> [options] [-- [native-options]]
cmake --build --preset <preset> [options] [-- [native-options]]
Options:
<snip>
How can I get cmake --build to output the exact command (exe & arguments) that is being used for building? And how do I affect it?
For Visual Studio generator CMake uses MSBuild (or whatever the generator is configured for, actually, i think it's kind of "implementation-defined" feature, which is not supposed to be exposed to the users).
You can find full list of MSBuild command-line options here. In order to provide the build tool with the said options use <build-tool-options> of CMake's --build command. E.g. here is (quite verbose) logging:
cmake --build Debug -- -v:d
How can I get cmake --build to output the exact command (exe &
arguments) that is using for building?
As I proposed originally you better just live with the abstractions provided by CMake, but one trick that you may find handy (and it kind of works independently from the build tool) is to try to specify some garbarge options for the tool, so it triggers error and exposes some details:
cmake --build Debug -- garbarge
In this case MSBuild actually prints exactly the command which failed (with original + garbarge arguments):
MSBUILD : error MSB1008: Only one project can be specified.
Full command line: '"C:/Program Files/Microsoft Visual Studio/2022/Community/MSBuild/Current/Bin/amd64/MSBuild.exe" ALL_BUILD.vcxproj /p:Configuration=Debug /p:Platform=x64 /p:VisualStudioVersion=17.0 /v:m garbarge'

"cannot open file 'user32.lib'" when trying to use Visual Studio 2005 on Windows 10

I'm attempting to match output with a C++ Win32 executable compiled with Visual Studio 2005, so I'm trying to use that MSVC to do so. I have a project defined in CMake. I open "Visual Studio 2005 Command Prompt", but when I try to cmake -G "NMake Makefiles" .. I get LINK : fatal error LNK1104: cannot open file 'user32.lib'.
Here's the CMakeLists.txt:
cmake_minimum_required(VERSION 3.15)
# set the project name
project(LEGOStarWarsSaga)
# add the executable
add_executable(LEGOStarWarsSaga src/main.cpp)
Here's the Visual Studio 2005 Command Prompt output:
C:\Users\aprim\Documents\lstsc>mkdir build
C:\Users\aprim\Documents\lstsc>cd build
C:\Users\aprim\Documents\lstsc\build>cmake -G "NMake Makefiles" ..
-- The C compiler identification is MSVC 14.0.50727
-- The CXX compiler identification is MSVC 14.0.50727
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - failed
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 8/VC/bin/cl.exe
-- Check for working C compiler: C:/Program Files (x86)/Microsoft Visual Studio 8/VC/bin/cl.exe - broken
CMake Error at C:/Program Files/CMake/share/cmake-3.19/Modules/CMakeTestCCompiler.cmake:66 (message):
The C compiler
"C:/Program Files (x86)/Microsoft Visual Studio 8/VC/bin/cl.exe"
is not able to compile a simple test program.
It fails with the following output:
Change Dir: C:/Users/aprim/Documents/lstsc/build/CMakeFiles/CMakeTmp
Run Build Command(s):nmake /nologo cmTC_41947\fast && "C:\Program Files (x86)\Microsoft Visual Studio 8\VC\BIN\nmake.exe" -f CMakeFiles\cmTC_41947.dir\build.make /nologo -L CMakeFiles\cmTC_41947.dir\build
Building C object CMakeFiles/cmTC_41947.dir/testCCompiler.c.obj
C:\PROGRA~2\MI30EB~1\VC\bin\cl.exe #C:\Users\aprim\AppData\Local\Temp\nmBDB4.tmp
testCCompiler.c
Linking C executable cmTC_41947.exe
"C:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\cmTC_41947.dir --rc=C:\PROGRA~2\MI30EB~1\VC\bin\rc.exe --mt=C:\PROGRA~2\MI30EB~1\VC\bin\mt.exe --manifests -- C:\PROGRA~2\MI30EB~1\VC\bin\link.exe /nologo #CMakeFiles\cmTC_41947.dir\objects1.rsp #C:\Users\aprim\AppData\Local\Temp\nmBE13.tmp
LINK Pass 1: command "C:\PROGRA~2\MI30EB~1\VC\bin\link.exe /nologo #CMakeFiles\cmTC_41947.dir\objects1.rsp /out:cmTC_41947.exe /implib:cmTC_41947.lib /pdb:C:\Users\aprim\Documents\lstsc\build\CMakeFiles\CMakeTmp\cmTC_41947.pdb /version:0.0 /machine:X86 /debug /INCREMENTAL:YES /subsystem:console kernel32.lib user32.lib gdi32.lib winspool.lib shell32.lib ole32.lib oleaut32.lib uuid.lib comdlg32.lib advapi32.lib /MANIFEST /MANIFESTFILE:CMakeFiles\cmTC_41947.dir/intermediate.manifest CMakeFiles\cmTC_41947.dir/manifest.res" failed (exit code 1104) with the following output:
LINK : fatal error LNK1104: cannot open file 'user32.lib'
NMAKE : fatal error U1077: '"C:\Program Files\CMake\bin\cmake.exe"' : return code '0xffffffff'
Stop.
NMAKE : fatal error U1077: '"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\BIN\nmake.exe"' : return code '0x2'
Stop.
CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
CMakeLists.txt:4 (project)
-- Configuring incomplete, errors occurred!
See also "C:/Users/aprim/Documents/lstsc/build/CMakeFiles/CMakeOutput.log".
See also "C:/Users/aprim/Documents/lstsc/build/CMakeFiles/CMakeError.log".
After reading online, I've come to find that this is something to do with missing the Windows SDK. However, I have the Windows SDKs 7.1 and 10.0 installed. What am I missing?
Bonus points if there's a build tool that'll make this process (nearly) seamless for anyone cloning the project.
EDIT: Installing Visual Studio 2005 Professional with the full Visual C++ option installs the SDK properly, and the project builds. My worry is that not everyone has access to VS 2005 Pro.

CMake project using ifort failed. "is not able to compile a simple test program."

I can compile the project using gfortran in both Linux and Windows with no error. But for some reason I have to use ifort.exe as compiler in Windows and it failed. Anyone can help?
The detailed information is as follows:
-- Detecting Fortran compiler ABI info
-- Detecting Fortran compiler ABI info - failed
-- Check for working Fortran compiler: D:/Program Files/IVF/compilers_and_libraries_2018.3.210/windows/bin/intel64/ifort.exe
-- Check for working Fortran compiler: D:/Program Files/IVF/compilers_and_libraries_2018.3.210/windows/bin/intel64/ifort.exe- broken CMake Error at D:/Program Files/CMake/share/cmake-3.18/Modules/CMakeTestFortranCompiler.cmake:51 (message): The Fortran compiler
"D:/Program Files/IVF/compilers_and_libraries_2018.3.210/windows/bin/intel64/ifort.exe"
is not able to compile a simple test program. It fails with the following output:
Change Dir: C:/Users/xxx/build/CMakeFiles/CMakeTmp
Run Build Command(s):D:/PROGRA~2/MINGW-~1/X86_64~1.0-P/mingw64/bin/mingw32-make.exe cmTC_809ef/fast && mingw32-make.exe[1]: Entering directory 'C:/Users/xxx/build/CMakeFiles/CMakeTmp'
D:/PROGRA~2/MINGW-~1/X86_64~1.0-P/mingw64/bin/mingw32-make.exe -f CMakeFiles\cmTC_809ef.dir\build.make CMakeFiles/cmTC_809ef.dir/build
mingw32-make.exe[2]: Entering directory 'C:/Users/xxx/build/CMakeFiles/CMakeTmp'
Building Fortran object CMakeFiles/cmTC_809ef.dir/testFortranCompiler.f.obj
D:\PROGRA~2\IVF\COMPIL~1.210\windows\bin\intel64\ifort.exe /nologo /fpp /W1 /nologo /fpp /libs:dll /threads /Od /debug:full /dbglibs /FoCMakeFiles\cmTC_809ef.dir\testFortranCompiler.f.obj /FdCMakeFiles\cmTC_809ef.dir/ -c C:\Users xxx\build\CMakeFiles\CMakeTmp\testFortranCompiler.f
warning #31001: The dll for reading and writing the pdb (for example, mspdb110.dll) could not be found on your path. This is usually a configuration error. Compilation will continue using /Z7 instead of /Zi, but expect a similar err r when you link your program.
Linking Fortran executable cmTC_809ef.exe
"D:\Program Files\CMake\bin\cmake.exe" -E cmake_link_script CMakeFiles\cmTC_809ef.dir\link.txt --verbose=1
"D:\Program Files\CMake\bin\cmake.exe" -E vs_link_exe --intdir=CMakeFiles\cmTC_809ef.dir --rc=rc --mt="" --manifests -- xilink /nologo #CMakeFiles\cmTC_809ef.dir\objects1.rsp /out:cmTC_809ef.exe /implib:cmTC_809ef.lib /pdb:C:\Users\xxx\build\CMakeFiles\CMakeTmp\cmTC_809ef.pdb /version:0.0 /machine:x64 /debug /INCREMENTAL:YES /subsystem:console user32.lib
RC Pass 1: command "rc /fo CMakeFiles\cmTC_809ef.dir/manifest.res CMakeFiles\cmTC_809ef.dir/manifest.rc" failed (exit code 0) with the following output:
The system cannot find the file specified.mingw32-make.exe[2]: *** [CMakeFiles\cmTC_809ef.dir\build.make:107: cmTC_809ef.exe] Error -1 mingw32-
make.exe[2]: Leaving directory 'C:/Users/xxx/build/CMakeFiles/CMakeTmp'
mingw32-make.exe[1]: *** [Makefile:140: cmTC_809ef/fast] Error 2
mingw32-make.exe[1]: Leaving directory 'C:/Users/xxx/build/CMakeFiles/CMakeTmp'
The error is because that the rc.exe cannot be found. I solved the problem by adding the file path to the PATH variable.

GDCM vtk msvc2013

I have successfully built VTK 7.1.1 and Qt 5.3.2 with MSVC2013. I have downloaded GCDM and configured with Cmake with no shared_lib. I can build the ALL_BUILD project in GDCM solution configured with CMake, but the INSTALL project can not be built and it gives me this error:
1>------ Build started: Project: vtkgdcm, Configuration: Debug x64 ------
1> vtkImageMapToColors16.cxx
1>c:\vtk\gdcm-2.6.7\utilities\vtk\vtkImageMapToColors16.h(116): error C2555: 'vtkImageMapToColors16::GetMTime': overriding virtual function return type differs and is not covariant from 'vtkObject::GetMTime'
1> C:\VTK\VTK-7.1.1\Common\Core\vtkObject.h(107) : see declaration of 'vtkObject::GetMTime'
2>------ Build started: Project: INSTALL, Configuration: Debug x64 ------
2> -- Install configuration: "Debug"
2> CMake Error at cmake_install.cmake:31 (file):
2> file INSTALL cannot find "C:/VTK/bin/../../../bin/vtkCommonCore-7.1.dll".
2>
2>
2>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(132,5): error MSB3073: The command "setlocal
2>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(132,5): error MSB3073: "C:\Program Files\CMake\bin\cmake.exe" -DBUILD_TYPE=Debug -P cmake_install.cmake
2>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(132,5): error MSB3073: if %errorlevel% neq 0 goto :cmEnd
2>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(132,5): error MSB3073: :cmEnd
2>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(132,5): error MSB3073: endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
2>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(132,5): error MSB3073: :cmErrorLevel
2>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(132,5): error MSB3073: exit /b %1
2>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(132,5): error MSB3073: :cmDone
2>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(132,5): error MSB3073: if %errorlevel% neq 0 goto :VCEnd
2>C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V120\Microsoft.CppCommon.targets(132,5): error MSB3073: :VCEnd" exited with code 1.
========== Build: 0 succeeded, 2 failed, 17 up-to-date, 0 skipped ==========
It says it can not find vtkCommonCore-7.1.dll ,and that file does not exist on my vtk, but the .lib version of the file exists.
Can anybody save me?
I solved my problem this way:
First, I built the .dll missing files by building VTK using shared_libs option ON.
Secondly, as Jamey mentioned I fixed the error C2555 by changing the definition of GetMTime in vtkImageMapToColors16, apparently VTK version 7.1.1 was not compatible with GDCM 2.6. So I changed the output type of GetMTime function from long int to output of the virtual function in vtkObject::GetMTime.