Xubuntu - AVR32-linux crosscompile sqlite

N

n1k0

Gast
Xubuntu - AVR32-linux crosscompile sqlite (SOLVED)

Hallo zusammen,

ich stehe vor einem seltsamen Problem. Zunächst ein paar Informationen:

System A Linux avr32devel 2.6.24-25-generic #1 SMP Tue Oct 20 07:31:10 UTC 2009 i686 GNU/Linux + buildroot toolchain für avr32-linux

System B Linux ngw.example.net 2.6.18-atngw #1 Fri Apr 27 13:45:58 CEST 2007 avr32 unknown

So nun zum eigentlichen Problem: ich will sqlite auf dem xubuntu-Rechner kompilieren und auf dem avr-32-linux Board zum laufen bekommen. Das hat bis jetzt auch geklappt. Angestellt habe ich das mit folgenden Befehlen (im sqlite3 Source Ordner):

./configure --host=avr32-linux --prefix=/home/niko/ngw100/sqlite3/dist
make
make install


Als resultat bekomme ich im ....sqlite/dist/ - Ordner folgende Verzeichnisse:
drwxr-xr-x 2 niko niko 4096 2009-10-29 18:04 bin
drwxr-xr-x 2 niko niko 4096 2009-10-29 18:04 include
drwxr-xr-x 3 niko niko 4096 2009-10-29 18:04 lib


Jetzt bin ich auf der avr32-linux-Maschine!

Die sqlite3-binary läuft nur wenn in /usr/lib auch die libsqlite3.so /.so.0 lib drinnen ist. Auch gut! sqlite3 läuf also bestens auf dem Zielsystem!

Nun das Problem - Es gibt eine Möglichkeit sich eigens ein Programm zu schreiben, welches die Funktionalität der sqlite3 Shared-lib verwendet. D.h. man muss in seinem c-Code nicht dauernd system("sqlite...bla..blubb"); aufrufen sondern kann mit sqlite3_open("db-file") sqlite3_exec(...) und vielen weiteren Funktionen im Programm arbeiten.

Beispielcode von der sqlite-Seite (sqlite.org) - Der Code muss nicht verstanden werden, es geht nur ums Prinzip!
Code:
#include <stdio.h>
#include <sqlite3.h>
#include <stdlib.h>

static int callback(void *NotUsed, int argc, char **argv, char **azColName){
  int i;
  for(i=0; i<argc; i++){
    printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
  }
  printf("\n");
  return 0;
}

int main(int argc, char **argv){
  sqlite3 *db;
  char *zErrMsg = 0;
  int rc;

  if( argc!=3 ){
    fprintf(stderr, "Usage: %s DATABASE SQL-STATEMENT\n", argv[0]);
    exit(1);
  }
  rc = sqlite3_open(argv[1], &db);
  if( rc ){
    fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db));
    sqlite3_close(db);
    exit(1);
  }
  rc = sqlite3_exec(db, argv[2], callback, 0, &zErrMsg);
  if( rc!=SQLITE_OK ){
    fprintf(stderr, "SQL error: %s\n", zErrMsg);
    sqlite3_free(zErrMsg);
  }
  sqlite3_close(db);
  return 0;
}

Jetzt befinde ich mich wieder auf der xubuntu =)
Das funktioniert wie gewünscht, wenn ich es für meine xubuntu-maschine erstelle.

gcc -o main main.c -lsqlite3 (lib aus /usr/local/lib)

Vorgang ohne Fehler und die binary funktioniert auch

avr32-linux-gcc -o main main.c -lsqlite3 (lib aus der toolchain, welche ich zuvor für avr32 erstellt habe)
....c/lib/libsqlite3.so: warning: the use of LEGACY `utimes' is discouraged, use `utime'

"Nur" ein warning... die binary auf die avr32-Maschine geschoben

Achtung: bin wieder auf AVR32

./main bricht wärend sqlite3_open ab und das tolle ist, der returncode ist 0

Was ich definitiv weiß: die vorher erstellte sqlite3 für avr32 greift auch wie das eigene Programm auf die selbe lib (libsqlite3.so) zu! Warum stirbt das eigene Programm mitten zur Laufzeit nachdem es wenigstens die Datenbankdatei angelegt hat(war leer) und gibt mir ein return 0 zurück (echo $?)?

Darauf dachte ich: Hah, dann lade ich die lib und funktionen selber zur Laufzeit:

Code:
#include <stdio.h>
#include <sqlite3.h>
#include <stdlib.h>
#include <dlfcn.h>

#define LIBSQLITE "libsqlite3.so"
#define DB_FILE "test.db"

//*****************DYNAMIC LOAD ROUTINES*************************************


// Load the desired library
static void *load_lib(const char *lib)
{
	static void *handle;
	handle = dlopen (LIBSQLITE, RTLD_NOW);
	if(handle == NULL){
		printf("error at dlopen(): %s\n",dlerror());
		exit(EXIT_FAILURE);
	}

	return handle;

}


// Loads the desired function
static void *load_func(void *handle, const char *func)
{
	void *funcptr = dlsym(handle, func);
	if(funcptr == NULL){
		printf("error at dlsym(): %s\n",dlerror());
		exit(EXIT_FAILURE);
	}

	return funcptr;

}

// Unloads / frees the library
static void close_func(void *handle)
{
	if(dlclose(handle))
		printf("error at dlclose(): %s\n",dlerror());	
}

//*****************DYNAMIC LOAD ROUTINES END***********************************


// Callbackfunction for sqlite
static int callback(void *NotUsed, int argc, char **argv, char **azColName){
  int i;
  for(i=0; i<argc; i++){
    printf("%s = %s\n", azColName[i], argv[i] ? argv[i] : "NULL");
  }
  printf("\n");
  return 0;
}




int main(int argc, char* argv[])
{
	// define libraryhandle
	void *lib_handle;

	// Functionpointers for some sqlite functions
	int (*db_open) (const char *filename, sqlite3 **ppDb );
	int (*db_exec) (sqlite3*, const char *sql, int (*callback)(void*,int,char**,char**), void *, char **errmsg);
	int (*db_close) (sqlite3*);


	char *zErrMsg = 0;
	sqlite3 * db;

	// Load libsqlite3.so
	lib_handle = load_lib(LIBSQLITE);

	// catch some sqlite functions
	db_open = load_func(lib_handle, "sqlite3_open");
	db_exec = load_func(lib_handle, "sqlite3_exec");
	db_close = load_func(lib_handle, "sqlite3_close");

	
printf("open...\n");	

	db_open(DB_FILE,&db);

printf("..fin!\n");

	db_exec (db, "CREATE TABLE tbl1(arr varchar(10))", callback, 0, &zErrMsg);

	db_exec (db, "INSERT INTO tbl1 VALUES('hehe')", callback, 0, &zErrMsg);

	db_exec (db, "SELECT * FROM tbl1", callback, 0, &zErrMsg);

	db_close(db);

	printf("hello world!\n");

	close_func(lib_handle);
	
	return 0;
}

...machte keinen Unterschied zum vorherigen Vorgehen, außer, dass das warning weg war (ist ja klar!)

Falls jemand etwas damit anfangen kann würde ich mich sehr über Hilfe freuen. Wenn allgemeine Fragen zu dem AVR32-linux Thema bestehen, bin ich natürlich auch bereit zu helfen.

Grüße n1k0
.
.
.
EDIT (autom. Beitragszusammenführung) :
.

OK hat sich erledigt! Mir ist noch eine Möglichkeit eingefallen, wie man das Ganze kompilieren kann:

Nicht dynamisch! -> statisch

avr32-linux-gcc main.c sqlite3.o -o main -ldl -lpthread
sqlite3.o: In function `dotlockLock':
/home/niko/Desktop/sqlite-3.6.19/sqlite3.c:12385: warning: the use of LEGACY `utimes' is discouraged, use `utime'


Zwar wieder ein warning aber das Kompilat lässt sich auf dem Zielsystem ausführen. Unterschied: dynamisch ist die main nur 6kB groß statisch jedoch 1.2 MB.

Die sqlite.o habe ich aus dem sqlite-Sourceverzeichnis, in welchem ich das Ganze für die AVR32-linux-Architektur kompiliert habe.


Dennoch: Wer weiß wie man das dynamisch schafft, kann sich weiterhin gerne melden. Das Thema ist ja nur zur hälfte durch *g


Grüße n1k0


.
EDIT:



Endgültige Lösung (wie banal *tock*) avr32-linux-gcc -o main main.c -lsqlite3 -ldl -lpthread er hat nicht gemotzt als es ohne -ldl -lpthread war...funktionieren tuts aber definitiv mit =)

Ich hab bevor ich hier gepostet habe wirklich viel gesucht und probiert... kaum gepostet, hats nahezu von allein geklappt.:rofl:

Also Zusammengefasst:

dynamisch: (libabhängig aber klein)
1. avr32-linux-gcc -o main main.c -lsqlite3 -ldl -lpthread (Standard) 5.5kB
2. avr32-linux-gcc -o main main_extload.c -ldl -lpthread (die Funktionspointer Version) 6.3kB

statisch: (libunabhängig aber groß)
avr32-linux-gcc -o main main.c sqlite3.o -ldl -lpthread 1.2MB


SOLVED! *Bier aufmach*

Grüße n1k0 :D
 
Zuletzt bearbeitet von einem Moderator:

bytepool

Code Monkey
Beiträge
791
Hi,

willkommen im Board. :)

Noch eine kurze Anmerkung, wenn du mit source code hantierst, solltest du am besten die
Code:
 tags benutzen, das macht deinen Post deutlich lesbarer (und erhoeht damit deine Chancen auf eine sinnvolle Antwort).

mfg,
bytepool
 

Ähnliche Themen

Unix Webserver mit HTML Seite erstellen

String auf Konsole ausgeben

Ausführbare C-Datei von Mac OS auf Embedded Linux ausführen

GCC liefert in Eclipse Kompilierfehler

Aufgabe in C

Oben