How to print WORKING_DIRECTORY in CMake? - visual-studio

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.

Related

CTest can't find executables under Visual Studio on Windows

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.

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.

Copying executable using CMake add_custom_command in visual studio

Some context: I'm compiling a legacy CMake project using Visual Studio 2019 on a Windows 10 host, but targeting a remote aarch64 Ubuntu16.04 machine. To do so, I added a debug configuration for "Linux-Debug" to point at the machine's IP address (this part works, as I can build, and debug with breakpoints).
The Problem:
I have the following add_custom_command inside my CMakeLists.txt
# Create the executable
add_executable( imageCaptureAEv1 ${SOURCES})
#copy it to the home directory
add_custom_command(TARGET imageCaptureAEv1 POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:imageCaptureAEv1> /home/nvidia)
Where /home/nvidia is the directory I want to copy the executable to after I build it (POST_BUILD), and imageCaptureAEv1 is the name of the executable.
I believe this copy never happens, as the file never shows up in /home/nvidia when I ssh into the Ubuntu machine. All I want to do is copy the executable to an easier to find directory (visual studio prepends the build directory with a crazy long hash that I could get rid of, but I'd rather keep the build directory separate from where I'm copying it).
Is there an easier way? Or, am I missing something with my command?
The above cmake code DOES copy the executable, I just need to make sure a run a rebuild or clean then build in my particular environment, otherwise the executable doesn't get overwritten.

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.

How to add CMake INSTALL project automatically to build configurations

I'm trying to deploy a couple of .ini files to the binary directory when compiling, using CMake. I did this through the following lines (typed by hand; feel free to edit if you find a typo)
FILE(GLOB INI_FILES "${CMAKE_CURRENT_SOURCE_DIR}/../misc/*.ini")
INSTALL(FILES ${INI_FILES} CONFIGURATIONS Debug DESTINATION ${CMAKE_BINARY_DIR}/bin/Debug)
INSTALL(FILES ${INI_FILES} CONFIGURATIONS Release DESTINATION ${CMAKE_BINARY_DIR}/bin/Release)
This properly generates an INSTALL project in my Visual Studio solution which works if 'compiled' manually. However, the project is not part of the Debug and Release build configurations of the Solution, meaning it won't be executed when compiling the solution. Is there a way to add the project manually to the build configurations in CMake?
Or is this not intended and I need to call CMake differently?
I'm Using CMake 3.0.2 with Visual Studio 2013.
I'm generating my Visual Studio solution like this:
"%VS120COMNTOOLS%..\..\VC\vcvarsall" amd64
cmake .. -G "Visual Studio 12 2013 Win64"
Yes, you can add a custom command to copy the .ini files before you build the project. Assuming your build target is named my_target, you can do something like this:
FILE(GLOB INI_FILES "${CMAKE_CURRENT_SOURCE_DIR}/../misc/*.ini")
add_executable(my_target test.cpp)
foreach(FN ${INI_FILES})
add_custom_command(TARGET my_target
PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E copy "${FN}" "${CMAKE_CURRENT_BINARY_DIR}")
endforeach()
It basically uses cmake to copy the .ini files individually over to the build directory.

Resources