I use C-SPY macros for automated testing. For this purpose I load a startup macro file and it loads additional macro files using the following code:
execUserSetup()
{
__registerMacroFile("$_ENVVAR_$\\macros-1.mac");
__registerMacroFile("$_ENVVAR_$\\macros-2.mac");
...
}
This works like a charm when I run the startup macro from within the IAR Embedded Workbench.
But what I really want to do is running the tests with CSpyBat.exe. There I specify my startup.mac using the option --macro startup.mac.
The files macros-1.mac and so on won't be found then. Instead I get error messages for the macro files (with garbage file names, see below):
ERROR: Could not open macro file: #۸0ٸ`ٸ#2#u
If I use the pathnames without the environment variables, everything is okay.
What am I doing wrong?
The answer is: The workbench supports expanding environment or project variables, but CSpyBat doesn't. So told me IAR support. Also they gave me the following pointer:
See 'C-SPY Debugging Guide' - "Using C-SPY in batch mode", "INVOCATION SYNTAX", page 492:
Note: In those cases where a filename is required—including the DLL files—you are
recommended to give a full path to the filename.
Related
I am wanting to measure the time it takes for my C++ video processing program to process a video. I am using CLion to write the program and have Cmake set up to compile and automatically run the program with a test video. However, in order to find execution time I have been using the following command in the MacOS terminal:
% time ./main ../Media/test_video.mp4
Is there a way for me to configure Cmake to automatically include time in the execution of ./main to streamline my process further?
So far I've tried using set(CMAKE_ARGS time "test_video.mp4") and some command line argument functions but they don't seem to be acting in the way that I'm looking for.
It is possible to use add_custom_target to do what you want. I'll not consider this option further as it seems abusing the build system for something it wasn't designed to do. Yet it may have an advantage over using CLion configuration: it would be available to be used outside of CLion. That advantage seems minor: why not run the desired command directly in those contexts?
The first CLion method would be to define an external tool which run time on the current build target. In File|Settings...|Tools|External Tools define a new tool with /bin/time as program, $CMakeCurrentProductFile$ $Prompt$ as arguments. When choosing that tools (in Tools|External Tools) it will now prompt you for the argument and then run /bin/time on the current target with the provided arguments. Advantage: you don't have to define the tool once, it will be available in every project. Inconvenients: the external tools are available in every project, thus it doesn't make sense to be more specific than $Prompt$ for the arguments and the working directory; it isn't possible to specify environment variables, it isn't possible to enforce the need of a build before running the command.
The second CLion method would to be define a Run/Debug Configuration. Again use /bin/time as program (chose "Custom Executable"), specify $CMakeCurrentProductFile$ as first argument (here it makes sense to provide the other arguments as desired, but note that $Prompt$ is still a valid choice if needed). Advantages: it makes sense to be as specific as needed; you have all the feature of configurations (environment variables, input redirections, specifying actions to be executed before the execution). Inconvenient: it doesn't work with other CLion features which assume that the program is the target such as the debugger, the profiler, ... so you may have to duplicate configurations to get them.
Note that the methods aren't exclusive: you can define an external tools and then add configurations for the case where it is more convenient.
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.
We are using an environment variable to specify a path to a library we use. Most of the time it points to the released version but sometimes to a development version.
Anyway, it works ok when I use $(MyLib)/path;%(AdditionalIncludeDirectories) for building the C++ application but I can not open the project resources. However, when I use %(MyLib)/path;%(AdditionalIncludeDirectories) it works.
Now, what is the difference?
I thought the correct way is to use $(EnvVar) but for the resource editor it doesn't seems to work. And if $(EnvVar) is the correct way then why does Visual Studio use %(AdditionalIncludeDirectories) and not $(AdditionalIncludeDirectories)
The error I get is: fatal error RC1015: cannot open include file 'afxres.h'.
You use %(item) to refer to an MSBuild metadata item. Using $(AdditionalIncludeDirectories) would not work well if you also had an environment variable by that name. So %(MyLib)/path ought to resolve to just /path.
You can put echo %(MyLib)/path in a prebuild event to verify this.
Which is probably enough to stop confusing rc.exe, the resource compiler. Which is a stone-cold-old SDK utility, going back all the way to Windows version 1.0. It is pretty temperamental, very picky about command line options and .rc script file text encoding. Do keep in mind that it dates from an era long before Windows started to support a forward slash as a path separator, everybody had to use a backslash back in 1986.
So use "$(MyLib)\path" instead, including the double quotes so you don't confuzzle it when MyLib contains embedded spaces. And do favor using a project property sheet instead so there are some odds that somebody can still figure out how to get the project built correctly 2+ years from now.
As part of a build process, I need to take an environment variable defined by a batch script and use it as a constant within the code at compile time.
For example, say I have defined an environment variable named BUILD_VERSION and set it to 1.0.0, when compiled I want 1.0.0 to be baked into my code. EG:
Batch file:
set BUILD_VERSION = 1.0.0
; call vs compiler
C++ File:
const std::string build_version = BUILD_VERSION // Which will result in "1.0.0".
How would I go about doing this?
In the end I followed txchelp advice and added a /D flag into the Command Line -> Additional Options section of the project properties to declare the environment variable as a preprocessor definition.
It looked something like this:
Then in the batch script that started the build:
set SVN_BUILD_VERSION=1.0.0
And finally to extract it as a string within the source code:
#define STRINGIZER(arg) #arg
#define STR_VALUE(arg) STRINGIZER(arg)
#define BUILD_VERSION_STRING STR_VALUE(BUILD_VERSION)
// ...
const std::string version = BUILD_VERSION_STRING; // Results in "1.0.0".
You can use a prebuild step (I suppose you are on Visual Studio) which will run script which will get this environment variable value, parse C++ source file and change the value
"1.0.0.0" to "1.0.0.1".
Such substitution can be conveniently done by awk.
A VERSION_INFO resource could be a good way go.
The version info so embedded can be inspected by right-clicking the executable and checking its properties.
To do that at the command line:
Redirect output from a batch file to an [.rc] file defining the resource.
Compile the resource using rc.exe.
Embed the resulting .res file by simply passing it to the linker.
Within Visual Studio it might be more complicated.
I have some C++ code base, documented with doxygen, and build with GNU make.
Version information is centralized in makefile, where I have something like:
VERSION=1.2.3.4
In my makefile, the CFLAGS add the following define:
CFLAGS += -DAPP_VERSION=$(VERSION)
This enables me to get the version in code, like this:
#define STR_EXPAND(tok) #tok
#define STR(tok) STR_EXPAND(tok)
int main()
{
cout << "software version is << STR(APP_VERSION) << endl;
}
Now, what I would like is to have this in the doxygen-produced html files:
Current version of software is 1.2.3.4
I managed to export the makefile variable into the doxygen configuration file with:
(edit: doxygen is called from makefile, through a 'make-doc' target)
PREDEFINED = APP_VERSION=$(VERSION)
But then, if I try in the doxygen \mainpage command something like this, it fails, because (of course), macro names don't get expanded in comments...
/**
\mainpage this is the doc
Current version is $(APP_VERSION) -- or -- ... is APP_VERSION
*/
Questions
Do you know of a way to "expand" that macro in the doxygen comments ? This could be done by some sed processing on the file holding the comment in the makefile, but maybe this can be solved directly with doxygen ?
How do other projects handle versioning (besides automatic versioning tool that VCS provide, I mean), in a way that the version id is uniquely defined in a file, so it can be fetched both by software build system and documentation build system.
Related: How to display a defined value
Macros in comments are not generally expanded (see, for example, this answer). This is not unique to doxygen and I can 't think of a way to do this using the PREDEFINED configuration option.
As you state in the question, you can use sed, see the third bullet point in this answer. For example, using the following
INPUT_FILTER = "sed -e 's/VERSION/1.0/'"
will replace all instances of VERSION with 1.0 in all your source files (you can specify which files to process with INPUT_FILTER, rather than processing all source files). You might not want VERSION to be expanded everywhere, so perhaps it is best to use something like $(VERSION) and sed this token. Also, you will need a way of getting your version number from your makefile and into your doxygen configuration file. This can be done with another sed.
To address your last bullet point, doxygen has the FILE_VERSION_FILTER configuration option for determining the version number of each file. Using this will print some version information (whatever is printed to standard out from the command specified in FILE_VERSION_FILTER) at the top of each file page. In the documentation there are examples of getting the version number using a number of different version control systems. Also, here is a page describing how to use git and doxygen to extract version information.
The only drawback with this configuration option is that I don't know how to specify where the file version information should appear in the final documentation. I presume you can use a layout file: I presume you can change the layout of pages, but I have never done this and don't know how easy it would be to use this to include version information on the mainpage.
You need to use the "export" functionality of make ie a very simple make file with
project_name=FooBar
export project_name
all:
doxygen Doxyfile
Will allow you to use the following comments in C++
/*! \mainpage Project $(project_name) Lorem ipsum dolor
I can see this becoming a PITA with a large set of exports but it's a fairly simple way to do it. Alternatively you could run doxygen from a separate BASH script with all the exports in it to avoid polluting your Makefile too much.
the commands manual suggests that $(VARIABLE) expands environment variables. So maybe you can put your version in an environment variable?