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.
Related
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.
Apologies because I'm pretty new and inexperienced at this but I'm trying to compile OpenExr-2.3.0 (downloaded from http://www.openexr.com/downloads.html and extracted to a 'exr_2_3_0' directory) on Windows with cmake and Visual Studio 15. I'm just going to outline the basic questions I have before going into detail:
Should the ilmbase build do more than just create some header files in the relevant include directory? (I know the 2.2.0 build did and I've a feeling this is what's missing).
I'm confused as to how to tell the openexr build where these header files are. It never seems to be able to find them so I'm pretty sure I'm either building them to the wrong place or missing a step.
The README file suggests the following:
Launch a command window, navigate to the IlmBase folder with CMakeLists.txt,and type command: setlocal del /f CMakeCache.txt cmake
-DCMAKE_INSTALL_PREFIX= -G "Visual Studio 10 Win64" ..\ilmbase
Navigate to IlmBase folder in Windows Explorer, open ILMBase.sln and build the solution. When it build successfully, right click
INSTALL project and build. It will install the output to the path you
set up at the previous step.
Go to http://www.zlib.net and download zlib
Launch a command window, navigate to the OpenEXR folder with CMakeLists.txt, and type command: setlocal del /f CMakeCache.txt cmake
-DZLIB_ROOT= -DILMBASE_PACKAGE_PREFIX= -DCMAKE_INSTALL_PREFIX= -G "Visual Studio 10 Win64" ^ ..\openexr
Navigate to OpenEXR folder in Windows Explorer, open OpenEXR.sln and build the solution. When it build successfully, right click
INSTALL project and build. It will install the output to the path you
set up at the previous step.
So I create a deploy folder inside the source directory and from the source directory I run:
cd ilmbase-2.3.0
setlocal
del /f CMakeCache.txt
cmake -DCMAKE_INSTALL_PREFIX="../deploy" -G "Visual Studio 15 Win64" ../ilmbase-2.3.0
This builds a sln file in the ilmbase folder, which builds with no errors but the install project inside that solution only creates a bunch of header files inside the 'source/deploy/include/OpenEXR' folder. Again, is this all it's supposed to do or is there supposed to be a lib directory with dll files etc built as a result at this stage?
I've successfully built zlib with no errors but when I try point 4 I run into errors of:
CMake Error at IlmImfExamples/CMakeLists.txt:3 (ADD_EXECUTABLE) Target
"IlmImfExamples" links to target "IlmBase::IlmThread" but the target
was not found. Perhaps a find_package() call is missing for an
IMPORTED target or an ALIAS is missing?
I'm guessing I should be adding a path from cmake to the new files? Even if I open the openexr.sln that is generated and try to build, IlmImfExamples fails to build. If I manually add the header files that it complains about it still won't build, complaining that it can't find OpenEXR::IlmImf.lib It's right that this hasn't been built but I've no idea why, or at least I can't find it if it has.
I did see this thread on github:
https://github.com/openexr/openexr/issues/355
that says there are errors in the CMakeLists.txt which I have also changed. But I'm rapidly hitting a brick wall of knowledge at this stage so any help is greatly appreciated.
Thanks,
Paddy
I tried to define where to put the .exe generated by cmake + visual studio.
I put this in the cmakefiles.txt
IF(CMAKE_SYSTEM_NAME STREQUAL Windows)
INSTALL(TARGETS
mialsrtkRefineHRMaskByIntersection
DESTINATION ${CMAKE_INSTALL_PREFIX})
ENDIF(CMAKE_SYSTEM_NAME STREQUAL Windows)
but at the end all exe are in the folder of the vcxproj in a subfolder Debut.
is that normal ?
How can I specify the output directory ?
on linux I put destination bin and it works.
What you're setting is the installation destination directory. In Visual Studio, installation is performed by building the special target INSTALL. That is equivalent to make install in Make world.
Note that you can also specify the build output directory. The ways to do that are :
Variable CMAKE_RUNTIME_OUTPUT_DIRECTORY, which provides global settings.
Target property RUNTIME_OUTPUT_DIRECTORY, which controls settings for a particular target.
Both of these have per-configuration variants, or sister variables/properties which affect other things than executables (e.g. CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG). Please see the CMake docs for details.
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.
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.