Symbol not found when linking library

I'm trying to link a library in a JNI project I have. I'm running into a strange bug where the console output tells me that there was a "symbol not found for x86 64 architecture". I'm kinda stumped on what could be going wrong. There are other classes but they're way too many to put here. Here's my code:

EDIT: I'll include the entire console debug log. It doesn't mention which symbol is the one in question.

EDIT 2: I fixed a static variable that was a problem, but it's still giving an error. Updated the code to reflect changes

Console Debug Log:

14:24:05 **** Build of configuration Debug for project HPA* Program ****
make all 
cc -v -c -stdlib=libstdc++ -fPIC -I/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/ HPAProgram.c++ -o libhpaprogram.o
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin13.0.0
Thread model: posix
 "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.9.0 -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name HPAProgram.c++ -mrelocation-model pic -pic-level 2 -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 224.1 -v -coverage-file "/Users/zalbhathena/Documents/workspace/Thesis-Test-Application/HPA* Program/jni/libhpaprogram.o" -resource-dir /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.0 -I /System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/ -stdlib=libstdc++ -fdeprecated-macro -fdebug-compilation-dir "/Users/zalbhathena/Documents/workspace/Thesis-Test-Application/HPA* Program/jni" -ferror-limit 19 -fmessage-length 0 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.9.0 -fobjc-dispatch-method=mixed -fobjc-default-synthesize-properties -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fdiagnostics-show-option -o libhpaprogram.o -x c++ HPAProgram.c++
clang -cc1 version 5.0 based upon LLVM 3.3svn default target x86_64-apple-darwin13.0.0
ignoring nonexistent directory "/usr/include/c++/4.2.1/i686-apple-darwin10/x86_64"
ignoring nonexistent directory "/usr/include/c++/4.0.0"
ignoring nonexistent directory "/usr/include/c++/4.0.0/i686-apple-darwin8/"
ignoring nonexistent directory "/usr/include/c++/4.0.0/backward"
ignoring nonexistent directory "/usr/local/include"
#include "..." search starts here:
#include <...> search starts here:
 /System/Library/Frameworks/JavaVM.framework/Versions/A/Headers
 /usr/include/c++/4.2.1
 /usr/include/c++/4.2.1/backward
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/5.0/include
 /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)
End of search list.
libtool -dynamic -lSystem libhpaprogram.o -o libhpaprogram.dylib
ld: warning: -macosx_version_min not specified, assuming 10.8
Undefined symbols for architecture x86_64:
  "__Z11create_dcdtv", referenced from:
      _Java_HPAProgram_sayHello in libhpaprogram.o
ld: symbol(s) not found for architecture x86_64
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/libtool: internal link edit command failed
make: *** [libhpaprogram.dylib] Error 1

14:24:05 Build Finished (took 162ms)

HPAProgram.c++

#include <stdio.h>
#include "HPAProgram.h"
#include "DCDTWrapper.h"

extern void create_dcdt();
JNIEXPORT void JNICALL Java_HPAProgram_sayHello (JNIEnv *env, jobject obj) {
   printf("Hello World!\n");
   create_dcdt();
}

DCDTWrapper.h

# include "DCDTsrc/se_dcdt.h"
# include "DCDTsrc/gs_polygon.h"
# include <stdlib.h>
void create_dcdt ();

DCDTWrapper.c++

# define END 12345.6
# define FIRST_EXAMPLE  Example1
//# include "DCDTsrc/se_dcdt.h"
//# include "DCDTsrc/gs_polygon.h"
//# include <stdlib.h>
# include "DCDTWrapper.h"

static double Example1[] =
       { -10, -10, 10, -10, 10, 10, -10, 10, END,
           1, 1, 7, 3, 3, 8, END,
         END };

static const double* CurExample = FIRST_EXAMPLE;
static SeDcdt *TheDcdt;
static GsPolygon CurPath;
static GsPolygon CurChannel;
static float CurX1=0, CurY1=0, CurX2=0, CurY2=0;
static int   CurSelection=0; // -2,-1: moving point, >0: moving polygon


void create_dcdt ()
 {
   const double* data = CurExample;
   GsPolygon pol;

   // domain:
   while ( *data!=END ) { pol.push().set((float)data[0],(float)data[1]); data+=2; }
   TheDcdt->init ( pol, 0.00001f );

   while ( *++data!=END )
    { pol.size(0);
      while ( *data!=END )  { pol.push().set((float)data[0],(float)data[1]); data+=2; }
      TheDcdt->insert_polygon ( pol );
    }
 }

makefile:

# Define a variable for classpath
CLASS_PATH = ../bin

# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)

all: libhpaprogram.dylib

# $@ matches the target, $< matches the first dependancy
libhpaprogram.dylib:
    cc -v -c -stdlib=libstdc++ -fPIC -I/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/ HPAProgram.c++ -o libhpaprogram.o
    libtool -dynamic -lSystem libhpaprogram.o -o libhpaprogram.dylib

HPAProgram.h : HPAProgram.class
    javah -classpath $(CLASS_PATH) $*

clean:
    rm HPAProgram.h libhpaprogram.o libhpaprogram.dylib

Answers


This is your problem:

static void create_dcdt ();

When you declare a global object static in a header file, every single translation unit (ie: cpp file) that includes it will want to create their own version of that object.

You probably want to qualify create_dcdt() with extern:

extern void create_dcdt();

Then in the file DCDTWrapper.c++ remove the static qualifier.

This will tell the compiler to allow all versions of the undefined object to be resolved at link time, to a single version that lives in one cpp file.

(the extern keyword is probably optional but you certainly do not want to use static here)


The second part of your problem is that you are not including the DCDTWrapper.c++ file in your build project.

Modify your makefile like this:

libhpaprogram.dylib:
    cc -v -c -stdlib=libstdc++ -fPIC -I/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/ HPAProgram.c++ -o libhpaprogram.o
    cc -v -c -stdlib=libstdc++ -fPIC -I/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/ DCDTWrapper.c++ -o DCDTWrapper.o 

    libtool -dynamic -lSystem libhpaprogram.o DCDTWrapper.o -o libhpaprogram.dylib

I fixed my problem, here's the updated makefile:

SRC=DCDTsrc
TGT=obj
INCLUDES=-IDCDTsrc DCDTWrapper.h SearchAlgorithms.h
FLAGS=-stdlib=libstdc++ -std=c++0x -D GS_SYSTEM_RAND_LIBS -lm -fPIC -I/System/Library/Frameworks/JavaVM.framework/Versions/A/Headers/ -v
SOURCES=$(wildcard $(SRC)/*.cpp) DCDTWrapper.cpp SearchAlgorithms.cpp
OBJS=$(addprefix $(TGT)/, $(notdir $(SOURCES:.cpp=.o)))
CC=g++

# Define a variable for classpath
CLASS_PATH = ../bin

# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)


$(TGT)/%.o: $(SRC)/%.cpp
    $(CC) $(FLAGS) -c $< -o $@

$(TGT)/%.o: %.cpp
    $(CC) $(FLAGS) -c $< -o $@

# $@ matches the target, $< matches the first dependancy
libsearchalgorithms.dylib: $(OBJS)
    libtool -lc -lstdc++ -ldl -macosx_version_min 10.9 -lm -dynamic -lSystem $(OBJS) -o libsearchalgorithms.dylib



SearchAlgorithms.h : SearchAlgorithms.class
    javah -classpath $(CLASS_PATH) $*

clean:
    rm -rf $(TGT)
    mkdir $(TGT)
    if [ -a SearchAlgorithms.h ] ; \
    then \
        rm SearchAlgorithms.h ; \
    fi;
    if [ -a libsearchalgorithms.o ] ; \
    then \
        rm libsearchalgorithms.o ; \
    fi;
    if [ -a libsearchalgorithms.dylib ] ; \
    then \
        rm libsearchalgorithms.dylib ; \
    fi;

all:clean SearchAlgorithms.h libsearchalgorithms.dylib

Need Your Help

How to let users display the files they have uploaded

php html file-upload database-design delete-file

I have code for uploading files that is working fine. When uploading the file to the database I grab the username of the uploader from another database. I also have a page where I desplay all the

How to set icon in main.xml by java code?

android

I want to change menu item icon when I touch menu item.