C++ 将具有循环链接依赖关系的makefile转换为CMake

C++ 将具有循环链接依赖关系的makefile转换为CMake,c++,c,makefile,cmake,C++,C,Makefile,Cmake,我有多个实现(.c或.cpp文件),它们实现了同一头文件的不同功能。我有用于构建的makefile方法,我想用cmake重新实现它。(注意,我不能更改实现文件或头。如果可以,我不会按原样设计和实现解决方案。)我准备了较小的案例来指出我的问题 标题h: #ifndef __HEAD__ #define __HEAD__ int foo(float e, float b); void boo(float *eo, float *eh); void setup(); int load(int* n)

我有多个实现(.c或.cpp文件),它们实现了同一头文件的不同功能。我有用于构建的makefile方法,我想用cmake重新实现它。(注意,我不能更改实现文件或头。如果可以,我不会按原样设计和实现解决方案。)我准备了较小的案例来指出我的问题

标题h:

#ifndef __HEAD__
#define __HEAD__

int foo(float e, float b);
void boo(float *eo, float *eh);
void setup();
int load(int* n);

#endif
1.c:

#include "head.h"

void boo(float *eo, float *eh)
{
  *eo = 0.4f;
  *eh = 2.3f;
}
2.c:

#include <stdio.h>
#include "head.h"
void setup()
{
  printf("hello!\n");
  int m = 13;
  int* n = &m;
  load(n);
}
main.cpp:

#include "head.h"
int main()
{
  setup();
  return 0;
}
int foo(float e, float b)
{
  float i, j;
  boo(&i, &j);
  return 4;
}
makefile:(这是构建和链接)

到目前为止,我使用cmake进行了哪些尝试:(您可以观察到我的失败尝试,如评论所示)


我肯定错过了关于cmake构建生成的一些关键点。希望有些帮助。

即使在旧的MaFILE文件中也不适用,因为你是在混合C和C++。这个问题实际上与你的构建系统无关,必须与C和C++的混合做。 要解决此问题,请将头文件更改为:

#ifndef HEAD_H
#define HEAD_H

#ifdef __cplusplus
extern "C" {
#endif

int foo(float e, float b);
void boo(float *eo, float *eh);
void setup();
int load(int* n);

#ifdef __cplusplus
}
#endif

#endif

最大的变化是,在头文件中,我为宏添加了一个宏代码< > CpPuSPLUS < /C> >,它由C++编译器定义,而不是C编译器。当定义

\uuucplusplus
时,我已经告诉编译器将函数声明视为“C”声明,这意味着函数将不执行任何操作

问题是C++编译器会修改函数名,从而使函数重载。这意味着,例如函数“代码>安装程序< /C>”的符号在编译为C++时是不同的。<代码>外部“C”<代码>告诉C++编译器不要修改名称。 如需有关
extern“C”
的更多信息,请参阅


还要注意,我更改了头include-guard,因为所有带双前导下划线的符号都是为所有作用域中的“实现”(即编译器和标准库)保留的。参见.< /p> ,即使在旧的MaFILE文件中,也不适用,因为您正在混合C和C++。这个问题实际上与你的构建系统无关,必须与C和C++的混合做。 要解决此问题,请将头文件更改为:

#ifndef HEAD_H
#define HEAD_H

#ifdef __cplusplus
extern "C" {
#endif

int foo(float e, float b);
void boo(float *eo, float *eh);
void setup();
int load(int* n);

#ifdef __cplusplus
}
#endif

#endif

最大的变化是,在头文件中,我为宏添加了一个宏代码< > CpPuSPLUS < /C> >,它由C++编译器定义,而不是C编译器。当定义

\uuucplusplus
时,我已经告诉编译器将函数声明视为“C”声明,这意味着函数将不执行任何操作

问题是C++编译器会修改函数名,从而使函数重载。这意味着,例如函数“代码>安装程序< /C>”的符号在编译为C++时是不同的。<代码>外部“C”<代码>告诉C++编译器不要修改名称。 如需有关
extern“C”
的更多信息,请参阅


还要注意,我更改了头include-guard,因为所有带双前导下划线的符号都是为所有作用域中的“实现”(即编译器和标准库)保留的。例如,

我认为它是有效的,因为他定义了代码> cc= g++< /COD>,这样C++编译器就被用来编译C代码。谢谢你的明确回答。成功了。另外,关于双引线下划线的建议,我忘记了。我认为它是有效的,因为他定义了代码> cc= g++< /COD>,这样C++编译器就被用来编译C代码。谢谢你的明确回答。成功了。还有关于双前导下划线的建议,我忘了。
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
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>)
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 
#ifndef HEAD_H
#define HEAD_H

#ifdef __cplusplus
extern "C" {
#endif

int foo(float e, float b);
void boo(float *eo, float *eh);
void setup();
int load(int* n);

#ifdef __cplusplus
}
#endif

#endif