CTest can't find executables under Visual Studio on Windows - visual-studio

When building tests on the Windows platform with Visual Studio from a CMake project, CTest is unable to locate the executables for it. The tests are located under a subfolder tests/, but the generated project files for Visual Studio appear to put all executables under bin/ in the build tree. Here is a snippet of the CMakeLists.txt for the tests folder:
project(tests)
enable_testing()
...
add_executable(basicTest basictest.cpp)
target_link_libraries(basicTest gtest_main)
add_test(basicTest basicTest)
When building this on Linux and Mac OS platforms, there is no issue, CTest can find and execute all the tests. For the command cmake -B build -S ., the tests can be found as expected under build/tests/basicTest. However, when using the Visual Studio Generator that comes with CMake on Windows, it outputs all binaries under paths with build/bin/$(ConfigurationName)/basicTest.exe. When running ctest -V, it reports that it tries the following paths:
build/tests/basicTest
build/tests/basicTest.exe
build/tests/Release/basicTest
build/tests/Release/basicTest.exe
build/tests/Debug/basicTest
build/tests/Debug/basicTest.exe
But never paths under build/bin/. If I copy the folder build/bin/Release/ into build/tests/ then CTest reports all tests were successful. What's the correct fix for this to make CTest operate correctly across all platforms?
Do I need to add something to the path used by the add_test() CMake command? Do I need to add a property to the targets to place them correctly, or a property to the tests to tell them where their executable is?
Bonus: This should probably be it's own question, but is there a straight-forward way to get vtest.console.exe to also run these tests? I can already run all the tests from the Visual Studio "Run All Tests" menu option.

Related

CMake run shell command after building error

I have a Visual Studio 2019 CMake project and i need to run a postbuild script which copys a file (The file is not generated by the build process). What i did so far is add a custom command in CMake with
add_custom_command(TARGET testExec POST_BUILD COMMAND "../postbuild.bat")
The postbuild.bat would copy the file. This works great most of the time but when my build fails due to some compile error, the postbuild script won't be executed.
How can i run the postbuild script even if the build fails ? I know there is a similar question here but sadly no proper solution. If there is a way to configure a postbuild event directly inside a Visual Studio CMake project this would also be suitable, but it seems like this is not possible (because in a cmake project i don't have a project file).
Since The copied file is not generated by the build you can use PRE_BUILD. On Visual Studio Generators, it runs before any other rules are executed within the target.(https://cmake.org/cmake/help/latest/command/add_custom_command.html).
The other solution could be to use add_custom_command(OUTPUT as the file seems independent of the build.

How to print WORKING_DIRECTORY in CMake?

I have this line in my CMakeLists.txt:
add_test(NAME ${PROJECT_NAME} COMMAND ${PROJECT_NAME} WORKING_DIRECTORY ${PROJECT_SOURCE_DIR})
The problem is that WORKING_DIRECTORY does not seem to be set correctly.
message("Futurama ${PROJECT_SOURCE_DIR}")
It shows that PROJECT_SOURCE_DIR is what I expect, but when I run my generated VS projects, the work folder is $(ProjectDir), and that is wrong since I do the build in a separate folder.
Is it possible that setting of WORKING_DIRECTORY is broken for the Visual Studio generator?
If not, how can I print the status of WORKING_DIRECTORY after add_test?
There are a few ways you may verify that the WORKING_DIRECTORY is set properly.
Programmatically (as commented):
get_test_property(${PROJECT_NAME} WORKING_DIRECTORY test_dir)
message("My test's working directory: ${test_dir}")
Inspection:
Navigate to the CTestTestfile.cmake file in your build folder, and open it in a text editor. You can see in the commands here that the WORKING_DIRECTORY property is being properly set.
However, the $(ProjectDir) listed for Working Directory of the RUN_TESTS Visual Studio project is pointing to a folder in your build directory; this is a Debugging property and isn't actually used when running the CTest tests. This is used when Visual Studio is debugging an executable. Because the RUN_TESTS project cannot actually be debugged (the CTest tests are actually run as a post-build event), this Working Directory property doesn't apply to your situation.

Select MSVS build configuration when generating a buildsystem with CMake

I have a multiplatform CMake project, and occasionally I have to build it manually for Windows. I generate a buildsystem like this:
cmake -DCMAKE_BUILD_TYPE=Release -G"Visual Studio 16 2019" -A x64 ../path/to/source
Then I open *sln file and press F7 to build. It runs for 40 minutes, and after that I understand that I didn't select proper configuration in the combobox. It's annoying! When command line option was -DCMAKE_BUILD_TYPE=Release, but combobox was set to Debug, build fails after spending a decent time.
Is it possible to generate an MSVS project with build configuration selected from command line?
Note that I'm aware of msbuild command and it's -p:Configuration=xxxxx flag. The question is about cases when for some reason you need to build from Visual Studio's GUI.
Changing the selected configuration for the GUI is not possible with CMake at this moment.
The main reason for this is that this information is stored in the .suo file generated by Visual Studio. CMake itself only generates the project and solution files, while the .suo file will be generated by Visual Studio itself.
Alternatively, use CMake's command line build option for this. After configuring your project and generating the VS .sln file from CMake as usual, simply run:
cmake --build <path_to_build_directory> --config Release
This works independently of the selected generator and is the most reliable way of building CMake projects.

CMake + MSVC build tools 2015 - what to do after invoking cmake?

I've never used CMake on Windows, or with MSVC, before; so this is a newbie question.
I've installed CMake and some minimal freely-downloadable "Microsoft Visual C++ build tools 2015" (from here) on a Windows 10 machine. I have my CMake-based project (which builds fine on Linux) checked out, and I'm ready to go.
So, in a shell window, I do:
PS C:\Users\joeuser\the_project> mkdir build
... etc. etc. ...
PS C:\Users\joeuser\the_project> cd build
PS C:\Users\joeuser\the_project\build> cmake ../
-- Building for: Visual Studio 14 2015
-- Selecting Windows SDK version to target Windows 10.0.15063.
-- lots of checks here
-- etc. etc.
and that's done. So far so good. But - what now? On a Unix'ish system, I would execute make, and perhaps make install; and maybe make clean later on. My questions are:
Do the MSVC tools I'm using have an equivalent of make? I've head about nmake and msys but I'm not sure those are relevant here.
What do I do now in order to build, install or clean the build directory?
Is it better/easier/more common practice to use a different CMake generator in my scenario?
Making my previous comments an answer:
You would then call the underlying build tool directly via CMake:
cmake --build . --target ALL_BUILD --config Debug -- /nologo /verbosity:minimal
This gives you an almost quiet build process as you are used to from make.
Why the hell do I have to provide so much arguments to CMake?
Because CMake is a build system generator and directs those arguments to the underlying build tool (make, MSBuild, nmake, ...). The underlying build tool may have different naming conventions for targets etc., e.g. make users provide almost always the targets all, clean, and install. But the Visual Studio solution generated by CMake uses by default ALL_BUILD, INSTALL, RUN_TESTS. There is no CLEAN target. Using MSBuild,
To install your solution you would select --target INSTALL.
For running tests, you would select --target RUN_TESTS.
For cleaning you have to use --target ALL_BUILD --config Debug -- /nologo /verbosity:minimal /t:Clean because the Visual Studio solution does not contain a clean target but MSBuild provides one.
Further important arguments of MSBuild are:
/maxcpucount:<numberOfCpus> (to limit the number of CPUs the build process is using) and
"/l:FileLogger,Microsoft.Build.Engine;logfile=<YOUR_LOGFILE_NAME>" to save MSBuild output to file.

CMake Copying Multiple DLLs Failing

So I have seen the other posts regarding moving external dll files to the current project's .exe output location for use at runtime but I seem to be running into an odd issue that I can't find information on.
I am using the following custom command to copy my libfreenect2 dlls into my output directory for my project:
add_custom_command(TARGET kinect_feeds POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"libfreenect2_output_path/bin/*.dll"
$<TARGET_FILE_DIR:kinect_feeds>)
CMake sets up my project just fine, but when I go to run the command in Visual Studio it errors out when trying to copy the files. I think the issue is with the wildcard character. I used the error output in the Visual Studio to copy the complete command into by git bash window and it works as expected. Also Visual Studio has no problem moving multiple files if they are explicitly defined like so:
add_custom_command(TARGET kinect_feeds POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"libfreenect2_output_path/bin/freenect2.dll"
"libfreenect2_output_path/bin/glfw3.dll"
$<TARGET_FILE_DIR:kinect_feeds>)
My question is, do wildcard characters not work in CMake commands when being executed by Visual Studio or is there something that I am missing? For now I will just type out all of the DLL files explicitly, but I was hoping to avoid this.
I am using the latest version of CMake and Visual Studio 2015 Community Edition.
I'm running into the same issue with CMake 3.6.1 and Visual Studio 2012. I don't think Visual Studio has any impact though, because I get the errors from the command line as well
From a CMD prompt:
> cmake -E copy .\data\*.bin \temp
Error copying file ".\data\*.bin" to "\temp".
This question references a CMake bug report regarding wildcards, that was supposed to be fixed in CMake 3.5, but doesn't appear to work on Windows with CMake 3.6.1.
I think your solution to list each file individually is the current solution.

Resources