【问题标题】:Compiling C and C++ with single makefile使用单个 makefile 编译 C 和 C++
【发布时间】:2020-03-05 09:22:29
【问题描述】:

我正在尝试创建一个使用我的 earlier created shared library, which by the way is now static 的可执行文件,其中包括 openSSL 静态库。因此,我使用了与创建该库相同的 Makefile,并对其进行了破解以使其在这里工作。看起来是这样的

LIBBASE=/home/AB/Documents/APP/APP_2.17.0
OPENSSL1.0.2p_INSTALL_LOC=/home/AB/Documents/APP/OpenSSL-1.0.2p-installation
CC=gcc
CXX=g++
CFLAGS= -Wall -g -pedantic
CPPFLAGS= -Wall -g -pedantic 
RM= rm -f
.PHONY: all clean

c_src=$(shell find . -iname "*.c")
$(info source=$(c_src))

cpp_src=$(shell find . -iname "*.cpp")
$(info cppsource=$(cpp_src))

INC=-I$(LIBBASE)/include
$(info includes=$(INC))

# need to link pthread library here as well
LIB = -pthread

# aforementioned library
LIB+=-L$(LIBBASE)/lib 
LIB+= -l:libSCA.a

#need to add SSL related libraries
LIB+= -L$(OPENSSL1.0.2p_INSTALL_LOC)/lib
LIB+= -l:libssl.a -l:libcrypto.a -static-libgcc

# As mentioned, we need to link dl and libz libraries as well
LIB+= -ldl -lz

$(info links=$(LIB))

obj=$(c_src:.c=.o) $(cpp_src:.cpp=.o)
all: APP
clean:
    $(RM) *.o APP
    $(shell find $(APPBASE) -type f -iname "*.o" -exec rm -rf {} \;)

.c.o:
    ${CXX} -static ${CPPFLAGS} $(INC) -c $< -o $@
    #${CC} -static ${CFLAGS} $(INC) -c $< -o $@

.cpp.o:
    ${CXX} -static ${CPPFLAGS} $(INC) -c $< -o $@

APP: $(obj)
    $(LINK.cxx) $^ -o $@ $(LIB)

但是我无法让它工作。我得到了很多未定义的对我的库定义的符号的引用。我已经注意在 cpp 文件中的这些符号周围使用 extern C,但它似乎没有帮助。

顺便说一句,还有比这更直接或更简单的方法吗?

此外,在浏览此处的各种答案时,我发现.c.o 之类的目标已经过时,不应再使用。是否有最新的、详尽的、 实用的 Makefile 权威指南(问太多了)??

更新 1:所以在这里我可以访问日志,我注意到我得到的所有未定义的引用错误都与我静态链接到我的共享库的 SSL 库定义的符号有关。我的错误日志示例:

/home/AB/Documents/APP/APP_2.17.0_Linux/libAPP.so: undefined reference to `SSL_CTX_free'
/home/AB/Documents/APP/APP_2.17.0_Linux/libAPP.so: undefined reference to `X509_set_issuer_name'

所以我想制作一个静态库,可以在内部链接(或者更确切地说是合并)libssl.aModified my aforementioned makefile 并创建了一个静态 libAPP.a。但我仍然不断收到这些错误。

我终于在这个 makefile 中添加了 libssl.alibcrypto.a,瞧,很多错误都得到了修复。我仍然有一些与dlopen 和 pthreads 相关的错误,所以我也添加了这些错误。我还使用 CXX 编译器编译所有内容,以消除由于名称混淆引起的问题。

现在让我感到困扰的是,与 SSL 相关的符号应该已经存在于 libAPP.a 中(尽管 nm 将它们报告为 undefined 并且可能需要自己提出另一个问题:D )。但我仍然需要在此处指定libSSL.alibcrypto.a 以便链接器找到它们!那么创建存档(libAPP.a)而不是共享库(libAPP.so)有什么好处呢?

最后在链接阶段,我的链接器找不到lz

/usr/bin/ld: cannot find -lz

只是为了它,我尝试将相同的标志添加到创建该存档的 makefile 中,并且找到它没有问题。有什么建议吗??

【问题讨论】:

  • GnuMake 手册有一些启发性的章节。
  • 当然可以,我确定。但是自己处于生产环境中,我希望你明白我的时间很短(现在不是哪个开发人员:))。如果您有快速修复或可以指出其中的明显缺陷或建议更简单的方法来解决此类问题,我将不胜感激!
  • @thebusybee 顺便说一句,当我放松并想学习新东西时,我一定会看看这些章节
  • 首先你应该明白你的问题不在于make或makefile。如果您遇到链接错误,则意味着问题在于您的编译或链接命令错误。因此,试图将它归咎于 make 或 makefile 不会让你有任何收获。如果您不熟悉如何将编译器和链接器与共享库一起使用,一个有用的练习是尝试直接在 shell 提示符下运行编译命令,直到您弄清楚哪些是正确的。那么你可以考虑如何以最有效的方式将它们放入你的 makefile 中。
  • 按照惯例,CXXFLAGS 是 C++ 编译器的标志,而CPPFLAGS 是 C 预处理器的标志。

标签: c++ c makefile linker mixed-mode


【解决方案1】:

我会按以下步骤执行此操作:

  1. 收集所有命令以“手动”构建所有内容。只有当这有效时,如果你是初学者,继续前进是有意义的。这些命令可以放在批处理文件中。
  2. 提取依赖项和规则。
  3. 在 Makefile 中写入;归根结底,Makefile 就是:浓缩知识如何构建。
  4. 试试 Makefile。
  5. 如果我遇到错误,我将使用 make 的选项 -d-p-n 来查看它的想法。可能还有更多有用的选项。

【讨论】:

    【解决方案2】:

    最明显的问题是,当您的程序包含 C++ 组件时,您使用 $(LINK.c) 进行链接,因此您没有获得任何 C++ 库等。尝试使用$(LINK.C)$(LINK.cc)$(LINK.cpp)$(LINK.cxx)(C++ 所需的值因make 版本而异,但至少应预定义其中一个。)

    【讨论】:

    • 我想将所有目标文件链接到一个可执行文件中。那些从 C 文件生成的文件以及从 cpp 文件生成的文件。如果 `LINK.c' 不是正确的方法,那是什么?
    • 尝试$(LINK.cpp) - 如果您使用的 make 版本中未定义,请尝试其他方法之一。
    • 会直接由 make 推断出 {LINK.cpp} 还是我需要明确定义它?另外,我可以链接所有对象,无论它们的来源如何(C/C++)??
    猜你喜欢
    • 1970-01-01
    • 2018-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-24
    • 1970-01-01
    相关资源
    最近更新 更多