Sublime Linter with clang can't find header file in header - c++

I'm using sublime text with the sublime linter plugin especially with clang.
When I open a folder, it use the root of the folder as a header location, so if I have
src
├── World
│   ├── Chunk.cpp
│   ├── Chunk.hpp
│   ├── World.cpp
│   └── World.hpp
└── main.cpp
In World.cpp I need to include "World/World.hpp".
But if in World.hpp I include Chunk.hpp the same way ("World/Chunk.hpp"), I get an error but
in World.hpp I have no error. Error are only in file I include that include other file.

I had the same issue. You need to tell clang where to look for the files, i.e. which directories you want to include. Go Preferences --> Package Settings --> SublimeLinter --> Settings and add a new section for clang++:
// SublimeLinter Settings - User
{
"linters":
{
"clang++": {
"I" : [
"${folder}/src",
"${file_path}",
]
}
}
}
In your case the two include directories will actually point to the same path but in general, the first version is to include your source directory (e.g. you have a unit test from a different folder open which accesses code from you src directory) and the second line includes the location of your current file.
If you need different directories, find some more variables you can use here.

Related

How to get unit tests (using CMake and GTest) to know where a folder of test data is?

I am using CMake and GTest to unit test a C++ program. One of my tests uses fopen() to open a file of test data.
I am struggling to figure out how to not get a "No such file or directory" error.
Directory Structure
├── CMakeLists.txt
├── build
├── src
│ └── myProgram.cxx
└── tests
├── CMakeLists.txt
├── data
│ ├── dataset1.txt
│ ├── dataset2.txt
│ ├── dataset3.txt
│ └── dataset4.txt
└── myProgramTests.cxx
Test Code
TEST(test, read_data_file) {
// Open test file
std::FILE *f = fopen("inputs/dataset1.txt", "r");
if (f == NULL){
perror ("Error opening file");
}
fclose(f);
}
This seems simple, but I can't figure out what to put here. I have tried "dataset1.txt", "inputs/dataset1.txt", "tests/inputs/dataset1.txt". What am I missing / is there a way for me into "include" these files via a line in CMakeLists.txt so I can just read them in with one of the strings I tried above?
Summary: How do I properly reference the location of files stored in a tests/data subdirectory within GTest?
Use ctest of cmake. Its add_test command has a useful property WORKING_DIRECTORY that are you looking for.
Paths that do not start with a / are relative to your current working directory, i.e the directory your shell is in when you run the tests.
For example, if your current working directory is the top-level directory of your project, then the relative path to dataset1.txt is tests/data/dataset1.txt

How can I avoid relative paths in #includes when building with Bazel

I'm struggling to understand the logic of how includes work in Bazel targets. I want my code to be modular, so I am trying to avoid #include statements with relative or long absolute paths.
Suppose I have the following workspace structure:
tree .
.
├── BUILD
├── is_binary_tree
│   ├── BUILD
│   └── is_binary_tree.cpp
├── lib
│   ├── BUILD
│   ├── graphs.cpp
│   └── graphs.h
└── WORKSPACE
I'm getting the following warning when trying to bazel build //is_binary_tree:is_binary_tree and I don't understand what it means :
WARNING: /is_binary_tree/BUILD:1:10:
in includes attribute of cc_binary rule
//is_binary_tree:is_binary_tree: '../lib' resolves to 'lib' not below
the relative path of its package 'is_binary_tree'. This will be an
error in the future
Why would ../lib resolve to lib. Lib should be in the parent directory of is_binary_tree, so from the standpoint of is_binary_tree it can be found at ../lib, isn't this right?
To get rid of the relative path and avoid having something like #include ../lib/graphs.h in is_binary_tree/is_binary_tree.cpp I added an includes attribute to my is_binary_tree target like so:
is_binary_tree/is_binary_tree.cpp
#include "graphs.h"
int main(){
return 0;
}
is_binary_tree/BUILD
cc_binary(
name="is_binary_tree",
srcs=["is_binary_tree.cpp"],
includes=["../lib"],
deps=["//lib:graphs"],
)
And I'm getting the aforementioned WARNING. What am I missing?
And more broadly, what is the best way to include dependencies without having long relative paths in #include statements ? (I want my code to be modular and not specific to a given Bazel workspace folder organization)
Thanks
That includes should go in //lib:graphs, so that anything which depends on it (has it in deps) uses it. lib/BUILD should look like this:
cc_library(
name = "graphs",
hdrs = ["graphs.h"],
srcs = ["graphs.cpp"],
includes = ["."],
visibility = ["//visibility:public"],
)
Then you drop includes from is_binary_tree and it should work.
In general, each Bazel target contains information about its files. It depends on other targets to use their files.
More broadly, Bazel defaults to #include paths relative to the base of the repository. That means you'd write #include "lib/graphs.h" in any file, whether that's is_binary_tree/is_binary_tree.cpp or x/y/z/foobar.cpp. That avoids collisions between graphics/constants.h and audio/constants.h, without using absolute paths.

How do I import a package from the local filesystem using dub?

I have a project that uses dub. I want to use an external file vendored into my project, as a dependency. How do I do this? I don't want to have it in my project's source/ dir. I don't want to add it as a dub managed dependency, but I do want to be able to just import xxx.
The package is this one: https://github.com/gianm/d-json , it does not use dub or have a dub.json project file.
Alternative thing: make a third_party directory, put the file in there, then add that to the sourcePaths in your dub config (you'll probably specify both ["third_party", "source"] since the default source will be overridden if you don't list it too.
Convert the package to dub by adding a dub.json file in the root, with the following contents: {"name": "jsonx"}. Create a source folder, and move jsonx.d into it.
Put the folder anywhere you want, e.g. top-level next to your own project.
Add the following dependency to your dub.json:
"dependencies": {
...
"jsonx": {"path": "../jsonx/"}
}
You can now import the package anywhere using import jsonx;.
In conclusion, if your app is in a dir called app, your tree should look like this:
.
├── app
│   ├── dub.json
│   └── source
│      └── myapp.d
└── jsonx
├── dub.json
└── source
└── jsonx.d

gitignore pattern to include all directories with a specific sub directory

I am trying to setup a .gitignore file for openFrameworks. I have a folder that contain project folders - each one has a src directory. I would like to include the folder itself and the src directory only for every project.
Here is my current .gitignore file
# ignore these files
# ignoring everything except spec items
*
# allow these files
!.gitignore
!/README.md
!/*/src
Any help would be greatly appreciated. Ideally I would like the committed folder structure to look something like this:
.
├── project_1
│   └── src
│   └── file.cpp
├── project_2
│   └── src
│   └── file.cpp
└── project_3
└── src
└── file.cpp
What am I missing? Thank you.
If you ignore files and folders (with '*'), you won't be able to exclude sub-folders.
The rule to remember remains:
It is not possible to re-include a file if a parent directory of that file is excluded.
Try instead ignoring files only.
**
Then you can exclude subfolders like src:
!.gitignore
!/README.md
!src/
# or, to be more specific
!/*/src
For any element that would be still ignored, check what rule is involved with:
git check-ignore -v -- an/ignored/element

Proper way to include headers in C or C++

I just found out i've been doing this wrong for the whole time. I haven't used any ide and only use gcc. I have started using makefile also to compile my large project.
most of the time the file structure was this
├── makefile
└── src
├── folder1
│   ├── header1.cpp
│   └── header1.h
├── folder2
│   ├── header2.cpp
│   └── header2.h
└── main.cpp
on header2.cpp, when I include header1.h I do it like this
file header2.cpp
#include "../folder1/header1.h"
this is how I include the other files from another folder.
I think I am doing wrong. most of the tutorial I have watch uses Ide and they don't include it like that.
some include it like this
#include "folder1/header1.h"
or others put it in a one folder like headers/
then include it like this.
#include "header1.h"
Can anyone guide me. how do i achieve this. I been doing this bad including I guess.
I don't want to include files like this
#include "../../../../sofarfolder1/header1.h"
thanks. it makes me puke everytime I see my code.
You can use the -Idir flag to tell GCC to look for header files in the directory dir, if you don't want to use ../.
More info: https://gcc.gnu.org/onlinedocs/cpp/Search-Path.html
https://gcc.gnu.org/onlinedocs/gcc/Directory-Options.html
In your makefile, you can invoke gcc with -I../../../sofardirectory
That way, it will look in that directory for headers you include.
An unusual alternative to using compiler flags to specify additional include directories is to use the C Preprocessor to create defined constants for the include file path.
For instance if you have an include file with a relative path such as #include "../../stuff/lib1/thing1.h" you can do something like the following.
#define THING1_H_PATH "../../stuff/lib1/thing1.h"
// ...
#include THING1_H_PATH
The gcc C Preprocessor documentation, The C Preprocessor in section 1.3.2, The #include Directive has this to say:
#include anything else
This variant is called a computed #include. Any `#include' directive
whose argument does not fit the above two forms
is a computed include. The text anything else is checked for macro
calls, which are expanded (see section 1.4 Macros). When this is done,
the result must fit one of the above two variants--in particular, the
expanded text must in the end be surrounded by either quotes or angle
braces.
This feature allows you to define a macro which controls the
file name to be used at a later point in the program. One application
of this is to allow a site-specific configuration file for your
program to specify the names of the system include files to be used.
This can help in porting the program to various operating systems in
which the necessary system header files are found in different places.
How I deal with headers depends in if they are going to be installed (as with a library) or not.
Private headers I would keep in the project source folder:
├── Makefile
└── src
├── header1.cpp
└── header1.h
├── header2.cpp
└── header2.h
└── main.cpp
Then just include them like this:
#include "header1.h"
Public headers (to be installed) I generally put in a project subfolder like this:
├── Makefile
└── src
├── project
│ ├── header1.h
│ └── header2.h
└── header1.cpp
└── header2.cpp
└── main.cpp
And I include them like:
#include <project/header1.h>
In order to locate the public headers you need to set a compiler flag. For GCC that is -I
g++ -Isrc ... etc ...
When the headers are installed they will go somewhere like /usr/include:
── usr
└── include
├── project
│ ├── header1.h
│ └── header2.h
And client software will include them the same way:
#include <project/header1.h>
But they will supply different flag settings to find them:
g++ -I/usr/include ... etc ...