Eclipse CDT: Define quoted string as preprocessor define - c++

I have an eclipse CDT C++ project that has a bunch of unit tests. The tests need access to data that I put in a data directory in the same directory. I wanted to use a preprocessor define -Dtest_data_dir="<path/to/data/dir>" to specify the data directory to use.
It looks like this won't work due to this bug in eclipse. Given that, what is the best way to accomplish this? I could hard code the path to the data directory but then I'll have problems with out of source builds not finding the directory.

The linked bug report in question provides the answer. Since I just encountered the issue myself and Google brought me here first...
The answer is to escape your double-quoted string in single quotes. ie:
-Dtest_data_dir='"<path/to/data/dir>"'

Related

cmake project include dirs detection in vim editor [duplicate]

I have a cmake project. I want to do the following easily
search the declaration, definition and references of any variable, function, etc. under the cursor, which may be declared in an external header file whose path is added using INCLUDE_DIRECTORIES in CMakeLists.txt
rename a variable, function, etc. that is declared in the project
How can I set this up?
You can try to use vim plugin cmake4vim in order to integrate CMake to Vim.
This plugin helps to work with cmake targets and allows to generate compilation database file (compile_commands.json). A lot of plugins use this file for code completion, jump to definition and etc. (for example YCM)
Also you can use vim lsp plugins (for example vim-lsp) these plugins use language servers for code completion, refactoring and another good features.
But CMake project integration (cmake cache generation, project compilation, etc.) and search the declaration, definition and etc are different tasks. And different plugins and tools solve these tasks.
You can tell Vim where to look for includes by adding entries to the path option. I don't have enough experience with Cmake to know how to pull paths from CMakeLists.txt, though.
See :help 'path'.
Assuming a properly set path, it is possible to use the built-in :dsearch and related commands to search for definitions across includes.
The define option has a prescriptive name but it could be used to find any specific pattern so you could alter it to match declarations, too, or really anything.
See :help include-search and :help 'define'.
Vim has no built-in concept of "reference". :isearch and friends should work for that but they will probably be too noisy.
Renaming is usually done with something like:
:grep foo paths
:cwindow
:cdo s/foo/bar/gc
YouCompleteMe will help you. It uses compilation_database.json, witch can be generated by cmake.
This plugin also provides autocompetion for many languages.
I use functions in vim and assign them to a hotkey.
https://developer.ibm.com/tutorials/l-vim-script-2/
it gives you more an IDE feel. but at the end of the day you get a bit more control.

Good Practice: How to define path to external libraries for compilation

I am fairly unused to compilation and building projects so pardon me if my approach to compilation and build seems a bit odd. Any tip is welcome.
I am currently working on a 3D geometry C++ project (Which is a dll). This project uses external dll's such as BOOST. So when building the project I have to define the directories in which the .dll, .lib and .h/.hpp files are.
Currently I am using scons to build the project and define those paths straight in the SConstruct file.
However those paths are later reused for other build operations. (In the present case compiling the C++ code in MEX for matlab but that's not really the point here).
Thus I currently have to define the same path in different places which is inefficient. In addition the project has to be easy to set up for another user. So having to change and update path in many different files is something I would like to avoid.
From where I stand I see two alternatives:
First I could ask the user to define environment variables and read them from inside my various build scripts. However I am not really satisfied with this solution for it asks the user for additional manipulation and, as far as I've understand, I lose the cross-platform portability that scons offers. (I know it might still possible but requires some extra steps and I'd like to keep things as simlpe as possible)
Second I could define all my path in a single .txt (or something similar) file at the root of my project and read it from my various build scripts. However this makes the process sensitive to typos and parsing errors which is not really to my taste.
So my question is the following:
Is there a better way or good practice to have the user input the paths necessary for compilation that satisfies the following:
Has the user only input once every path
Is done within the project folder through a file or something else
Is as foolproof as possible
Does not require too much additional download/installing (I don't really want to have the user install a brand new software for this. However I'm fine with something like a simple light .exe that I can add in my project files)
SCons's Variables are likely your best choice here.
See: https://scons.org/doc/production/HTML/scons-user.html#sect-command-line-variables
It allows reading defaults from a file:
vars = Variables('custom.py')
You'd have to craft some logic to save any variables specified on the command line.

How to create dynamic defines for Visual Studio?

I have a C++ project that builds on several platforms.
On Mac OSX and Linux, I use SConstruct, which allows me to have some "smartness" regarding the different compilation steps. Namely, I could put the program version in a file named VERSION at the root of the repository, whose content is simply:
2.0
In the build SConscript, I just have to open, read and parse that file and I can create dynamic defines based on it. For instance:
env.Append(CXXFLAGS=['-DVERSION_MAJOR=%s' % open('VERSION').read().split('.')[0]])
This is, for obvious reasons, very convenient. It also allows me to put today's date in an environment variable for instance.
Now for Windows, I have a .sln file with different .vcxproj files into which I'd like to do something similar, except I have no idea how.
To summarize, my question is: how can I have "smart" defines like that (reading, parsing a file and putting its content into several environment variables) without having to change the .sln/.vcxproj files manually on every version shift ?
I know I could use SCons on Windows too, but I'd like not to (mainly because it seems less popular on the platform, and I don't want to scare potential contributors that only know Windows-specific tools).
A common way to do this is to define your constants in an include file:
e.g.
// Version.h - Autogenerated, don't edit
#define VERSION_MAJOR 1
Next you write a script or a program (in your favourite language) to obtain version from somewhere and dynamically write Version.h. Possibly parse the old Version.h and increment or get it from some external source.
In visual studio, create a custom build step for Version.h and make it dependent on something that forces it to update on every build.
You could maintain the current solution, and for Windows, integrate it with Visual Studio solution and project files generated by SCons using the MSVSProject() builder or the MSVSSolution() builder.
You can find more info about these SCons builders here.

Is there anyway to figure out what STL header file has not been included directly?

Our product uses C++ as the programming language. One annoying issue of using C++ STL is that we forget to include the necessary header files, because the file may have been included in some other STL header, the build passes. For example,
In Mac platform using Xcode, if I use std::auto_ptr without include memory.h but include iostream.h, the build will pass, but it will fail in Android platform.
But I don't want move the code to Android for an build check for each code change commit. So, is there anyway to avoid that problem?
Edit 1:
I know the best solution is to not forget the include the header. But developers make mistakes. So is there any tool to help check it?
Edit 2:
Seams no ideal solution, so I will use vim script to check it in my editor,the solution is similar to https://github.com/vim-scripts/vim-cpp-auto-include/blob/master/ftplugin/cpp_auto_include.vim
You can use a common_includes.h file that includes all necessary files there, and include that file everywhere you need. This will simplify the situation and will help out forgetting to include some file. At least you will forget it only one time :).
The only tool I know of... is the compiler itself.
Whenever the issue is portability, the best solution I have seen was to simply put on automated build/test suites for all required environments. Then, whenever a pull request is made it will be validated on all your build bots, and you will be warned if you forgot something.

Automatic build ID

We're looking for a way to include some sort of build ID automatically in our builds. This needs to be portable (VC++, g++ on Linux and Mac) and automatic. VC++ is what matters most, since in the other environments we use custom Python build scripts so I can do whatever I want.
We use SVN, so we were looking at using the output of svnversion to write the revision to a header and include it. This has problems : if we put the file in SVN, it will appear as modified every time, but it would be a superfluous commit and in a sense generate an infinite loop of increasing revisions. If we don't put the file in SVN and just create it as a pre-build step, the sources wouldn't be complete, as they'd need the pre-build step or Makefile to generate that file.
We could also use __DATE__ but we can't guarantee the file that uses the __DATE__ (ie writes it to a log file) will be compiled if some other file is modified - except if we "touch" it, but then we'd cause the project to be always out of date. We could touch it as the pre-build step, so it would get touched only if the rest of the project is out of date, thus not causing a spurious compile, but if VC++ computes the dependencies before the pre-build step, this wouldn't work (the file with __DATE__ won't get compiled)
Any interesting ideas?
We're using the output of svnversion, written to a header file and included. We omit the file from the repository and create it in a pre-build step; this has worked quite well for us. (I'm not sure why you object to using a pre-build step?)
We're currently using a Perl script to convert svnversion's output into a header file; I later found out that TortoiseSVN includes a subwcrev command (which has also been ported to Linux) that can do much of the same thing.
If you don't like the idea of an include file not in source control that is required for a build, consider a batch file or other build step that programmatically creates a file/include and call the svnversion within your build process.
basically GENERATE the file so you don't have an unversioned and required file.
EDIT
Josh's subwcrev is probably the best idea.
Before that was implemented I wrote my own hacky tool to do the same thing - do replacement in a template file.
It could be as simple as:
% make -DBUILD_NUMBER=`svnlook youngest /path/to/repo`
I'd look at SvnRev. You can use it as a custom pre-build step in VS, or call it from a makefile, or whatever else you need to do, and it generates a header file that you can include in your other files that will give you what you need. There's good documentation on the site.
SubWCRev is another option, though the Linux port is newer, and I don't know that a Mac version exists. It's very useful on Windows for .NET (which I'm guessing isn't an issue for you, but I'm adding this for future reference), because it allows you to create a template file that can be used to generate, for example, the Properties file for a .NET assembly.
Automatic builds can typically be full, clean builds. In that case, you start in a clean directory and there would be no issue with __DATE__ in any case. Otherwise, see Paul Beckinham's idea.
Why not tie a GUID to it, almost every language has support for generating one, or if your's doesn't there are alot of algorithms for that around.
(Although, if you do use subversion, I personally like Josh's idea better!)