Compiling C with non standard header - c

I have my main C file:
#if defined(WIN32)
#include <windows.h>
#include <stddef.h>
#endif
#if defined(LINUX)
#include <curses.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if defined(WIN32)
#include <conio.h>
#endif
#include <ctype.h>
#include <a429usbnt.h>
#if defined(WIN32)
#include "genlib.h"
#endif
void main()
{
_open_xpc(1);
}
When I try to compile using this command
gcc -I. -L. test.c -o test
I get the following error: undefined reference to '_open_xpc'.
However if I change the call to the _open_xpc function and instead just
printf("%d", XPC_ERROR_ACTIONCODE);
the program compiles fine and the correct value assigned to the definition of XPC_ERROR_ACTIONCODE is printed out, so the compiler is linking a429usbnt.h but will only recognize defined variables and not the functions.

If you are trying to link against a .lib file with gcc, it seems you need to define a directory with -L and an actual file with -l

Related

Header.h: No such file or directory

I'm trying to link my c files and header files in compilation, but get the following error:
fatal error: header1.h: No such file or directory #include <header1.h>
The problem is, I have included the header file using #include <header1.h> in each c file, and compiled using the command gcc header1.h file1.c file2.c main.c -Wall -std=c99 But still gives me the error in every c file. I've included the top of my code from each file below.
header1.h:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct microtreat{
int id;
char user[51];
char text[141];
struct microtreat*next;
}treat;
main.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <header1.h>
file 1:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <header1.h>
file 2:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <header1.h>
How do I fix this error? Thanks
try
#include "header1.h"
when you use the <> include. the pre processor search's for the header in certain paths but if you want to include file in the directory of your c files you should use include ""
if you want to include header file in other directory you can compile it with the directory which the header is in like so:
gcc some_compilation_flags name_of_c_file_to_compile.c -iquote /path/to/the/header/directory
the flag -iquote say to the compiler to include this directory to find the include file in it
There are two ways of including headers in C/C++.
#include <header.h> looks for the header in the system path
#include "header.h" starts looking from the local folder of the file including the header
Here there is a much more detailed explanation
What is the difference between #include <filename> and #include "filename"?

Weird behavior with defines for usleep() and inet_aton()

I have created two modules: files.h and connection.h.
files.h is included in connection.h.
files.h uses usleep() function and connection.h uses inet_aton() function at some point of the respective .c files. Those functions need the following defines:
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE
So, as files.h is included in connection.h, I thought I could just write those defines in files.h but when I compile I get the following error:
connection.c:23:6: error: implicit declaration of function ‘inet_aton’
So I decided to try to write those defines in connection.h instead of files.h just to compile and get the following error:
files.c:298:3: error: implicit declaration of function ‘usleep’
At this point, my next option was writing the defines in the respective .c files to solve this. But instead, I got this error while compiling:
files.c:302:3: error: implicit declaration of function ‘usleep’
connection.c:23:6: error: implicit declaration of function ‘inet_aton’
I don't understand what's the issue. How can I use both functions?
files.h
#ifndef _FILES_H_
#define _FILES_H_
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
// ...
#endif
connection.h
#ifndef _CONNECTION_H_
#define _CONNECTION_H_
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "files.h"
#include <ctype.h>
#include <pthread.h>
// ...
#endif
This seems to be an ordering issue..
When you include in this way:
#include <unistd.h> // other includes as well
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE
The header files are brought in without the override defines.
However, the purpose of the defines is to change what functions/signatures are imported from the headers!
And since C is very linear, the order matters..
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE
#include <unistd.h> // other includes as well
Basically, define your requests first, before you include any standard header file.
These must be included before the FIRST TIME the header is seen -
So if 'connection.c' includes something before connection.h, then the defines may not be present for the first include of <unistd.h>
I finally solved this issue writing the defines above the includes thanks to your suggestions BUT in the .c files. Still not working if I write the defines anywhere in the .h files.
files.c
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE
#include "files.h"
connection.c
#define _XOPEN_SOURCE 500
#define _POSIX_C_SOURCE 1
#define _GNU_SOURCE
#include "connection.h"

C macro name must be an identifier

I've created a c project and this is the beginning of the main.c file:
#include <curl/curl.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "include/httpdef.h"
//...some code
The httpdef.h beginning is this:
#ifndef httpdef
#define httpdef
#include <stdint.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <curl/curl.h>
//definitions
#endif
At the very first line of both files I get the error from the gcc compiler:
macro name must be an identifier
What could be the problem?
EDIT: I realized now that actually the compiler doesn't give any error, it's my vim plugin (YouCOmpleteMe) that generates this error. If I compile everything works and the error doesn't appear

can't compile c program that uses openssl libraries

I am having a hard time finding this missing reference when running : gcc server.c -I /pwdmanlib/src -lssl -lcrypto -o server the include is my src files (headers needs etc..) and the rest is th required ssl libraries.
I am getting the following output from gcc:
In file included from server.h:49:0,
from server.c:39:
/pwdmanlib/src/util/constants.h:30:0: warning: "LINE_MAX" redefined
#define LINE_MAX 2048
^
In file included from /usr/include/limits.h:147:0,
from /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/limits.h:168,
from /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/syslimits.h:7,
from /usr/lib/gcc/x86_64-linux-gnu/5/include-fixed/limits.h:34,
from /pwdmanlib/src/util/constants.h:26,
from server.h:49,
from server.c:39:
/usr/include/x86_64-linux-gnu/bits/posix2_lim.h:81:0: note: this is the location of the previous definition
#define LINE_MAX _POSIX2_LINE_MAX
^
In file included from server.c:39:0:
server.h: In function ‘start_server’:
server.h:126:34: warning: comparison between pointer and integer
if (p == NULL || listen_sock == NULL) {
^
In file included from server.c:39:0:
server.h: In function ‘routeClient’:
server.h:394:29: warning: passing argument 1 of ‘sendall’ makes pointer from integer without a cast [-Wint-conversion]
if (sendall(worker_sock, resp_data, fileLen) == -1) {
^
In file included from server.c:39:0:
server.h:70:5: note: expected ‘SSL * {aka struct ssl_st *}’ but argument is of type ‘int’
int sendall(SSL *ssl, char *buf, ssize_t *len);
^
/tmp/ccubinQD.o: In function `InitSSL':
server.c:(.text+0x1305): undefined reference to `OPENSSL_init_ssl'
server.c:(.text+0x1314): undefined reference to `OPENSSL_init_ssl'
server.c:(.text+0x1323): undefined reference to `OPENSSL_init_crypto'
/tmp/ccubinQD.o: In function `InitCTX':
server.c:(.text+0x1333): undefined reference to `TLS_server_method'
server.c:(.text+0x1350): undefined reference to `SSL_CTX_set_options'
collect2: error: ld returned 1 exit status
I found the OPENSSL_init_ssl function call in the ssl library and it is apparently getting included but can't be found by other references to it in the library?? The includes from my program are specified below:
ssl_funcs.h
#include <openssl/bio.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
#include <openssl/crypto.h>
server.h
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <unistd.h>
#include "util/oop.h"
#include "util/stringops.h"
#include "util/constants.h"
#include "fawkes_proto.h"
#include "crypto/ssl_funcs.h"
server.c
#include <netdb.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <fcntl.h>
#include <sys/wait.h>
#include <unistd.h>
#include "server.h"
#include "util/constants.h"
When linking in dynamic libraries with the -l option, these must occur last, after all other options:
gcc server.c -I /pwdmanlib/src -o server -lssl -lcrypto
Besides this, you should address the warnings in your code. These can potentially lead to undefined behavior.
To add to dbush's answer above I also needed to compile with an explicit target directory for the linking library like so: gcc server.c -I/pwdmanlib/src -o server -L/usr/local/lib -lssl -lcrypto
Moreover, I also implemented a solution for this in CMake (build system I use for my projects) and provided that below as well in case anyway else might find that useful. This is just the pertinent portion of it, if anyone wants the full src to the cmake I would be more than happy to provide it.
CMakeLists.txt
# Add libraries
include_directories(${LOCAL_LIBS_DIR})
include_directories("/usr/local/lib")
#link_directories("/usr/local/lib")
add_library(ssl SHARED IMPORTED) # or STATIC instead of SHARED
set_property(TARGET ssl PROPERTY IMPORTED_LOCATION "/usr/local/lib/libssl.so")
add_library(crypto SHARED IMPORTED) # or STATIC instead of SHARED
set_property(TARGET crypto PROPERTY IMPORTED_LOCATION "/usr/local/lib/libcrypto.so")
#include_directories("/opt/openssl-1.1.0e")
#find_package (my_library COMPONENTS REQUIRED component1 component2 OPTIONAL_COMPONENTS opt_component)
# Define build targets and link libraries
add_executable(main ${SOURCE_FILES})
target_include_directories(main PUBLIC /usr/include/openssl)
target_link_libraries(main
PRIVATE ${Boost_LIBRARIES}
PRIVATE ${PostgreSQL_LIBRARIES}
PRIVATE ${cJSON_ROOT_DIR}
# PRIVATE ${CryptoPP_ROOT_DIR}
# PRIVATE ${Kore_ROOT_DIR}
# PRIVATE ${POCO_LIBRARIES}
PRIVATE ssl
PRIVATE crypto
)

gcc compile time type resolution

I have three files, say A.c , B.c and C.c, all of which #include common.h
In common.h, I include "sys/socket.h" and I protect the common.h by macros:
#ifndef __COMMON_H
#define __COMMON_H
// body of file goes here
#endif
When i compile the code, I get several errors such as below
In file included from /usr/include/sys/socket.h:40,
from tcpperf.h:4,
from wrapunix.c:1:
/usr/include/bits/socket.h:425: error: conflicting types for 'recvmmsg'
/usr/include/bits/socket.h:425: note: previous declaration of 'recvmmsg' was here
In file included from /usr/include/sys/socket.h:40,
from tcpperf.h:4,
from wrapsock.c:1:
As you can see wrapunix.c and wrapsock.c, they both include tcpperf.h, but tcpperf.h is guarded with macros,yet gcc complains that recvmsg was declared multiple times. How do I resolve this issue?
Update:
Here is the header of tcpperf.h, that is causing issues
#ifndef _TCPPERF_H
#define _TCPPERF_H
#include <sys/types.h>
#include <sys/socket.h>
#include <time.h>
#include <regex.h>
#include <errno.h>
#include <sched.h>
#include <pthread.h>
#include <argp.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <linux/tcp.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <signal.h>
#include <sys/prctl.h>
#include <unistd.h>
#include <sys/wait.h>
#endif
The above error can be reproduced by providing "-combine -fwhole-program" flags to gcc such as
gcc -std=gnu99 -Wall -combine -fwhole-program -I. error.c wrapunix.c wrapsock.c file1.c file2.c -o file2 -lrt
The error is "conflicting types for 'recvmmsg'" rather than just duplicate definition (which would be tolerated if equal). That means your .c source receives two different version of recvmmsg: one by your direct tcpperf.h inclusion and another one by inclusion it via sys/socket.h. I believe you have another version of tcpperf.h elsewhere in inclusion path with different (perhaps older version) recvmmsg.
The problem is almost certainly related to -combine. This is a bit of a guess, but in looking at the definition of recvmmsg:
extern int recvmmsg (int __fd, struct mmsghdr *__vmessages,
unsigned int __vlen, int __flags,
__const struct timespec *__tmo);
note that it takes a struct mmsghdr as an argument. However, while this prototype is unconditional, struct mmsghdr is only defined if __USE_GNU is set:
#ifdef __USE_GNU
/* For `recvmmsg'. */
struct mmsghdr
{
struct msghdr msg_hdr; /* Actual message header. */
unsigned int msg_len; /* Number of received bytes for the entry. */
};
#endif
-combine is basically equivalent to concatenating all your files together and then compiling them. Is there any chance that between the text of wrapunix.c and wrapsock.c that GNU_SOURCE is being defined? If that happened, then the first definition of recvmmsg would use a definition of struct mmsghdr that was local to just the prototype, while the second definition would use the real struct. Those two definitions would then be incompatible, which would result in the error message that you got.

Resources