CMake + VSCode: configure_file and linting - c++

This may already have been asked and answered, but I couldn't find it if so.
I have VSCode and CMake setup and working fine and I am also using the ms-vscode.cmake-tools extension, and my c_cpp_properties.json has "configurationProvider": "ms-vscode.cmake-tools".
As part of my project CMakeLists.txt file I have:
configure_file(app_version.hpp.in app_version.hpp)
Obviously the actaul app_version.hpp file does not exist until cmake is run on the project and even then the actual file is placed into the build directory. The result of this is that the linter cannot find the file and so lots of red squiggles appear.
Is there a nice way to deal with this to make the linter happy, or do I have to specify a "fake" app_version.hpp with blank #defines etc?

You can tell CMake where to put the result of configure_file(), even back into your source tree. You'll still have to run cmake first. As an example...
configure_file(${CMAKE_SOURCE_DIR}/templates/app_version.hpp.in ${CMAKE_SOURCE_DIR}/include/app_version.hpp)
I can't think of a project that I work on that doesn't write back like this to the source directory, so running cmake at least once after checkout is second nature to me. Remember to set up your version control to ignore the output file, otherwise you get a different kind of "red squiggly line".

Related

How to set up C++ Testmate in VS Code

Ok, n00b question. I have a cpp file. I can build and run it in the terminal. I can build and run it using clang++ in VSCode.
Then I add gtest to it. I can compile in the terminal with g++ -std=c++0x $FILENAME -lgtest -lgtest_main -pthread and then run, and the tests work.
I install the C++ TestMate extension in VSCode. Everything I see on the internet implies it should just work. But my test explorer is empty and I don't see any test indicators in the code window.
I've obviously missed something extremely basic. Please help!
Executables should be placed inside the out or build folder of your workspace. Or one can modify the testMate.cpp.test.executables config.
I'd say, never assume something will "just work".
You'll still have to read the manual and figure out what are the names of config properties. I won't provide exact examples, because even though I've only used this extension for a short time, its name, and therefore full properties path, has already changed, so any example might get obsolete quite fast.
The general idea is: this extension monitors some files/folders, when they change, it assumes those are executables created using either gtest or catch2. The extension tries to run them with standard (for those frameworks) flags to obtain a list of test suites and test cases. If it succeeds, it will parse the output and create a nice list in the side panel. Markers in the code are also dependent on the exactly same parsed output, so if you have one, you have the other as well.
From the above, you need 3 things to make this work:
Provide correct path (or a glob pattern) for finding all test executables (while ignoring all non-test executables) in the extension config. There are different ways to do this, depending on the complexity of your setup, they are all in the documentation though.
Do not modify the output of the test executable. For example, if you happen to print something to stdout/stderr before gtest implementation parses and processes its standard flags, extension will fail to parse the output of ./your_test_binary --gtest-list_tests.
If your test executable needs additional setup to run correctly (env vars, cwd), make sure, that you use the "advanced" configuration for the extension and you configure those properties accordingly.
To troubleshoot #2 and #3 you can turn on debug logging for the extension (again, in the VSCode's config json), this will cause an additional "Output" tab/category to be created, where you can see, which files were considered, which were run, what was the output, and what caused this exact file to be ignored.
This messed with me for a while, I did as Mate059 answered above and it didn't work.
Later on I found out that the reason it didn't work was because I was using a Linux terminal inside windows (enabled from the features section) and I previously had installed the G++ compiler using the linux terminal so the compiler was turning my code into a .out file, for some reason TestMate could not read .out files.
Once I compiled the C++ source file using the powershell terminal it created a .exe file which I then changed the path in the setting.json as Mate059 said and it showed up.
TL;DR
Mate059 gave a great answer, go into settings.json inside your .vscode folder and modify "testMate.cpp.test.executables": "filename.exe".
For me it also worked using the wildcard * instead of filename.exe but I do not suggest to do that as in that might mess up something with the .exe from the main cpp file and what not.

Why can't Code Blocks find header, even though it's there?

I have the following project layout in Code::Blocks 13.12. I'm running as root.
Notice the file dtconfig.h is in the Headers folder.
The file is located in the same directory as the main.cpp file:
However, when I go to build I get the following error:
When I wrap the include in quotes, such as:
#include "dtconfig.h"
It works, but then I have to modify all the other headers to do the same thing. These headers are not something I have written and are part of a source project. So I don't want to go messing around with these files if I don't have to.
Is there anything I need to do/configure in the program to get this to work?
Also, I am running Ubuntu 16.04.1 LTS Mate.
You're not meant to use angle brackets (<dtconfig.h>) for your own project's code, but if you need to make them work without changing every file, then you can pass an option to the compiler telling it to use your dtSearch directory as an include directory.
I don't know whether C::B supports include directories in the GUI, but you can always fall back to passing -Ipath/to/dtSearch to GCC and Clang directly, or /I for MSVC. You can do this where C::B lets you specify additional command line options for the compiler.

Setting up ROS package in CLion

I am using CLion (C++ IDE) for editing a ROS package. I was able to open a package by opening the CMakeLists.txt file. But, I get an error,
"FATAL_ERROR "find_package(catkin) failed. catkin was neither found in the workspace nor in the CMAKE_PREFIX_PATH. One reason may be that
no ROS setup.sh was sourced before"
How do I solve this problem? Will I be able to make the project in CLion (If so, how do I) after I make changes to the code or do I have to catkin_make in a separate terminal?
Try this (for Linux):
Open a command line
Run catkin_make on your package.
source your catkin_workspace/devel/setup.bash file e.g. source ~/my_dev_folder/catkin_ws/devel/setup.bash
Start CLion from [CLion install dir]/bin/clion.sh e.g. cd ~/Downloads/clion-1.2.4/bin && ./clion.sh
CLion should then start with knowledge about the packages in your catkin workspace, through the local environment variables set up by the setup.bash file.
To add on to what WillC suggested, you can also modify the desktop entry to start the application from bash instead of manually doing so.
To do this, edit the desktop file located at
~/.local/share/applications/jetbrains-clion.desktop
by modifying the line containing Exec= to
Exec=bash -i -c "/INSTALL_LOCATION/clion-2016.3.2/bin/clion.sh" %f
To add on to what WillC suggested,CLion reload the last cmake compiling result by default.
However, if you failed to find catkin.cmake during the last attempt even though you source the devel/setup.bash and open CLion, you also cannot find catkin.cmake.
You should click File --> Reload Cmake Project and you should get the right result.

SCons not finding "stdafx.hpp" when using nested directories

I have a C++ project, and I am transitioning from Visual Studio Solutions to SCons for builds, so Linux users can also build my code. This is my first foray into SCons, and it's working very well with simple projects. But, for this project, I have a nested directory structure:
main/
sub1/*.cpp
sub2/*.cpp
sub3/*.cpp
file1.cpp
file2.cpp
And I have the following SConstruct file:
env = Environment()
env['PCHSTOP'] = 'stdafx.hpp'
env['PCH'] = env.PCH('stdafx.cpp')[0]
env.Program('program', [
'file1.cpp',
'file2.cpp',
'sub1/file1.cpp',
'sub2/file1.cpp',
'sub3/file1.cpp'
])
Running scons from the command line causes the following error:
fatal error C1083: Cannot open include file: 'stdafx.hpp': No such file or directory
Obviously, this is an MSVC error. But this should be solvable with Scons, I'm just not sure how..
I Noticed that Visual Studio will copy all the *.obj files to a build directory before linking by default. I think this may be part of the solution, but again, I'm unsure.
What I AM sure of, is this is not the first time someone has come across this problem, but Google didn't turn up anything for me.
PS: Unlike in the example, none of the files have naming conflicts, and could theoretically be moved to a flattened folder structure by SCons without issue.
This looks like you'll have to specify the proper include paths in your Environment via the "CPPPATH" variable...but it's difficult to tell without seeing the full command line. Remember, that all SCons envs are clean initially. So, if you're in the wrong working directory, a simple "#include " doesn't find the header if it's in a different folder.
Have a look at SCons' UserGuide, chap. 14 "Hierarchical Builds", which might give you a few more ideas and insights, or come over to the User mailing list at scons-users#scons.org.

Shortcut to intel compiler directory to use in makefile

I compiled my program with intel C++ compiler for windows (from Intel Composer 2011), and got an error message that libmmdd.lib cannot be found. I googled this problem, and some people said that I have to reinstall my compiler, and I did; however, that didn't resolve the problem, so I started looking in the intel compiler directory, and found that this file (and other required libraries as well) are located at
%CompilerDirectory%\compiler\lib\ia32
It doesn't make sense to write in the make file the whole absolute path of the libraries, so I started searching, and I could only find that %mklroot% points to the math kernel directory. And even with a -L%mklroot%/../compiler/lib/ia32 approach for linking I couldn't link to the libraries correctly, so eventually I did a lame move to solve the problem, which is, I copied every file the linker asks for to the source directory, and so was the problem temporarily solved.
Since this way of solving the problem isn't the best one, I wonder if there's a way to link to those libraries without having to copy the files. It's strange because the compiler should find its own libraries alone, but... I don't know...!
Any ideas? is there something like, %compilerroot%, that points to the compiler directory and that I could put in my makefile (or actually my qmake, since I'm using Qt).
Thanks for any efforts :-)
Instead of using %mklroot% try $$(mklroot) or $(mklroot).
You can find the explanation here:
Variables can be used to store the contents of environment variables.
These can be evaluated at the time that qmake is run, or included in
the generated Makefile for evaluation when the project is built.
To obtain the contents of an environment value when qmakeis run, use
the $$(...) operator:
DESTDIR = $$(PWD)
message(The project will be installed in $$DESTDIR)
In the above assignment, the value of the PWD environment variable is
read when the project file is processed.
To obtain the contents of an environment value at the time when the
generated Makefile is processed, use the $(...) operator:
DESTDIR = $$(PWD)
message(The project will be installed in $$DESTDIR)
DESTDIR = $(PWD)
message(The project will be installed in the value of PWD)
message(when the Makefile is processed.)
In the above assignment, the value of PWD is read immediately when the
project file is processed, but $(PWD) is assigned to DESTDIR in the
generated Makefile. This makes the build process more flexible as long
as the environment variable is set correctly when the Makefile is
processed.
EDIT:
It is strange that neither $$(mklroot) nor $(mklroot) gave you the result you would expect. I did a simple test to verify what I wrote above:
Opened a Command Prompt
Created a new environment variable 'mklroot' with a test value: set mklroot=C:\intel_libs
Verified the result of the previos step: echo %mklroot%. I got C:\intel_libs
Placed your 3 qmake functions at the end of my .pro file:
warning($(%MKLROOT%))
warning($(MKLROOT))
warning($$(MKLROOT))
Ran qmake: qmake. The result:
Project WARNING:
Project WARNING: c:\intel_libs
Project WARNING: c:\intel_libs
As you can see the 2nd and the 3rd warning() displayed the string I set to the environment variable.