I am configuring CMake build project on Windows for MSVC++ project.It build ok the executable,then installs it into a defined directory.In my cases that's:
${CMAKE_SOURCE_DIR}/x64/${CMAKE_BUILD_TYPE}/
The executable has got a folder in the same directory with files which it loads upon the launch.If I launch the .exe manually it opens up and runs ok.But I want to do it via ctest.
I defined ctest like this:
add_test(ENGINE_TEST1 ${CMAKE_SOURCE_DIR}/x64/${CMAKE_BUILD_TYPE}/MyApp.exe
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/x64/${CMAKE_BUILD_TYPE})
When I call from the cmd:
ctest
The executable is starting up but crashes immediately with the error:
Debug Error!
Program:../..../.../MyApp.exe
R6010 -abort() has
been called.
Indeed,when checking the CMake's Last Test.log file it shows that it runs the test not in "WORKING_DIRECTORY but in the directory where the MyApp.exe has been built by CMake.How do I change that?
As I am not CMake pro I am sure the following answer is not the optimal way to do it,but at least it works for me.
Again,I was trying to run ctest on an executable from within the directory into which cmake had installed it.The exe on the startup was trying to load dependent files which were in the same directory.But it was crashing because it couldn't fin the files.
It appears that the cmake default workspace directory is the directory where the cmake files and projects are generated.That's 'build' directory.So when the executable is launched via ctest it search the paths of the files to load relative to the build directory.
Now,CMAKE has 2 variations of add_test() method.One is simple with arguments:
add_test([test_name] [test exe path])
It doesn't take care of the working directory.
And another one which is explained here does include an argument for explicit setup of the working directory.
Frankly speaking,I wasn't able to get this advanced function working as it was demanding to supply some test .config which I didn't understand how to setup.So what I did,I used the simple add_test function.
And then I set the working directory to the location of my executable using this:
set_tests_properties(mytest PROPERTIES WORKING_DIRECTORY "${TEST_WOKRING_DIR}")
And it fixed the problem.
Related
I am downloading this code from GitHub (subdivision-regression), and am getting stuck following the instructions:
To build doosabin_regression:
Run CMake with an out of source build.
Set COMMON_CPP_INCLUDE_DIR to the full path to rstebbing/common/cpp.
Set DOOSABIN_INCLUDE_DIR to the full path to rstebbing/subdivision/cpp/doosabin/include.
Set Ceres_DIR to the directory containing CeresConfig.cmake.
Set GFLAGS_INCLUDE_DIR, GFLAGS_LIBRARY and RAPID_JSON_INCLUDE_DIR. (Add -std=c++11 to CMAKE_CXX_FLAGS if compiling with gcc.)
Configure.
Build.
I have edited the CMakeLists.txt file to put the correct paths in. I then created a new directory called subdivision-regression-bin and ran:
cmake ../subdivision-regression/src
It completes this and displays:
-- Configuring done
-- Generating done
-- Build files have been written to: /home/hert5584/RStebbing/subdivision-regression-bin
However, when I try and run the example code, it cannot find the files listed in CMakeLists.txt (I know they are the right paths as otherwise CMake does not run).
I have tried running:
sudo make install
But get the following error:
make: *** No rule to make target 'install'. Stop.
Any ideas why this isn't working? Have the above steps Configured and Built the files?
The ordered CMake idiom to understand is:
The Configure step
The Generate step (This is often subsumed in the Configure step, and not mentioned explicitly, as in this case.)
The Build step (in which you actually compile/link your code into libraries/executables)
Take a look at this resource for information about the configure and generate stages.
You didn't appear to perform the steps to set CMake cache variables. For these you have to use CMake command line options (-D specifically). So run CMake as something like this instead to set all six variables:
cmake -DCOMMON_CPP_INCLUDE_DIR=/rstebbing/common/cp -DDOOSABIN_INCLUDE_DIR=...[More CMake Cache variables]... ../subdivision-regression/src
For building, try just running make without sudo or install:
make
I have built a flatpak package out of my application. However, flatpak-builder in the end complains:
Error: Command 'executable' not found
Where executable is the name of my program, which I have specified in my manifest as "command": "executable".
When I check in the build folder, my executable is in build-folder/files/executable. (files is auto-generated and seems to be the base installation directory, all the libraries get put in the lib folder below there).
When I change the command to e.g. /executable, the package gets created.
When test-running the application, I have to specify the full path to the executable for it to run:
flatpak-builder --run bin org.myorg.executable.json build-folder/files/executable
(when I just specify executable here instead of build-folder/files/executable, it tells me bwrap: execvp executable: No such file or directory).
However, when I install the flatpak via a local repo , flatpak run org.myorg.executable shows
bwrap: execvp /executable: No such file or directory
(where executable is the name of my executable). Of course, I suppose it should just be executable instead of /executable, but flatpak-builder won't create a package with that value!
So, what am I doing wrong here, how can I create a working package with flatpak-builder?
My mistake - my executable should have gone into the bin folder, now it works...
This question already has answers here:
How to always run command when building regardless of any dependency?
(4 answers)
Closed 4 years ago.
I am trying to copy a directory of files after my project is built, every time my project is built.
In my project's CMakeLists.txt file I have the following:
# Copy resources
file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/assets DESTINATION ${PROJECT_BUILD_DIR}/)
This works the first time the project is built, and it works anytime I call make in the directory that CMAKE has generated the makefile in.
However, in my IDE (CLion) I think there is some sort of caching / checking to see if the project is already built.
As a result, if I only change an asset file, and not the underlying code, the files are never copied to the location of the binary.
Is there a way to force a post-build script to be executed after every time build is called?
Or, put another way, is there a way to force the CMakeLists.txt file to be every time I build my project?
This is specific to CLion but concerns cmake more generally.
I am using CMAKE 3.9.1
Thanks
File(COPY file path) is executed at configure time, one of the three main phase of CMake flow Configure -> build -> install
If you want to execute a command after a build there is two ways to do it.
First with (Probably the better one)
add_custom_command(TARGET MyTarget POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets $<TARGET_FILE_DIR:MyTarget>/assets)
Will copy the asset directory, to artifactDirectory/assets.
You need to precise the assets directory in the destination.
CMake documentation isn't that clear on this point
copy_directory ...
Copy directories to directory. If directory does not exist it will be created.
Reference is there : add_custom_command (3.9.6)
Second with a custom target that execute at the end of the build of every targets and so depends on all targets.
Syntax would be
add_custom_target( MyTarget ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/assets $<TARGET_FILE_DIR:MyTarget>/assets DEPENDS MyOtherTargets)`
Will create a target called MyTarget that execute, a command when builded after target or files it depends on are builded/generated.
(This command have some unexpected behaviours when a project is built, with multiple cores.)
Reference is there : add_custom_target (3.9.6)
For information my environment is CLION 2017.3 and CMake 3.10
My configuration has CMake 3.6, Visual Studio 2015 and latest Google test from GitHub. I add my unit tests through one of my cmake functions addGtest and do the build. After this I can run the test from my RUN_TESTS target or using ctrl + F5 in VS and works as expected.
The final goal is to run the unit tests at build time using the CMake dependency management. For now, as a first step, I have enhanced my function to create a custom_target (included the entire function, in case there are unforeseen issues in the working part), but not build it:
function (addGtest)
# vvvv this part works as explained vvvv #
set (optBOOLS)
set (optSINGLES EXE)
set (optLISTS DLL_LIST)
cmake_parse_arguments (myARGS
"${optBOOLS}" "${optSINGLES}" "${optLISTS}" ${ARGN})
# addExecutable is a function that adds target executables
set(myARGS_DLL_LIST gtest_main gtest "${myARGS_DLL_LIST}")
addExecutable (EXE ${myARGS_EXE} DLL_LIST ${myARGS_DLL_LIST} ${myARGS_UNPARSED_ARGUMENTS})
add_test (NAME ${myARGS_EXE} COMMAND ${myARGS_EXE} WORKING_DIRECTORY
${CMAKE_INSTALL_PREFIX}/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>/bin
) # so it can be run using ctest
# ^^^^ this part works as explained ^^^^ #
add_custom_target (${myARGS_EXE}.tgt DEPENDS ${myARGS_EXE}
COMMAND ${myARGS_EXE} --gtest_output="xml:${myARGS_EXE}.xml"
WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/$<$<CONFIG:Release>:Release>$<$<CONFIG:Debug>:Debug>/bin
)
endfunction (addGtest)
As expected when I perform the build, a new target, say, utMyTest.tgt is added to VS, but it is not built. Now when I build this new target by hand in VS, I expect that the test will be run. But it doesn't and gives the following error:
1> The filename, directory name, or volume label syntax is incorrect.
I tried providing full path to the COMMAND option, removing double quotes around --gtest_output value, but to no avail. On the other hand when I cd to the working directory in a command line window and invoke the exe, it works fine!!
The first question is how do I fix it to run the test by building this new target? After that, I plan to add_custom_target (${myARGS_EXE}.run) and add_dependencies (${myARGS_EXE}.run ${myARGS_EXE}.tgt). Would this then run the test whenever the exe changes? Or should I do something else? Thank you for your help.
Could not add so much details in the comment, hence this answer.
1. Answer to the original problem
Since I needed the configuration dependent path in the WORKING_DIRECTORY option of the add_custom_target command, but cannot pass generator expressions to it, the idea is to use the CMAKE_CFG_INTDIR variable so:
add_custom_target (${myARGS_EXE}.tgt
DEPENDS ${myARGS_EXE}
COMMAND ${myARGS_EXE} --gtest_output=xml:${myARGS_EXE}.xml
WORKING_DIRECTORY ${CMAKE_INSTALL_PREFIX}/${CMAKE_CFG_INTDIR}/bin
)
Now, when you build the above target, the unit test is run in the WORKING_DIRECTORY which is not entirely desirable, since that is the install directory for libs and exes. It would be really nice to ...
2. Run the unit test from its build directory
While, at the same time, picking up the DLL paths from within Visual Studio, and storing the Gtest generated .xml file in the build directory. This is the solution:
In CMake version 3.10 CMAKE_MSVCIDE_RUN_PATH property was added. In the project wide CMakeLists.txt, set(CMAKE_MSVCIDE_RUN_PATH ${CMAKE_INSTALL_PREFIX}/${CMAKE_CFG_INTDIR}/bin) - thanks to this solution #3, we can appendPATH to point to our install directory. And then replace the above add_custom_target command with this:
add_custom_command (
TARGET ${myARGS_EXE} POST_BUILD
COMMAND ${myARGS_EXE} --gtest_output=xml:${myARGS_EXE}.xml
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}
)
This solution avoids the mess of creating additional targets. Clearly only when myARGS_EXE is built, the unit test is run. Obviously myARGS_EXE's transitive dependency on other DLLs is covered also.
If you have other elegant solutions, please post.
I am working on a c++ project and I am using cmake as the build system, so my workflow here is make changes to code. then,
rm -r build
mkdir build
cd build
cmake -G "Unix Makefiles" ..
make
Now I added glew as a dependency to the project, so whenever I try to run make I get an error saying SDL.h not found(this was working before).After sometime I decided to check CMakeCache.txt.opened it using vim then :wq that's all I did now if I run make, my project is building successfully, I am not sure why this is happening, Can anyone tell me why?
ps: added gif of this event, check it out to get a clear picture
(the code i am working on is linked as well, this exact issue is in this commit "dd4452b45c733e0612bc5f3c632e9d1a08be8072")
link to gif
link to code
variables in cmake are limited to the scope of the directory they are in plus their subdirectories.
This, calling find_module() in the gamelib subdirectory does not find that module for use in the main directory.
The preferred way to propagate include directory dependencies is to add them to the target (in the gamelib directory), like this:
target_include_directories(gamelib BEFORE PRIVATE
$<BUILD_INTERFACE:${SDL2_INCLUDE_DIR}>
$<BUILD_INTERFACE:${GLEW_INCLUDE_DIR}>
)
target_include_directories(gamelib SYSTEM BEFORE PUBLIC
$<BUILD_INTERFACE:${SDL2_INCLUDE_DIR}>
$<BUILD_INTERFACE:${GLEW_INCLUDE_DIR}>
)
then you don't need to even mention them in any executable that uses gamelib.