-1

I have a C project in Eclipse (Neon) on Ubuntu 15.10. I have downloaded the OpenSSL library.

I have included openssl/bn.h in my preprocessor directives. In my main.c file, I can refer to BN_new(), a function in bn.h:

bn.h

However, when I try to compile, I get an undefined reference for all calls into bn.h (BN_new(), BN_free(), etc).

BN_new undefined

As a side note, I copied the contents of openssl-1.0.2h/include/openssl to my /usr/include/ directory.

Why is this error happening at compile time?

my code:

#include <stdio.h>
#include "jpake.h"
#include <openssl/crypto.h>
#include <openssl/sha.h>
#include <openssl/err.h>
#include <openssl/bn.h>
#include <memory.h>

/*
 * In the definition, (xa, xb, xc, xd) are Alice's (x1, x2, x3, x4) or    
 * Bob's (x3, x4, x1, x2). If you see what I mean.
 */
typedef struct
{
char *name;  /* Must be unique */
char *peer_name;
BIGNUM *p;
BIGNUM *g;
BIGNUM *q;
BIGNUM *gxc; /* Alice's g^{x3} or Bob's g^{x1} */
BIGNUM *gxd; /* Alice's g^{x4} or Bob's g^{x2} */
} JPAKE_CTX_PUBLIC;


struct JPAKE_CTX
{
 JPAKE_CTX_PUBLIC p;
 BIGNUM *secret;   /* The shared secret */
 BN_CTX *ctx;
 BIGNUM *xa;       /* Alice's x1 or Bob's x3 */
 BIGNUM *xb;       /* Alice's x2 or Bob's x4 */
 BIGNUM *key;      /* The calculated (shared) key */
 };

static void JPAKE_ZKP_init(JPAKE_ZKP *zkp)
{
zkp->gr = BN_new();
zkp->b = BN_new();
}

static void JPAKE_ZKP_release(JPAKE_ZKP *zkp)
{
BN_free(zkp->b);
BN_free(zkp->gr);
}

typedef struct
{
const char *name;   //must be unique
int base;           //1 for Alice, 3 for Bob. Only used for printing stuff


}JPakeUserPublic;


typedef struct
{
JPakeUserPublic p;
BIGNUM *secret; //the shared secret
BIGNUM *key;    //the calculated (shared) key
BIGNUM *xa;     //ALice's x1 or Bob's x3
BIGNUM *xb;     //ALice's x2 or Bob's x4

}JPakeUser;

int main(int argc, char **argv)
{
JPakeUser alice, bob;
alice.p.name = "Alice";
alice.p.base = 1;
bob.p.name = "Bob";
bob.p.base = 3;

puts(alice.p.name);
}

I am not a new developer but I AM new to C and eclipse so I have been battling this for awhile. I have been experimenting with the makefile for this project also. Here is my makefile (it is modified from a C++ example):

all: hash4.exe

clean:
    rm jpakedemo.o hash4.exe

hash4.exe: jpakedemo.c
    gcc -g -o hash4 jpakedemo.c

jpakedemo.o:
    gcc -c -g jpakedemo.c
learningtofly
  • 353
  • 1
  • 2
  • 13
  • 3
    Please do not post links to images; post the code! – Jonathan Leffler Aug 10 '16 at 02:43
  • 2
    A function is *declared* in a header file, but it is *defined* in `.c`, `.o` (`.obj`), `.a` (`.lib`) or `.so` (`.dll`) files. If you only copied the *include* directory, you have the function *declared*, but not *defined*. – Amadan Aug 10 '16 at 02:44
  • 1
    You should post the command you're using to link the files. Are you including the correct library when you run the linker? The compilation to object file appears to be working OK; it is the linking that is failing. – Jonathan Leffler Aug 10 '16 at 02:44
  • Possible duplicate of [What is an undefined reference/unresolved external symbol error and how do I fix it?](http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix) – user253751 Aug 10 '16 at 02:45
  • I have edited the post to add my code – learningtofly Aug 10 '16 at 03:01

1 Answers1

1

The purpose of a .h header file is to describe what a particular function "looks like," so that correct code can be generated to make a call to that function.

But this, by itself, does not provide the function itself!

The final process of "linking all of the various compiler-outputs and libraries into 'a complete thing that can actually be run'" is performed by a separate program altogether ... which, appropriately enough, is called a "linker."

The subroutines that you refer-to could come from several places:   from another, separately-compiled, source program, or from a library. (If from a library, that library might be "statically" or "dynamically" linked.) Nevertheless, somehow, the necessary object-code must be found, so that they can be incorporated into the final executable.

OpenSSL subroutines, undoubtedly, come from a library (that is part of OpenSSL). Therefore, your Eclipse project probably does not presently contain a reference to that library, so that it can be found when needed.

Mike Robinson
  • 8,490
  • 5
  • 28
  • 41
  • Thank you for this answer. I added libssl.a and libcrypto.a to my sourcecode directory and then to my makefile and it compiled correctly. I am new to C and eclipse so this answer was written in a manner I was able to understand. – learningtofly Aug 10 '16 at 03:14
  • Yes, and it would be more-correct to say that "it **linked** correctly." You see, the `gcc` command *(et al)* ordinarily does both: it compiles the files (to produce `.a` files containing object-code), then it *links* everything to produce a single, (fairly ...) self-contained file: "an executable." Two distinct operations are therefore performed, but unobtrusively. (Eclipse hides details even more.) By adding these two (so-called "static," *vs*. "dynamic" ...) libraries to the mix, you enabled the linker to successfully find all of the assets that it needed. – Mike Robinson Aug 10 '16 at 14:42