【问题标题】:Compile *.cpp and *.c with Automake使用 Automake 编译 *.cpp 和 *.c
【发布时间】:2020-06-16 10:13:28
【问题描述】:

结构:

-myProject
    -Makefile.am
    -configure.ac
    -src
        -Makefile.am
        -main.c
        -test.c
        -test.h

当我尝试编译时,我收到错误未定义的对 test.c 中函数的引用。

Makefile.am:

   AUTOMAKE_OPTIONS = foreign
   SUBDIRS=src

src/Makefile.am:

   bin_PROGRAMS = TEST
   AM_CXXFLAGS =-Wall -Wno-psabi -w -pthread -I/usr/local/include
   AM_CFLAGS =-Wall -w
   #Sources
   TEST_SOURCES = test.c main.cpp
   TEST_LDADD = @LDFLAGS@ -lmosquitto
   TEST_LDFLAGS =-lmosquitto 

似乎无法链接这两个来源。有人可以帮帮我吗?

错误:

make  all-recursive
make[1]: Entering directory '/media/sf_Shared/Software/executables/TEST'
Making all in src
make[2]: Entering directory '/media/sf_Shared/Software/executables/TEST/src'
g++ -DHAVE_CONFIG_H -I. -I..    -Wall -Wno-psabi -w -pthread -I/usr/local/include -g -O2 -MT main.o -MD -MP -MF .deps/main.Tpo -c -o main.o main.cpp
mv -f .deps/main.Tpo .deps/main.Po
g++ -Wall -Wno-psabi -w -pthread -I/usr/local/include  -g -O2 -lmosquitto   -o TEST test.o main.o -lmosquitto 
/usr/bin/ld: main.o: in function `main':
/media/sf_Shared/Software/executables/TEST/src/main.cpp:564: undefined reference to `open_ports(unsigned int, unsigned int)'
collect2: error: ld returned 1 exit status
make[2]: *** [Makefile:366: TEST] Error 1
make[2]: Leaving directory '/media/sf_Shared/Software/executables/TEST/src'
make[1]: *** [Makefile:359: all-recursive] Error 1
make[1]: Leaving directory '/media/sf_Shared/Software/executables/TEST'
make: *** [Makefile:300: all] Error 2

我在 main.cpp 中包含了 test.h。有声明的函数open_ports(u_int32_t open_ports(u_int32_t a, u_int32_t b);),在test.c中实现

【问题讨论】:

  • 引用完整的错误并显示它适用的调用/函数。展示如何声明该函数以及如何调用它。可能是 C/C++ 链接的混合让你感到困惑。
  • 仅供参考,与实际问题无关:将@LDFLAGS@ 添加到非_LDFLAGS 变量看起来很可疑。改为将其添加到 _LDFLAGS

标签: c++ linker-errors automake


【解决方案1】:

这不是automake 的问题——您在Makefile.am 中做的事情是正确的(或至少接近于)。

问题是你的符号是在没有extern "C"的情况下声明的,但只在C中定义,所以当C++编译器接受你的main.cpp时,它期望找到一个mangled符号(它编码了函数的签名,即参数的数量和类型),而不是普通的(C)。

您可以说是这种情况,因为它正在寻找open_ports(unsigned int, unsigned int),而不仅仅是open_ports

最简单的解决方案是将您的main.cpp 更改为:

extern "C" {
#include "test.h"
}

这表明test.h 标头仅包含C 声明,然后将为您在test.c 中定义的内容生成正确的符号查找。

【讨论】:

  • 我会将extern "C" {} 行包含到test.h 文件本身中,但每个行都包含在#ifdef __cplusplus#endif 中。这样,您就可以在任何 C 和 C++ 文件中包含 test.h
  • 我认为这是风格问题上的一个争论点 :) 我不喜欢在仅 C 的标头中混合 C++ 构造 (extern "C"),而是非常注意使用“外语” (C) 来自 C++。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多