Incomplete typedefs in libgit2 - c

I am trying to integrate libgit2 (1.5.0) into my project. The compilation failes due to missing type definitions.
The CMakeLists.txt of my project includes the include directory and the libgit2.a file:
target_include_directories(myprj PUBLIC ../libgit2/src/libgit2-1.5.0/include)
set(myprj "${CMAKE_SOURCE_DIR}/lib/libgit2.a")
link_directories(myprj ${PROJECT_SOURCE_DIR}/lib)
target_link_libraries(myprj PUBLIC ${libgit} crypto ssl)
The following code is a simplified version of the code I am using, but it should demonstrate the problem:
#include <git2.h>
git_reference *ref;
git_branch_t btype;
int code = git_branch_next(&ref, &btype, iterator);
if(code != 0)
return code;
char* name = ref->name;
The compiler fails with the error:
error: invalid use of incomplete typedef ‘git_reference’
char* name = ref->name
^~
The include directory defines the type but the stuct itself is defined in the src directory only.
libgit2-1.5.0/include/git2/types.h (source)
typedef struct git_reference git_reference;
libgit2-1.5.0/src/libgit2/refs.h(source)
struct git_reference {
//...
};
I have tried to fix it by importing the src dir into my project but this doesnt work because of missing includes.
Import in Cmake:
target_include_directories(myprj PUBLIC ../libgit2/src/libgit2-1.5.0/src/libgit2)
Error:
libgit2/src/libgit2-1.5.0/src/libgit2/common.h:10:10: fatal error: git2_util.h: File or directory not found
10 | #include "git2_util.h"

I think this is on purpose, to make git_reference an opaque type. It can then be changed at will by the library authors without breaking compatibility.
To get the name of a reference, use git_reference_name instead of accessing the field directly:
const char* name = git_reference_name(ref);

Related

Including enums defined in header

I have been fiddling with enums for a while and wanted to try to use them in a project. The project structure is as follows:
// protocol.h
#ifndef PROTOCOL_H
#define PROTOCOL_H
enum C_C {P_NORTH = 0,
P_WEST = 1,
P_SOUTH = 2,
P_EAST = 3};
#endif
// other.h
#include "protocol.h"
struct cmd {
enum C_C code : 4;
};
void make_cmd(struct cmd*, enum C_C);
This file triggers the following errors:
field 'code' has incomplete type
'enum C_C' declared inside parameter list will not be visible outside of this definition or declaration
// other.c
#include "other.h"
void make_cmd(struct cmd* cmd, enum C_C code) {
cmd->code = code;
}
This throws the following errors:
conflicting types for 'make_cmd'
I have tried changing the enum to a type using typedef with no luck. This happens also with function definitions which rely on this type of parameters.
Will throw the following error:
type of formal parameter 2 is incomplete
Thanks for your help.
This only happens when using the defined enum in another header, either for structs or for functions prototypes.
I do believe there must be some issue with the compilation order. I have tested in Xilinx SDK and Vitis with the same result.
protocol.h holds all the definitions of the enums and the structures to be used throughout the project. I was hoping by just including this one in the other headers the definitions would be available to build the other.h and other.c on top of that one.
Update:
I have moved the definition of the structure inside the protocol.h and it lets me add a member using the enum without issues. I guess the problem is when importing protocol.h into another header and trying to use the enum there the compiler has all of the headers in the
This code compiles:
#include "other.h"
void make_cmd(struct cmd* cmd, enum C_C code) {
cmd->code = code;
}
int main(int argc, char *argv[])
{
struct cmd cmd;
make_cmd(&cmd, P_WEST);
}
If you #include "protocol.h" as well you'll get an error (type redefinition) because it is already included in other.h.

malloc a struct in kernel header file error :invalid application of 'sizeof' to incomplete type

I'm new to linux.
I'm practice syscall and I want to copy struct to user.
So I write a syscall which is using copy_to_user().
But When I write and compile test.c to test my syscall appear some error.
in linux/sched.h has defined:
struct pacct_struct {
int ac_flag;
long ac_exitcode;
unsigned long ac_mem;
cputime_t ac_utime, ac_stime;
unsigned long ac_minflt, ac_majflt;
};
and then I write a program that use this struct(test.c)
#include "linux/sched.h"
#include <stdlib.h>
int main(){
struct pacct_struct *ts;
ts = (struct pacct_struct *)malloc(sizeof(struct pacct_struct));
return 0;
}
and gcc show the follow error message:
test.c:6:44: error: invalid application of 'sizeof' to incomplete type 'struct pacct_struct'
I wonder to know if it's fine to use kernel struct by include header file.
If so, do I miss something? How to make pacct_struct become a 'complete type'?
thanks.
addition:
I check preprocessor with gcc -E
I found that seems no "struct pacct_struct" being included.
Next, I going to view sched.h that I included which was created by "make headers_install" after I compile the kernel.
The file only contains some cloning flags such like "#define CSIGNAL 0x000000ff"
So, I tried to include original source file of sched.h in dir "/usr/src/linux-2.6.39.4/include/linux", but it continue showing same error 'incomplete type'.
Then I check preprocessor again.
I still can't find 'struct pacct_struct' even I include original header file
Anything in sched.h after #ifdef __KERNEL__ is disappear, What happened?

undefined reference when including a header file

I get an error when I include a header file, but not if I include the source file instead.
The function is defined in the source file like this:
/* in User.c */
struct User {
const char* name;
};
struct User* addedUser(const char* name) {
struct User* user = malloc(sizeof(struct User));
user->name = name;
return user;
}
And used like this:
/* in main.c */
int test_addedUser() {
char* newName = "Fooface";
struct User* newUser = addedUser(newName);
assert(!strcmp(newName, newUser->name));
return 0;
}
This works great. I am able to call test_addUser without a problem when I #include "User.c".
However, I would like to #include "User.h" instead, which is located in the same directory:
/* in User.h */
struct User {
const char* name;
};
struct User* addedUser(const char*);
But, if I #include "User.h" instead of User.c, I get an error:
CMakeFiles/run_tests.dir/src/tests.c.o: In function `test_addedUser':
/home/rid/port/src/tests.c:(.text+0x4eb): undefined reference to `addedUser'
It seems strange to me that the reference works just fine when including the source file User.c but it is unable to reconcile User.h.
Any ideas why this might be?
#include means that the file included is copied into the source file.
So when you include your .c file, the function's code is here and it works.
If you include only the header file, it's good thanks to that your functions will know each other, at least they will now they exist but they need their code to work together, so you need now to compile your two files.c together, not one by one.
Maybe you're compiling by yourself :
gcc file1.c file2.c
Or with an IDE, you have to adjust the compiling options.
If you want to compile the C files separatly, you have to compile them in object files (-c option with gcc), then link them.
So I created some custom lib folder for example "engine" and placed some .cpp files in it:
main.cpp
engine/sprite.cpp
engine/sprite.h
engine/unit.cpp
engine/unit.h
So before compile cmd looked like:
g++ -o main main.cpp
After adding folder:
g++ -Iengine -o main main.cpp engine/*cpp
And it works

libwebsockets: Dereferencing pointer to incomplete type error

I'm using libwebsockets and I can't compile a demo code implemented by myself.
I created the context:
struct libwebsocket_context *context;
...
context = libwebsocket_create_context(&info);
and when I try to access the members of the struct libwebsocket_context, defined in private-libwebsockets.h:
struct libwebsocket_context {
struct pollfd *fds;
struct libwebsocket **lws_lookup; /* fd to wsi */
int fds_count;
int max_fds;
int listen_port;
...
};
For example,
printf("%d\n", context->listen_port);
The compiler returns,
error: dereferencing pointer to incomplete type
Thanks!
It seems that "struct libwebsocket_context" is not known for gcc - that's why this error occures. Are you sure that definition of this structure is included from .h file? I'd suggest you to insert for example #warning or #error with some message near definition of this struct (in .h file) and try to recompile your program. Your #error or #warning message should appear while compilation. If not - it means that gcc will not also see this struct.
The fact that the struct definition is in private-libwebsockets.h suggests that you are not supposed to use the struct members directly. You can #include that header to get access to the private implementation details of the library but you probably should not do it.

Strange makefile build error

I'm working on this very simple part of code, but somehow the build error is pretty strange to me.
I have these files in the project: main.c, http_request.h, http_request.c; and a simple Makefile.
1. http_request.h
/* STRUCTURES */
struct http_param {
char key[MAX_BUFFER];
char *value;
};
struct http_request {
int size;
struct http_param data[MAX_PARAM];
};
/* FUNCTIONS */
int parse_http_request(apr_pool_t *pool, const char *args, struct http_request *req); /* (A) */
2. http_request.c
#include <http_request.h>
...// something else goes here, it's fine
int
parse_http_request(apr_pool_t *pool, const char *args, struct http_request *req) /* (B) */
{
3. Makefile
-I$(PROJECT_DIR)/include
this directory contains http_request.h.
Then I build, it raises this error:
/project/src/http_request.c:14: warning: 'struct http_request' declared inside parameter list
/project/src/http_request.c:14: warning: its scope is only this definition or declaration, which is probably not what you want
/project/src/http_request.c: In function 'parse_http_request':
The error points to (A) and (B) as I mentioned in source code above.
Could anyone help to find out what the problem is?
Thanks.
I suspect, seeing that you use apr_pool_t, that you also have apache includes in your include path. apache also provides a file called http_request.h and that one gets included instead of the one you have.
use
#include "http_request.h"
instead of
#include <http_request.h>

Resources