Forum: PC-Programmierung Linke problem bei Cmake


von Kano (Gast)


Lesenswert?

Hallo zusammen,

ich möchte eine c -Library in mein c++ Proramm verwenden aber
ich habe eine Problem mit dem Linken von s SHARED_LIBS per Cmake :

Hier ist mein cmakeLists.txt:
1
cmake_minimum_required(VERSION 2.8)
2
3
SET(PNAME cprogram)
4
PROJECT(${PNAME})
5
6
include_directories (/usr/local/SGPx/include)
7
8
SET(SRCS prog.c)
9
ADD_EXECUTABLE(${PNAME} ${SRCS})
10
link_directories(usr/local/SGPx/lib)

 I n Verzeichnis inculde befnidet sich die Headerdatei sgp.h und lib ist
die object files libsgp.a  libsgp.so
hier ist die Meldung:
1
 
2
Scanning dependencies of target cprogram
3
[100%] Building C object CMakeFiles/cprogram.dir/prog.c.o
4
Linking C executable cprogram
5
CMakeFiles/cprogram.dir/prog.c.o: In function `spp_test':
6
prog.c:(.text+0x2f4): undefined reference to `Conver_Data'
7
prog.c:(.text+0x379): undefined reference to `sffcall'
8
prog.c:(.text+0x3b8): undefined reference to `smmp'
9
prog.c:(.text+0x3f7): undefined reference to `dd4'

kann mir da jamend weiterhelfen und zeigt wie ich die Library 
includieren und linken kann.

Danke schönmal im voraus.
kano

PS :
wenn ich das Programm mit gcc in Terminal compiliere, meldet keine 
fehler und zwar so:
1
/cprog$ gcc prog.c -L/home/marx/program/cprog/sgplib -lsgplib

von Rooney (Gast)


Lesenswert?

Du musst die zu linkenden Libraries auch benennen:

target_link_libraries(${PNAME} sgplib)

link_directories(...) setzt nur die Verzeichnisse, in denen der Linker 
nach zu linkenden Dependencies sucht.

RSp

von Rene H. (Gast)


Lesenswert?

1
add_executable(${PNAME})
2
target_link_libraries(${PNAME}
3
   sglib
4
   )

Grüsse,
René

von Kano (Gast)


Lesenswert?

habe es probiert aber er meldet jetzt Complier fehler:
1
Linking C executable cprogram
2
/usr/bin/ld: cannot find -lsgplib
3
collect2: error: ld returned 1 exit status
4
make[2]: *** [cprogram] Fehler 1
5
make[1]: *** [CMakeFiles/cprogram.dir/all] Fehler 2

von Kano (Gast)


Lesenswert?

ich habe die Cmakelists.txt geändert wie ihr vorgeschlagen habt, aber 
jetzt findet die Complieler die Lib nicht mehr:
1
cmake_minimum_required(VERSION 2.8)
2
3
SET(PNAME cprogram)
4
PROJECT(${PNAME})
5
6
include_directories (/usr/local/SGPx/include)
7
8
SET(SRCS prog.c)
9
10
add_executable(${PNAME} ${SRCS})
11
target_link_libraries(${PNAME} sgplib)

Compieler Meldung:
1
/cprog/build$ make
2
Scanning dependencies of target cprogram
3
[100%] Building C object CMakeFiles/cprogram.dir/prog.c.o
4
Linking C executable cprogram
5
/usr/bin/ld: cannot find -lsgplib
6
collect2: error: ld returned 1 exit status
7
make[2]: *** [cprogram] Fehler 1
8
make[1]: *** [CMakeFiles/cprogram.dir/all] Fehler 2
9
make: *** [all] Fehler 2

von Rene H. (Gast)


Lesenswert?

Du musst natürlich schon den Pfad angeben:
1
link_directories(/usr/local/SGPx/lib)

Mein vorheriges Post war als Ergänzung gedacht :-)

Grüsse,
René

von Kano (Gast)


Lesenswert?

Hallo Rene,

habe ich auch ausprobiert und  meldet immer noch die gleich fehler:

[code]
cmake_minimum_required(VERSION 2.8)

SET(PNAME cprogram)
PROJECT(${PNAME})

include_directories (/usr/local/SGPx/include)
SET(SRCS prog.c)

add_executable(${PNAME} ${SRCS})
link_directories(/usr/local/SGPx/lib)

target_link_libraries(${PNAME} sgplib)


[\code]

von Rene H. (Gast)


Lesenswert?

1
cmake_minimum_required(VERSION 2.8)
2
3
SET(PNAME cprogram)
4
PROJECT(${PNAME})
5
6
include_directories (/usr/local/SGPx/include)
7
link_directories(/usr/local/SGPx/lib)
8
9
SET(SRCS prog.c)
10
11
add_executable(${PNAME} 
12
    ${SRCS}
13
    )
14
target_link_libraries(${PNAME} 
15
    sgplib
16
    )

Das target_link_directories gehört (logisch) zum add_executable.

Grüsse,
René

von Kano (Gast)


Lesenswert?

ich habe es genau ausprobiert aber wie gesagt den gleichen fehler:
1
 
2
cmake_minimum_required(VERSION 2.8)
3
4
SET(PNAME cprogram)
5
PROJECT(${PNAME})
6
7
include_directories (/usr/local/SGPx/include)
8
link_directories(/usr/local/SGPx/lib)
9
10
SET(SRCS prog.c)
11
12
add_executable(${PNAME} ${SRCS})
13
target_link_libraries(${PNAME} sgplib)

Compiler meldung:
1
Linking C executable cprogram
2
/usr/bin/ld: cannot find -lsgplib
3
collect2: error: ld returned 1 exit status
4
make[2]: *** [cprogram] Fehler 1
5
make[1]: *** [CMakeFiles/cprogram.dir/all] Fehler 2
6
make: *** [all] Fehler 2

aber wie die meldung zeigt, der sucht nach der Library in /usr/bin und 
die ist bei mir in usr/local/SGPx/lib,  kan das sein das das problem 
ist?

von Rene H. (Gast)


Lesenswert?

Du hast aber die Makefiles schon nochmal generieren lassen?
Poste mal die Zeile mit dem linker wenn Du make VERBOSE=1 machst.

Grüsse,
René

von Kano (Gast)


Lesenswert?

Hier ist make verbist =1:
1
ts/cprog/build$ make VERBOSE=1
2
/usr/bin/cmake -H/home/cmax/program/cprog -B/home/cmax/program/cprog/build --check-build-system CMakeFiles/Makefile.cmake 0
3
/usr/bin/cmake -E cmake_progress_start /home/program/cprog/build/CMakeFiles /home/cmax/program/cprog/build/CMakeFiles/progress.marks
4
make -f CMakeFiles/Makefile2 all
5
make[1]: Entering directory `/home/cmax/program/cprog/build'
6
make -f CMakeFiles/cprogram.dir/build.make CMakeFiles/cprogram.dir/depend
7
make[2]: Entering directory `/home/cmax/program/cprog/build'
8
cd /home/cmax/program/cprog/build && /usr/bin/cmake -E cmake_depends "Unix Makefiles" /home/cmax/program/cprog /cmax/program/cprog /home/cmax/programs/cprog/build /home/cmax/program/cprog/build /home/cmax/program/cprog/build/CMakeFiles/cprogram.dir/DependInfo.cmake --color=
9
make[2]: Leaving directory `/home/cmax/program/cprog/build'
10
make -f CMakeFiles/cprogram.dir/build.make CMakeFiles/cprogram.dir/build
11
make[2]: Entering directory `/home/cmax/program/cprog/build'
12
Linking C executable cprogram
13
/usr/bin/cmake -E cmake_link_script CMakeFiles/cprogram.dir/link.txt --verbose=1
14
/usr/bin/cc      CMakeFiles/cprogram.dir/prog.c.o  -o cprogram  -L/usr/local/SGPx/lib -rdynamic -lsgplib -lm -Wl,-rpath,/usr/local/SGPx/lib 
15
/usr/bin/ld: cannot find -lsgplib
16
collect2: error: ld returned 1 exit status
17
make[2]: *** [cprogram] Fehler 1
18
make[2]: Leaving directory `/home/cmax/programs/cprog/build'
19
make[1]: *** [CMakeFiles/cprogram.dir/all] Fehler 2
20
make[1]: Leaving directory `/home/cmax/program/cprog/build'
21
make: *** [all] Fehler 2

von Rolf Magnus (Gast)


Lesenswert?

Kano schrieb:
> aber wie die meldung zeigt, der sucht nach der Library in /usr/bin

Wo zeigt die das?

> und die ist bei mir in usr/local/SGPx/lib,  kan das sein das das problem

Ist sie auch tatsächlich da? Wie sieht dieses Verzeichnis aus?

von Rolf Magnus (Gast)


Lesenswert?

Deine Linker-Kommandozeile sieht eigentlich gut aus. Alles nötige ist 
drin. Also muß wohl die lib im Zielverzeichnis fehlen.

von mh (Gast)


Lesenswert?

Kann es sein dass du cmake den falschen Namen für die library nennst?
Im ersten Post schreibst du, dass sie den Namen libsgp.so hat. cmake 
sagst du aber sgplib, wodurch der linker soweit ich weiß nach 
libsgplib.so sucht. Also versuch es mal mit 
target_link_libraries(${PNAME} sgp)

von Rolf Magnus (Gast)


Lesenswert?

Damit soll's ja angeblich gehen:

Kano schrieb:
> /cprog$ gcc prog.c -L/home/marx/program/cprog/sgplib -lsgplib

Da fällt allerdings auf, daß die Lib nicht in /usr/local/SGPx/lib 
gesucht wird, sondern in /home/marx/program/cprog/sgplib.

von Kano (Gast)


Lesenswert?

die objects file liegen tatsächlich in den verzeichnise:

hier ist die ls ausgabe:
1
cmax@hgensm:/usr/local/SGPx/lib$ ls
2
libsgp.a  libsgp.so
3
cmax@hgens:/usr/local/SGPx/lib$ cd ..
4
cmax@hgens:/usr/local/SGPx$ cd include/
5
cmax@hgens:/usr/local/SGPx/include$ ls
6
sgp.h  sgp_int.h

von Rolf Magnus (Gast)


Lesenswert?

Da heißt sie aber auch - wie "mh" schon vermutet hat - libsgp.so und 
eben nicht libsgplib.so.

von Rene H. (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Da heißt sie aber auch - wie "mh" schon vermutet hat - libsgp.so und
> eben nicht libsgplib.so.

Ergo:
1
.
2
.
3
.
4
target_link_libraries(${PNAME} 
5
    sgp
6
    )

Grüsse,
René

von Kano (Gast)


Lesenswert?

Rolf Magnus schrieb:
> Damit soll's ja angeblich gehen:
>
> Kano schrieb:
>> /cprog$ gcc prog.c -L/home/marx/program/cprog/sgplib -lsgplib
>
> Da fällt allerdings auf, daß die Lib nicht in /usr/local/SGPx/lib
> gesucht wird, sondern in /home/marx/program/cprog/sgplib.

Hallo Rolf;

es lauft wenn ich es mit gcc kompliere ohne problem:
1
 gcc -o cprog prog.c -I /usr/local/SGPx/include -L  /usr/local/SGPx/lib -lsgp -lm

ich habe die library zum Probe in das verzeichnis da wo mein Prorgamm 
kopiert, aber es hat nicht gebracht.

von Kano (Gast)


Lesenswert?

Rene H. schrieb:
> target_link_libraries(${PNAME}
>     sgp
>     )


ich habe es mit
 target_link_libraries(${PNAME}
   sgp
  )
und bin weiter gekommen aber nun meldet  beim Ausführen  einen 
speicherzugriffsfehler:
1
/cprog/build$ make
2
Scanning dependencies of target cprogram
3
[100%] Building C object CMakeFiles/cprogram.dir/prog.c.o
4
Linking C executable cprogram
5
[100%] Built target cprogram
6
cmax@hgens:~/projects/cprog/build$ ./cprogram 
7
Speicherzugriffsfehler
8
cmax@hgens:

das kappier ich nicht, wenn ich das mit gcc kompliere, kann ich es ohne 
problem ausführen.

von Rolf Magnus (Gast)


Lesenswert?

Nimmt er vielleicht die falsche libsgp? Was sagt denn ein
1
ldd cprog
für dein von Hand übersetztes Programm und für das mit cmake erstellte 
jeweils, welche libsgp er nimmt?

von Kano (Gast)


Lesenswert?

Es funktioniert, ich bedanke mich  sehr  bei euch.

Gruß
kano

von Olga (Gast)


Lesenswert?

Kano schrieb:
> Linke problem bei Cmake

Die SPD hat auch gerade Linke Probleme... :>

von Kano (Gast)


Lesenswert?

Hallo zusammen,

ich muss doch noch an euch wieder anwenden,anscheined lasst mich dies 
Link Problem nicht weiterkommen.
Nun habe ich die Source Endung ( .c) in (.cpp) geändert und schön wieder 
taucht bei der Kompilierung  die Linke Fehler.

hier ist CMakeLists.txt:
1
cmake_minimum_required(VERSION 2.8)
2
3
SET(PNAME cprogram)
4
PROJECT(${PNAME})
5
6
include_directories (/usr/local/SGPx/include)
7
link_directories(/usr/local/SGPx/lib)
8
9
SET(SRCS prog.cpp)                  #aenderung .c in .cpp
10
11
add_executable(${PNAME} ${SRCS})
12
13
target_link_libraries(${PNAME} sgp)
14
target_link_libraries(${PNAME} m)

Die Meldung von Compieler:
1
 
2
 /cprog/build$ make
3
Scanning dependencies of target cprogram
4
[100%] Building CXX object CMakeFiles/cprogram.dir/prog.cpp.o
5
Linking CXX executable cprogram
6
CMakeFiles/cprogram.dir/prog.cpp.oIn function `spp_test':
7
prog.c:(.text+0x2f4): undefined reference to `Conver_Data'
8
prog.c:(.text+0x379): undefined reference to `sffcall'
9
prog.c:(.text+0x3b8): undefined reference to `smmp'
10
prog.c:(.text+0x3f7): undefined reference to `dd4'

wie gesagt wenn ich die saurce Endung mit .c versehen würde, meldet mir 
keinen fehler.

danke schön mal im veraus für jede Hilfe


Gruß
Kano

von Rene H. (Gast)


Lesenswert?

Wenn Du die Endung cpp hast, komiliert er mit g++. Hast Du das schon mal 
von Hand versucht?
Da wirst Du vermutlich ein Mangling/Demangling Problem mit Deiner 
Library haben.

Grüsse,
René

von Kano (Gast)


Lesenswert?

ja habe ich schön ausprobiert , kommt die gleiche Meldung:
1
cprog$ g++ -o cprog prog.cpp -I /usr/local/SGPx/include -L  /usr/local/SGPx/lib -lsgp
2
/tmp/ccTIdzwp.o: In function  `spp_test':
3
prog.c:(.text+0x2f4): undefined reference to `Conver_Data'
4
prog.c:(.text+0x379): undefined reference to `sffcall'
5
prog.c:(.text+0x3b8): undefined reference to `smmp'
6
prog.c:(.text+0x3f7): undefined reference to `dd4'

von Rene H. (Gast)


Lesenswert?

Dann musst du die Funktionen in Deinem cpp File in ein extern "C" 
packen.

Grüsse,
René

von Rene H. (Gast)


Lesenswert?


von Kano (Gast)


Lesenswert?

Danke sehr Rene,

genau daran lag es. ....Super.
ich habe die Header-datei in extern gepackt.


gibts eine andere alternative ohne es in extern "C"  zu packen.

von Rene H. (Gast)


Lesenswert?

Kano schrieb:
> gibts eine andere alternative ohne es in extern "C"  zu packen.

Nicht direkt.

1) Du nimmst den C Compiler, wenn Du ein C Projekt machst.
2) Du forcierst im cmake den C-Compiler zu nehmen, dann hast Du aber 
kein C++ Projekt

Wenn Du C++ und C mischen willst, dann geht es nur mit external C. Sonst 
passt es dem Linker nicht.

Schau mal ein c++ Binary mit nm <binary> an und dann mit nm <binary> | 
c++filt (c++filt macht ein Demangling).

Die Symbole werden anderes zusammengesetzt in C++ (eben, name mangling).

Grüsse,
René

von Rene H. (Gast)


Lesenswert?

Noch eine Ergänzung für das Verständnis:

In C++ kann man Funktionen/Methoden überladen. Z.Bsp:
1
void MyClass::func(uint8_t a) 
2
{
3
4
}
5
6
void MyClass::func(std::string str) 
7
{
8
9
}

Damit der Linker zwischen den beiden func() unterscheiden kann, muss die 
Signatur der Funktion/Methode in den Symbol Namen mit kompiliert werden.

Aus diesem Grund sind C++ und C Symbole nicht identisch.

Grüsse,
René

von Kano (Gast)


Lesenswert?

Danke Sehr Rene für die gute Erklärung.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.