Ich habe mehrere Implementierungen (.c oder .cpp-Dateien), die verschiedene Funktionen der gleichen Header-Datei implementiert. Ich habe den Makefile Ansatz für Build und ich möchte es mit cmake neu implementieren. (Beachten Sie, dass ich die Implementierungsdateien oder Header nicht ändern kann. Wenn ich könnte, würde ich die Lösung nicht so entwerfen und implementieren wie sie ist.) Ich habe kleinere vorbereitet Fall, um auf mein Problem hinzuweisen.Konvertieren von Makefile mit Circular Link-Abhängigkeit zu CMake
head.h:
#ifndef __HEAD__
#define __HEAD__
int foo(float e, float b);
void boo(float *eo, float *eh);
void setup();
int load(int* n);
#endif
impl1.c:
#include "head.h"
void boo(float *eo, float *eh)
{
*eo = 0.4f;
*eh = 2.3f;
}
impl2.c:
#include <stdio.h>
#include "head.h"
void setup()
{
printf("hello!\n");
int m = 13;
int* n = &m;
load(n);
}
impl3.c:
#include "head.h"
int load(int* n)
{
n = 0;
return 0;
}
main.cpp:
#include "head.h"
int main()
{
setup();
return 0;
}
int foo(float e, float b)
{
float i, j;
boo(&i, &j);
return 4;
}
Make-Datei: (dies baut und zum Verlinken)
# C compiler
CC = g++
CC_FLAGS = -g -O2
main: impl1.o impl2.o impl3.o
$(CC) $(CC_FLAGS) main.cpp impl1.o impl2.o impl3.o -o main
%.o: %.[ch]
$(CC) $(CC_FLAGS) $< -c
impl1.o: impl1.c
$(CC) $(CC_FLAGS) impl1.c -c
impl2.o: impl2.c
$(CC) $(CC_FLAGS) impl2.c -c
impl3.o: impl3.c
$(CC) $(CC_FLAGS) impl3.c -c
clean:
rm -f *.o *~ main *.linkinfo
Mit dem Make-Datei, werden diese Befehle ausgeführt:
g++ -g -O2 impl1.c -c
g++ -g -O2 impl2.c -c
g++ -g -O2 impl3.c -c
g++ -g -O2 main.cpp impl1.o impl2.o impl3.o -o main
Was habe ich versucht, mit cmake bis jetzt: (Sie können meine fehlgeschlagenen Versuche als kommentiert beobachten)
add_executable(${PROJECT_NAME} impl1.c impl2.c impl3.c main.cpp)
# add_library(impl1 OBJECT impl1.c)
# add_library(impl2 OBJECT impl2.c)
# add_library(impl3 OBJECT impl3.c)
# add_executable(${PROJECT_NAME} main.cpp $<TARGET_OBJECTS:impl3> $<TARGET_OBJECTS:impl2> $<TARGET_OBJECTS:impl1>)
# add_library(impl1 STATIC impl1.c)
# add_library(impl2 STATIC impl2.c)
# add_library(impl3 STATIC impl3.c)
# add_executable(main main.cpp)
#
# set(LIBS impl1 impl2 impl3)
#
# target_link_libraries(main ${LIBS} ${LIBS})
# add_library(headextra impl1.c impl2.c impl3.c)
# add_executable(${PROJECT_NAME} main.cpp)
# target_link_libraries(${PROJECT_NAME} headextra)
# add_library(headextra impl1.c impl2.c impl3.c main.cpp)
# add_executable(${PROJECT_NAME} $<TARGET_OBJECTS:headextra>)
Diese CMake-Datei generiert erfolgreich den Build und kompiliert sie auch. Aber beim Verknüpfen habe ich Fehler bekommen, die ich nicht beheben konnte:
make -f CMakeFiles/cmake_test.dir/build.make CMakeFiles/cmake_test.dir/build
/usr/bin/cc -o CMakeFiles/cmake_test.dir/impl1.c.o -c /home/ahmet/Desktop/cmake_test/impl1.c
/usr/bin/cc -o CMakeFiles/cmake_test.dir/impl2.c.o -c /home/ahmet/Desktop/cmake_test/impl2.c
/usr/bin/cc -o CMakeFiles/cmake_test.dir/impl3.c.o -c /home/ahmet/Desktop/cmake_test/impl3.c
/usr/bin/c++ -o CMakeFiles/cmake_test.dir/main.cpp.o -c /home/ahmet/Desktop/cmake_test/main.cpp
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmake_test.dir/link.txt --verbose=1
/usr/bin/c++ CMakeFiles/cmake_test.dir/impl1.c.o CMakeFiles/cmake_test.dir/impl2.c.o CMakeFiles/cmake_test.dir/impl3.c.o CMakeFiles/cmake_test.dir/main.cpp.o -o cmake_test -rdynamic
CMakeFiles/cmake_test.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x5): undefined reference to `setup()'
CMakeFiles/cmake_test.dir/main.cpp.o: In function `foo(float, float)':
main.cpp:(.text+0x31): undefined reference to `boo(float*, float*)'
collect2: error: ld returned 1 exit status
make[2]: *** [cmake_test] Error 1
make[1]: *** [CMakeFiles/cmake_test.dir/all] Error 2
make: *** [all] Error
Ich vermisse definitiv einen wichtigen Punkt über CMake Build Generation. Hoffentlich können einige helfen.
Ich denke, es hat funktioniert, weil er 'CC = g ++' so definiert, dass der C++ - Compiler zum Kompilieren von C-Code verwendet wird. – Jens
Vielen Dank für Ihre klare Antwort. Es funktionierte. Auch für den Hinweis auf doppelte führende Unterstreichungen habe ich das vergessen. – Vemulo