can't compile c program that uses openssl libraries - c

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
)

Related

Getting GCC error: "sys/memfd.h: No such file or directory"

I'm trying to use the memfd_create syscall in my C code. I tried to include sys/memfd.h as the man page for memfd_create says is appropriate, but GCC gives me an error "sys/memfd: No such file or directory".
I've tried Googling around and couldn't find anyone having the same problem. I noticed some versions of the manpage for memfd_create say that I should include sys/mman.h, but it didn't seem to help when I tried it. It would say memfd_create was implicitly declared.
Here is a minimal reproduction of my problem.
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/memfd.h>
int main(){
int fd;
fd = memfd_create("test", MFD_CLOEXEC);
return 0;
}
I expect the above code to compile and run without error.
On older systems, you'll have to include linux/memfd.h for the MFD_ defines, and call memfd_create() via the the syscall(2) wrapper (and include unistd.h and sys/syscall.h for it work).
#define _GNU_SOURCE
#include <unistd.h>
#include <sys/syscall.h>
#include <linux/memfd.h>
#include <err.h>
int main(void){
int fd;
if((fd = syscall(SYS_memfd_create, "test", MFD_CLOEXEC)) == -1)
err(1, "memfd_create");
return 0;
}
The Ubuntu man-pages in Bionic (18.04) are not up to date with this API (including its implementation in Bionic).
The Focal man-page correctly shows how to include memfd_create(). It says:
#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sys/mman.h>
So you only need to include <sys/mman.h>, and you need to build with -D_GNU_SOURCE in your compiler flags. Or, do as the man page says and literally #define _GNU_SOURCE before including the header. However, I recommend just compiling with -D_GNU_SOURCE instead.

Compiling C with non standard header

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

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.

Trouble with header file

I got the following error on compiling a c code I wrote. I understand that the problem is in the header file. Can anyone please tell me which all header files are needed to define these functions.
sign.c: In function ‘main’:
sign.c:78: warning: assignment makes pointer from integer without a cast
/tmp/ccnsSeHy.o: In function `sign_data_evp':
sign.c:(.text+0x68): undefined reference to `check_ssl_rv'
sign.c:(.text+0xd5): undefined reference to `check_ssl_rv'
sign.c:(.text+0x13e): undefined reference to `check_ssl_rv'
/tmp/ccnsSeHy.o: In function `main':
sign.c:(.text+0x1ca): undefined reference to `initialize'
sign.c:(.text+0x1d6): undefined reference to `select_engine'
sign.c:(.text+0x20a): undefined reference to `sign_data'
sign.c:(.text+0x216): undefined reference to `clean_engine'
sign.c:(.text+0x21b): undefined reference to `clean_up'
collect2: ld returned 1 exit status
The header files that I have used so far is:
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <netdb.h>
#include <unistd.h>
#ifdef __VMS
#include <socket.h>
#include <inet.h>
#include <in.h>
#else
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#include <openssl/crypto.h>
#include <openssl/ssl.h>
#include <openssl/err.h>
Operating platform: Linux
Thanks in advance.
You understand it wrong. It does not complain about unknown function prototype, it complains during the linking. So you probably forgot to link with some library or some object file.
try with this
gcc sslprogname.c -o sslprogname -Wl,-Bstatic -lssl -Wl,-Bdynamic -lssl3 -lcrypto.It worked for me

popen implicitly declared even though #include <stdio.h> is added

This is tiny snippet of my code.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
...
FILE * pipe;
...
pipe = popen ("ls /tmp -1", "r");
...
pclose(pipe);
blarg.c:106: warning: implicit declaration of function ‘popen’
blarg.c:106: warning: assignment makes pointer from integer without a cast
blarg.c:112: warning: implicit declaration of function ‘pclose’
blarg.c:118: warning: assignment makes pointer from integer without a cast
I'm really unsure. I looked up popen and all it requires is stdio.h which is provided. What is missing, or is the problem in the rest of my code (I don't really want to show more code because its an a assignment).
As the man page says:
Feature Test Macro Requirements for glibc (see feature_test_macros(7)):
popen(), pclose(): _POSIX_C_SOURCE >= 2 || _XOPEN_SOURCE || _BSD_SOURCE
|| _SVID_SOURCE
So you should #define _BSD_SOURCE or one of the others before #includeing stdio.h.
Replace -std=c99 or -std=c11 etc with -std=gnu99 or -std=gnu11.
I put the prototypes of popen and pclose at the top of my code. It seemed to have settled the problem.

Resources