Googletest no such file or directory - c++

I want to import my c++ code in the testing file i'm using for unittesting, but googletest can't find it. When i try to import on another file on same folder level it works.
BUILD: https://pastebin.com/UR048jg4
WORKSPACE: https://pastebin.com/cZ4KuN4t
I'm trying to import my file like this
#include "myvector.h"
├── BUILD
├── hello_test.cc
├── main.cpp
├── myvector.cpp
├── myvector.h
└── WORKSPACE
EDIT:
I don't know why, but i can't answer to comments. Thanks a lot to everyone
the problem was that i wasn't including myvector.h in my srcs in the BUILD file

I managed to get it working, i wasn't including myvector.h in my bazel BUILD file. This is the correct file
cc_test(
name = "hello_test",
size = "small",
srcs = ["hello_test.cc", "myvector.h"],
deps = ["#com_google_googletest//:gtest_main"],
)

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

Is there a way to specify output imports for generated C++ code when using ProtocolBuffers?

I'm trying to compile C++ code into a single binary using .proto files. My current process has 2 steps;
Generate C++ code from 3 .proto files using protoc.
Compile the generated code and my own C++ code into a single .o file.
However, when I try to compile in step 2, the generated code specified outputs as 'com/company/B.pb.h', which fails to be found by the compiler, because the file is in the same directory.
I don't want to manually change the generated code imports as I feel that should be done by protoc, and we also use these proto files for other projects (including generating java code using the same .proto files, which works). Is there a way to specify the generated code's imports WITHOUT changing the proto imports?
EDIT:
Is this an issue with protoc when generating multiple files at once? Should I be using a different command?
I know there are options for java like specifying the package or classname, but I can't find anything similar for C++.
option java_multiple_files = true;
option java_package = "com.company.B";
option java_outer_classname = "B";
Any help is much appreciated. More details below.
Directory structure:
.
├── com
│   └── company # generated code
│   ├── A.pb.cc
│   ├── A.pb.h
│   ├── B.pb.cc
│   ├── B.pb.h
│   ├── C.pb.cc
│   └── C.pb.h
├── Parser.cc
├── Parser.h
└── proto
└── com
└── company
├── A.proto
├── B.proto
└── C.proto
Protoc command: (run from .)
protoc --cpp_out=. --proto_path=proto/ com/company/A.proto com/company/B.proto com/company/C.proto
A.proto snippet:
syntax = "proto3";
option optimize_for = SPEED;
package com.company;
import "com/company/B.proto"; # specified as full path re Google's documentation
...
Parser.cc:
#include "parser.h"
...
Parser.h:
#include "com/company/A.pb.h"
#include "com/company/B.pb.h"
#include "com/company/C.pb.h"
...
G++ command:
g++ -fPIC -Lprotoc -lprotobuf parser.cc -o parser.so
The Error:
fatal error: com/company/B.pb.h: No such file or directory
#include "com/company/B.pb.h"
^~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
I never found a way to specify the output for C++ generated code, but I found a way to compile the code correctly without doing janky workarounds, and I think this is the approach I should have taken at the start. Here goes:
Step 1, the generated C++ code stays the same, and it is generated with path includes, and are compiled in the same directory.
Step 2 becomes a make file (we are using Ruby Make/Rake but the concept is the same)
The makefile specifies;
the parser.cc and all the generated .cc files as the sources.
the $LIBS flags -fPIC -lprotobuf (Note the lack of -Lprotoc here, I ran into errors further along the track. Usually about undefined symbols)
the $INCFLAGS ` -I$(srcdir)/com/company ```. (This is a directory for the make file to include in compilation)
the $VPATH $(srcdir)/com/company. (This is a directory for the make file to search.)
This resulted in a .o file being generated for each .proto file, and a .o file for the parser.cc. Then they are combined into a single .so file which can be used as we intended.
Feel free to ask questions if you run into similar issues.

Sublime Linter with clang can't find header file in header

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.