2016-04-22 4 views
0

Я пытаюсь построить i8086emu, который является кроссплатформенным эмулятором.Ошибка компиляции C: Неопределенные символы для архитектуры x86_64: «_stringAdd»

Я под Mac ` Я сделал, как сказал README.

Когда я бегу make команду после ./configure, я получил ошибку

Undefined symbols for architecture x86_64: 
    "_stringAdd", referenced from: 
     _i8086errorEx in i8086error.o 
     _i8086warningEx in i8086error.o 
     _i8086clearLog in i8086error.o 
ld: symbol(s) not found for architecture x86_64 
clang: error: linker command failed with exit code 1 (use -v to see invocation) 
make[2]: *** [devices/i8086vga.so] Error 1 
make[1]: *** [all] Error 2 
make: *** [all] Error 2 

Конечно, я гугле для решения. Однако я не получил никаких полезных ответов.

Кажется, я мог исправить это, изменив Makefile.

Может ли кто-нибудь дать мне подсказку?


EDIT

i8086util.c

/* i8086emu 
* Copyright (C) 2004 Joerg Mueller-Hipper, Robert Dinse, Fred Brodmueller, Christian Steineck 
* 
* This program is free software; you can redistribute it and/or modify 
* it under the terms of the GNU General Public License as published by 
* the Free Software Foundation; either version 2 of the License, or 
* (at your option) any later version. 
* 
* This program is distributed in the hope that it will be useful, 
* but WITHOUT ANY WARRANTY; without even the implied warranty of 
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
* GNU General Public License for more details. 
* 
* You should have received a copy of the GNU General Public License 
* along with this program; if not, write to the Free Software 
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 
*/ 

/****************************************************/ 
/* Autor: RD          */ 
/* Version: 1.0          */ 
/*             */ 
/* kleine Hilfsfunktionen         */ 
/*             */ 
/****************************************************/ 

#include <sys/time.h> 
#include <unistd.h> 
#include <stdarg.h> 
#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include "i8086proc.h" 
#include "i8086util.h" 
#include "i8086error.h" 


/* Autor: RD */ 
/* Liefert length bits ab bit pos aus b. */ 
/* Bsp: getBitSnipped(b, 5, 3) liefert */ 
/*  die bits die mit x markiert sind */ 
/*  Pos:    */ 
/*    |->      */ 
/*   00xxx000     */ 
/* 
unsigned char getBitSnipped(unsigned char b,unsigned char pos, unsigned char length) 
{ 
    unsigned char result; 
    result=b << (7-pos); 
    result=result >> (7-(length-1)); 
    return result; 
} 
*/ 

/* Verkettet s1 und s2 indem s1 um die Laenge von s2 */ 
/* erweitert wird. Gibt neues s1 zurueck.      */ 
char *stringAdd(char *s1, ...) 
{ 
    char *substr; 
    va_list vlist; /* variable Argumentliste vorbereiten */ 

    va_start(vlist, s1); /* variable Liste starten */ 

    for(;;) 
    { 
     substr=va_arg(vlist, char *); /* nächster Parameter */ 
     if(substr == NULL) break; /* NULL -> fertig! */ 
     //len=len+strlen(substr); /* neue Länge */ 
     //result = (char *)realloc(result, len); /* reservieren */ 
     //strcat(result, substr); /* Parameter anhängen */ 
     s1 = (char *)realloc(s1, strlen(s1)+strlen(substr)+1); /* reservieren */ 
     strcat(s1, substr); 
    } 
    va_end(vlist); 

    return s1; 
} 



/* Autor: RD */ 
/* vertauscht die oberen 8bit mit den unteren 8bit von i*/ 
/* 
unsigned short swapbytes(unsigned short i) //vertauscht die unteren 8 Bit mit den oberen 8 Bit eines Words 
{ 
    return (i<<8) | (i>>8); 
} 
*/ 
/*unsigned short joinBytes(unsigned char a,unsigned char b) //f?gt 2 bytes zu einem word zusammen, a high, b low 
{ 
    unsigned short res; 
    res=a; 
    res=res<<8; 
    res=res|b; 
} 
*/ 

/* JMH      */ 
/* sleep fuer Mikrosekunden */ 
void delay(long microsec) 
{ 
    struct timeval timeout; 

    timeout.tv_sec = microsec/1000000L; 
    timeout.tv_usec = microsec % 1000000L; 
    select(0, NULL, NULL, NULL, &timeout); 
} 

/* JMH                  */ 
/* Berechnet die Zeitdiff. zw 8086- und emu-Ausfuehrungsgeschwindigkeit  */ 
/* und setzt den emu gegebenenfalls in den sleep-modus bis die    */ 
/* Ausfuehrungsgeschwindigkeit wieder synchron sind.       */ 
/* clocks Takte die der 8086 benoetigen wuerde.        */ 
/* usedTime Zeit(micSec) die der emu fuer die Funktionen der Takte benoetigte */ 
void cmdWait(unsigned int clocks, unsigned long usedTime) 
{ 
    signed long procTime, waitTime; 

    procTime = clocks*i8068_TPI; /* Zeit die 8086 benoetigen wuerde*/ 
    waitTime = procTime-usedTime; /* Zeitdiff. zw emu und 8086 -> muss gewartet werden. */ 
    if (waitTime > 0)    /* emu war schneller als 8086 -> muss warten */ 
    { 
    //usleep(waitTime); 
    delay(waitTime); 
    } 
} 

/*copys the file src to file dest and creates file dest if it is not allready there*/ 
/*returns 1 if copy failed*/ 
/*returns 0 if copy was a success*/ 
int copyFile(char *src, char *dest) 
{ 
#define BUFFSIZE 1024 
int readblocks; 
FILE *infile,*outfile; 
void *buffer; 

    infile=fopen(src,"r"); //quelldatei oeffnen 
    if(infile==NULL) 
      return 1; 
    outfile=fopen(dest,"w"); //Zieldatei erstellen 
     buffer=malloc(BUFFSIZE*sizeof(char)); 

    if(outfile==NULL) 
     return 1; 
while(!feof(infile)) 
{ 
    readblocks=fread(buffer,sizeof(char),BUFFSIZE,infile); 
    fwrite(buffer,sizeof(char),readblocks,outfile); 
} 

free(buffer); 
fclose(infile); 
fclose(outfile); 
return 0; 
} 

Makefile.in

#@[email protected] 
#Compileroptionen 

SHELL = /bin/sh 
subdirs = @[email protected] 
top_srcdir = @[email protected] 
srcdir = @[email protected] 
prefix = @[email protected] 
exec_prefix = @[email protected] 
bindir = @[email protected] 
datadir = @[email protected]/@[email protected] 
pixdir = @[email protected]/share/pixmaps 
examplesdir = @[email protected]/@[email protected]/examples 
infodir = @[email protected]/@[email protected] 
libdir = @[email protected]/@[email protected] 
mandir = @[email protected] 
sysconfdir= @[email protected]/@[email protected] 
INSTALL=cp 

WIN32=`if [ "$(TERM)" = "cygwin" ]; then echo "-D _WIN32"; fi;` 
[email protected]@ 
CGUIFLGS=`if [ "$(TERM)" = "cygwin" ]; then echo "-mwindows"; fi;` 
CLIBS=`if [ "$(TERM)" != "cygwin" ]; then echo "-ldl"; fi;` 
EMUOBJ=i8086proc.o i8086error.o i8086datatrans.o i8086emufuncs.o i8086arithmetic.o i8086control.o i8086logic.o i8086util.o i8086controltrans.o i8086wrapper.o i8086messages.o i8086strings.o i8086config.o disasm/*.o i8086devices.o 
EMUSRC=*.c *.h disasm/*.c disasm/*.h emu.cfg rom.bin devices/*.c devices/*.h 
EMUEX=../asm/*.asm 
EMUINST=../configure Makefile.in ../config.guess ../install-sh ../mkinstalldirs 
EMUDOCS=../NEWS ../README ../AUTHORS ../ChangeLog ../COPYING 
DEVICES=devices/i8086pic.so devices/i8086pit.so devices/i8086sic.so devices/i8086beep.so devices/i8086vga.so 
[email protected]@ 


all: 
    if [ "@[email protected]" != "0" ]; then make i8086gui;else echo "GTK GUI is disabled - may be you lack of gtk!";fi; 
    if [ @[email protected] -eq 1 ]; then make i8086text;fi; 

i8086gui: ${DEVICES} i8086gui.o i8086gui_emufuncs.o i8086gui_error.o i8086gui_util.o i8086gui_paint.o ${EMUOBJ} 
    gcc ${CFLAGS} ${CGUIFLGS} -o i8086gui i8086gui.o i8086gui_emufuncs.o i8086gui_error.o i8086gui_util.o i8086gui_paint.o ${EMUOBJ} `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0` 
i8086text: i8086text.o ${EMUOBJ} ${DEVICES} 
    gcc ${CFLAGS} -o i8086text i8086text.o ${EMUOBJ} -lncurses ${CLIBS} 

i8086devices: i8086text ${DEVICES} 

#GUI 
i8086gui.o: i8086gui.c i8086gui.h 
    gcc ${CFLAGS} ${WIN32} -DPIXDIR=\"$(pixdir)\" -DVERSION_NUMBER=\"$(VERS)\" -D GTK_ENABLE_BROKEN -c i8086gui.c `pkg-config --cflags gtk+-2.0` 

i8086gui_emufuncs.o: i8086gui_emufuncs.c i8086gui_emufuncs.h 
    gcc ${CFLAGS} -c i8086gui_emufuncs.c `pkg-config --cflags gtk+-2.0` 

i8086gui_error.o: i8086gui_error.c i8086gui_error.h 
    gcc ${CFLAGS} -c i8086gui_error.c `pkg-config --cflags gtk+-2.0` 

i8086gui_util.o: i8086gui_util.c i8086gui_util.h 
    gcc ${CFLAGS} ${WIN32} -D GTK_ENABLE_BROKEN -c i8086gui_util.c `pkg-config --cflags gtk+-2.0` 

i8086gui_paint.o: i8086gui_paint.c i8086gui_paint.h 
    gcc ${CFLAGS} -DPIXDIR=\"$(pixdir)\" -DVERSION_NUMBER=\"$(VERS)\" -D GTK_ENABLE_BROKEN -c ${WIN32} i8086gui_paint.c `pkg-config --cflags gtk+-2.0` 

#GUI-END 

#EMU 

i8086text.o: i8086text.c 
    gcc ${CFLAGS} -DVERSION_NUMBER=\"$(VERS)\" -c i8086text.c 

i8086proc.o: i8086proc.c i8086proc.h 
    gcc ${CFLAGS} -DVERSION_NUMBER=\"$(VERS)\" -c i8086proc.c 

i8086error.o: i8086error.c 
    gcc ${CFLAGS} ${WIN32} -c i8086error.c 

i8086datatrans.o: i8086datatrans.c 
    gcc ${CFLAGS} -c i8086datatrans.c 

i8086emufuncs.o: i8086emufuncs.c 
    gcc ${CFLAGS} -c i8086emufuncs.c 

i8086arithmetic.o: i8086arithmetic.c 
    gcc ${CFLAGS} -c i8086arithmetic.c 

i8086control.o: i8086control.c 
    gcc ${CFLAGS} -c i8086control.c 

i8086logic.o: i8086logic.c 
    gcc ${CFLAGS} -c i8086logic.c 

i8086util.o: i8086util.c 
    gcc ${CFLAGS} -c i8086util.c 

i8086controltrans.o: i8086controltrans.c 
    gcc ${CFLAGS} -c i8086controltrans.c 

i8086wrapper.o: i8086wrapper.c 
    gcc ${CFLAGS} -c i8086wrapper.c 

i8086messages.o: i8086messages.c i8086messages.h 
    gcc ${CFLAGS} ${WIN32} -c i8086messages.c 

i8086strings.o: i8086strings.c i8086strings.h 
    gcc ${CFLAGS} -c i8086strings.c 

disasm/*.o: disasm/disasm.c disasm/insnsa.c disasm/insnsd.c disasm/regs.c disasm/regvals.c disasm/sync.c 
    gcc ${CFLAGS} -c disasm/disasm.c -o disasm/disasm.o 
    gcc ${CFLAGS} -c disasm/insnsa.c -o disasm/insnsa.o 
    gcc ${CFLAGS} -c disasm/insnsd.c -o disasm/insnsd.o 
    gcc ${CFLAGS} -c disasm/regs.c -o disasm/regs.o 
    gcc ${CFLAGS} -c disasm/regvals.c -o disasm/regvals.o 
    gcc ${CFLAGS} -c disasm/sync.c -o disasm/sync.o 

i8086config.o: i8086config.c i8086config.h 
    gcc ${CFLAGS} ${WIN32} -DDATADIR=\"$(DESTDIR)$(sysconfdir)\" -c i8086config.c 

i8086devices.o: i8086devices.c i8086devices.h 
    gcc ${CFLAGS} -c -DVERSION_NUMBER=\"$(VERS)\" i8086devices.c 

#Devices 
devices/i8086pic.so: devices/i8086pic.c devices/i8086pic.h i8086error.o i8086messages.o i8086util.o 
    gcc ${CFLAGS} -shared -fPIC devices/i8086pic.c i8086error.o i8086messages.o i8086util.o -o devices/i8086pic.so 

devices/i8086pit.so: devices/i8086pit.c devices/i8086pit.h i8086error.o i8086messages.o i8086util.o 
    gcc ${CFLAGS} -shared -fPIC devices/i8086pit.c i8086error.o i8086messages.o i8086util.o -o devices/i8086pit.so -lpthread 

devices/i8086beep.so: devices/i8086beep.c i8086error.o i8086messages.o i8086util.o 
    gcc ${CFLAGS} ${WIN32} -shared -fPIC devices/i8086beep.c i8086error.o i8086messages.o i8086util.o -o devices/i8086beep.so 

devices/i8086sic.so: devices/i8086sic.c i8086error.o i8086messages.o i8086util.o 
    if [ "@[email protected]" != "0" ]; then gcc ${CFLAGS} ${WIN32} -shared -fPIC devices/i8086sic.c i8086error.o i8086messages.o i8086util.o -o devices/i8086sic.so `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`;fi; 

devices/i8086vga.so: devices/i8086vga.c i8086error.o i8086messages.o i8086util.o 
    if [ 1 -eq 1 ]; then gcc ${CFLAGS} ${WIN32} -shared -fPIC devices/i8086vga.c i8086error.o i8086messages.o i8086util.o -o devices/i8086vga.so -lpthread `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`;fi; 
#Devices-End 



examples: 
    nasm examples/clockmem.asm 
    nasm examples/kitt.asm 
    nasm examples/beep.asm 

check: 
    echo "This is not implemented right now!" 

clean: 
    rm -f *.o devices/*.so disasm/*.o i8086text i8086gui 
cleangui: 
    rm -f i8086gui*.o i8086gui 

distclean: clean 
    /bin/rm -f Makefile config.h config.status config.cache config.log 
#@for dir in ${subdirs}; do \ 
# (cd $$dir && $(MAKE) distclean) \ 
# || case "$(MFLAGS)" in *k*) fail=yes;; *) exit 1;; esac; \ 
#done && test -z "$$fail" 



install:all 
    $(top_srcdir)/mkinstalldirs $(DESTDIR)$(bindir) 
    $(top_srcdir)/mkinstalldirs $(DESTDIR)$(devicesdir) 
    $(top_srcdir)/mkinstalldirs $(DESTDIR)$(examplesdir) 
    $(top_srcdir)/mkinstalldirs $(DESTDIR)$(pixdir) 
    $(top_srcdir)/mkinstalldirs $(DESTDIR)$(infodir) 
    $(top_srcdir)/mkinstalldirs $(DESTDIR)$(libdir) 
    $(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir) 
    $(top_srcdir)/mkinstalldirs $(DESTDIR)$(sysconfdir) 
    $(INSTALL) i8086text $(DESTDIR)$(bindir) 
    if [ "@[email protected]" != "0" ]; then $(INSTALL) i8086gui $(DESTDIR)$(bindir);fi; 
    $(INSTALL) emu.cfg $(DESTDIR)$(sysconfdir)/emu.cfg.example 
    $(INSTALL) rom.bin $(DESTDIR)$(datadir) 
    $(INSTALL) core.dmp $(DESTDIR)$(datadir) 
    $(INSTALL) i8086icon.png $(DESTDIR)$(pixdir) 
    $(INSTALL) devices/*.so $(DESTDIR)$(libdir) 
    $(INSTALL) $(EMUEX) $(DESTDIR)$(examplesdir) 
    $(INSTALL) $(EMUDOCS) $(DESTDIR)$(infodir)$ 

uninstall: 
    if [ "@[email protected]" != "0" ]; then /bin/rm -f $(DESTDIR)$(bindir)/i8086gui;fi; 
    -/bin/rm -f $(DESTDIR)$(bindir)/i8086text 
    -/bin/rm -f $(DESTDIR)$(sysconfdir)/emu.cfg.example 
    -/bin/rm -f $(DESTDIR)$(datadir)/emu.log 
    -/bin/rm -f $(DESTDIR)$(datadir)/rom.bin 
    -/bin/rm -f $(DESTDIR)$(datadir)/core.dmp 
    -/bin/rm -f $(DESTDIR)$(pixdir)/i8086icon.png 
    -/bin/rm -f $(DESTDIR)$(libdir)/i8086*.so 
    -/bin/rm -f $(DESTDIR)$(examplesdir)/* 
    -/bin/rm -f $(DESTDIR)$(infodir)/README 
    -/bin/rm -f $(DESTDIR)$(infodir)/AUTHORS 
    -/bin/rm -f $(DESTDIR)$(infodir)/ChangeLog 
    -/bin/rm -f $(DESTDIR)$(infodir)/NEWS 
    -/bin/rm -f $(DESTDIR)$(infodir)/COPYING 
    -/bin/rmdir $(DESTDIR)$(bindir) 
    -/bin/rmdir $(DESTDIR)$(devicesdir) 
    -/bin/rmdir $(DESTDIR)$(examplesdir) 
    -/bin/rmdir $(DESTDIR)$(pixdir) 
    -/bin/rmdir $(DESTDIR)$(infodir) 
    -/bin/rmdir $(DESTDIR)$(datadir) 
    -/bin/rmdir $(DESTDIR)$(sysconfdir) 
    -/bin/rmdir $(DESTDIR)$(libdir) 
+0

линкер не может найти функцию , узнать, к какой библиотеке принадлежит функция '_stringAdd'? добавьте эту библиотеку в компоновщик. – fluter

+0

Прошу прощения. Не могли бы вы указать немного больше? Я новичок в создании системы, и я всегда использую IDE для запуска своих проектов. Что означает «добавить библиотеку в компоновщик»? –

+0

Хорошо, забудьте о компоновщике сейчас, сначала вы узнаете, где находится функция? – fluter

ответ

1

В Makefile.in ошибка могла быть сделана:

линия 130-131, это писатель n:

devices/i8086vga.so: devices/i8086vga.c i8086error.o i8086messages.o 
    if [ 1 -eq 1 ]; then gcc ${CFLAGS} ${WIN32} -shared -fPIC devices/i8086vga.c i8086error.o i8086messages.o -o devices/i8086vga.so -lpthread `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`;fi; 

Я думаю, что i8086util.o отсутствует. Попробуйте заменить (i8086util.o появляется в две строки):

devices/i8086vga.so: devices/i8086vga.c i8086error.o i8086messages.o i8086util.o 
    if [ 1 -eq 1 ]; then gcc ${CFLAGS} ${WIN32} -shared -fPIC devices/i8086vga.c i8086error.o i8086messages.o i8086util.o -o devices/i8086vga.so -lpthread `pkg-config --cflags gtk+-2.0` `pkg-config --libs gtk+-2.0`;fi; 

Редактировать

После того, как вы сделали это, повторно запустить ./configure, а затем сделать

+0

Я редактировал вопрос. После изменения 'Makefile.in', все еще есть та же ошибка. В 'i8086util.c' есть метод' stringAdd', но не '_stringAdd'. Это точка? –

+0

На самом деле функция с именем 'stringAdd' будет оформлена в' _stringAdd', мы говорим о той же функции (см. [Обозначение имени] (https://en.wikipedia.org/wiki/Name_mangling)). Вы повторно запускали скрипт './Configure'? – purplepsycho

+0

Удивительный! Теперь он может быть построен успешно! –

Смежные вопросы