cmake project include dirs detection in vim editor [duplicate] - c++

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.

Related

Considering Autocompletion. How to tell Geany in which directories to look for header files?

I am coming from KDE to XFCE and hence arrive from KDevelop at Geany. I have no plans of using Geany for any compilation stuff, prefering to write my own CMakeLists.txt files. However, what I loved about KDevelop and dearly would have again:
In KDevelop I could "attach" an include-directory to a c++ file meaning that code autocompletion would look for #included headers within that directory and use its content.
For example it was possible to "attach" something like /usr/share/myIncludes/
containing "my_foo.h". Then in the source code of my program I would
#include "my_foo.h"
and henceforth auto-completion would kick in using the contents of "my_foo.h".
I find this surprisingly hard to google. Is there even a feature like that in Geany, and if so, how would one use it?
My Geany is a simple install (geany and geany-common) on a clean (no non-free stuff) Debian System.
Geany is not supporting dynamic parsing of header files due to the performances and resources impact it would have.
However, you can generate a tag file from your headers as described inside manual or maybe use a plugin like geanyctags or projectorganizer (recently rename from gproject) which could help you there
Also you can find tag-files inside the wiki which you can import via the Tools-menu.

Eclipse CDT: Define quoted string as preprocessor define

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>"'

Open declaration feature in VI

I'm a vi user for coding in Python. I love it: powerful, lowlevel, minimal gui without useless buttons, etc.
Now I'm approaching C++ with an opensource project that—as usual happened in opensource project—has poor documentation and sometimes (well, a lot of times) I have to open declaration and implementation and see what a particular function does.
In Eclipse this is really easy to do due to the Open Declaration (shortcut F3) feature. But I don't like the CDT plugin for Eclipse. I have a makefile project and it indicates some error in importing external .cpp files inside this opensource framework that requires a custom structure for directory and build path (and it's annoying to create a project every time in Eclipse for this custom structure).
I wish to have the same feature in vi. Do you know of anything?
Vim doesn't offer a feature like that by itself. A rudimentary way would be to use gd in command mode. If you want more sophisticated support, take a look at ctags and cscope. Those tools offer which you ask for and integrate nicely into Vim. A quick google search brought me to this link, which explains how to use cscope within Vim. Using ctags quite as easy: generate the ctags database/tags file and use Ctrl+] on an identifier to jump to its declaration. See :help ctags for more information.
One option: Use QT Creator with FakeVim mode enabled. You can follow declarations with F2.

Externalizing parameters for VS2008 C++ project compilation

Is there some way to externalize the paths of libraries that are used in the compilation process on Visual Studio 2008? Like, *.properties files?
My goal is to define "variables" referencing locations to headers files and libraries, like *.properties files are used in the Ant build system for Java.
I think you're looking for .vsprops files. They're comparable to the *.properties files.
Environment Variables?
All the $(xyz) replacements allowed in the propertier are, and you are allowed to "bring your own".
They are normally inherited from the parent process, so you can set them
for the machine / user in the system settings (usually inherited via explorer)
in a batch file that sets them before running devenv.exe
in an addin like SolutionBuildEnvironment to read them from a project file
I don't know how Ant works, but for your static libraries and headers you can edit the .vcproj file. These are XML files in fact. Libraries go in the VCLinkerTool tool tag, in AdditionalDependencies
<Tool
Name="VCLinkerTool"
AdditionalOptions=" /subsystem:windowsce,5.01"
AdditionalDependencies="iphlpapi.lib commctrl.lib coredll.lib"
/>
Additional header paths are defined in the VCCLCompilerTool tool tag, in AdditionalIncludeDirectories
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="dev\mydir"
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
/>
Be careful, there is one such section for each build configuration.
Is this what you are looking for?
Edit : the .vsprops suggested by MSalters are more powerful; you can define additional dependencies and libraries in them an make your projects inherit these properties. Well I learned something useful today!
If you're referring to influencing the location of #includes, Project properties|Configuration Properties|C/C++/Additional Include Directories is the ticket. There is also project properties|Common Properties|Additional reference search paths.
If your question is how do I parameterize stuff in a VCProj file like I would in Ant, the answer is that in VS2010 VC projects are[/can?] be MSBuild-based whereas VS2008 vcproj files are a proprietary XML based format [but as the other answers say, they have an analogous properties capability].
In the absence of more info, I'm pretty sure the standard approach for what you're doing is to add your search paths a la the first or second paragraph.
You can use a build system like CMake. You give CMake a high-level description of your project, and it spits out the necessary files to get your project to build correctly via another tool (e.g. Visual Studio's IDE, or a Unix-style makefile).
Paths: You can use CMake's INCLUDE_DIRECTORIES() and LINK_DIRECTORIES() commands in the CMakeList.txt configuration file to specify these paths. CMake has variables which describe both aspects of your environment (many of which can be autodiscovered, e.g. CMAKE_C_COMPILER which is the command to run your C compiler) plus any options you wish to allow the user to specify directly. All variables are stored in a separate plain text configuration file, CMakeCache.txt, that can be edited in a text editor or using a special GUI configuration tool.
CMake has many other features, like the ability to autodiscover the locations of many useful libraries, and to produce customised source/header files from "template" files containing CMake directives using the CONFIGURE_FILE() command.
Advantages:
Highly portable across common environments (e.g. it can produce solution files for several versions of MS Visual C++, as well as makefiles for Unix (e.g. Linux) systems).
Used by several large multiplatform projects (e.g. KDE)
Very simple to set up simple projects
I've found the dependency checking system to be rock-solid -- e.g. it knows to rebuild if you change compiler options (unlike naive use of make for example)
Disadvantages:
Ugly, primitive syntax
Documentation quality varies (e.g. it's sometimes hard to tell exactly what properties affect any given object)
Some time investment involved

Complex builds in Visual Studio

I have a few things that I cannot find a good way to perform in Visual Studio:
Pre-build step invokes a code generator that generates some source files which are later compiled. This can be solved to a limited extent by adding blank files to the project (which are later replaced with real generated files), but it does not work if I don't know names and/or the number of auto-generated source files. I can easily solve it in GNU make using $(wildcard generated/*.c). How can I do something similar with Visual Studio?
Can I prevent pre-build/post-build event running if the files do not need to be modified ("make" behaviour)? The current workaround is to write a wrapper script that will check timestamps for me, which works, but is a bit clunky.
What is a good way to locate external libraries and headers installed outside of VS? In *nix case, they would normally be installed in the system paths, or located with autoconf. I suppose I can specify paths with user-defined macros in project settings, but where is a good place to put these macros so they can be easily found and adjusted?
Just to be clear, I am aware that better Windows build systems exist (CMake, SCons), but they usually generate VS project files themselves, and I need to integrate this project into existing VS build system, so it is desirable that I have just plain VS project files, not generated ones.
If you need make behavior and are used to it, you can create visual studio makefile projects and include them in your project.
If you want less clunky, you can write visual studio macros and custom build events and tie them to specific build callbacks / hooks.
You can try something like workspacewhiz which will let you setup environment variables for your project, in a file format that can be checked in. Then users can alter them locally.
I've gone through this exact problem and I did get it working using Custom Build Rules.
But it was always a pain and worked poorly. I abandoned visual studio and went with a Makefile system using cygwin. Much better now.
cl.exe is the name of the VS compiler.
Update: I recently switched to using cmake, which comes with its own problems, and cmake can generate a visual studio solution. This seems to work well.
Specifically for #3, I use property pages to designate 3rd party library location settings (include paths, link paths, etc.). You can use User Macros from a parent or higher level property sheet to designate the starting point for the libraries themselves (if they are in a common root location), and then define individual sheets for each library using the base path macro. It's not automatic, but it is easy to maintain, and every developer can have a different root directory if necessary (it is in our environment).
One downside of this approach is that the include paths constructed this way are not included in the search paths for Visual Studio (unless you duplicate the definitions in the Projects and Directories settings for VS). I spoke to some MS people at PDC08 about getting this fixed for VS2010, and improving the interface in general, but no solid promises from them.
(1). I don't know a simple answer to this, but there are workarounds:
1a. If content of generated files does not clash (i.e. there is no common static identifiers etc.), you can add to the project a single file, such as AllGeneratedFiles.c, and modify your generator to append a #include "generated/file.c" to this file when it produces generated/file.c.
1b. Or you can create a separate makefile-based project for generated files and build them using nmake.
(2). Use a custom build rule instead of post-build event. You can add a custom build rule by right-clicking on the project name in the Solution Explorer and selecting Custom Build Rules.
(3). There is no standard way of doing this; it has to be defined on a per-project basis. One approach is to use environment variables to locate external dependencies. You can then use those environment variables in project properties. Add a readme.txt describing required tools and libraries and corresponding environment variables which the user has to set, and it should be easy enough for anyone to set up.
Depending on exactly what you are trying to do, you can sometimes have some luck with using a custom build step and setting your dependencies properly. It may be helpful to put all the generated code into its own project and then have your main project depend on it.