编译最小C++使用Make具有隐式规则的程序

发布于 2025-02-03 13:32:12 字数 2068 浏览 3 评论 0原文

文章显示了以下示例,用于使用make编译具有隐式规则的最小C程序。

CC = gcc
CFLAGS = -g

blah: blah.o

blah.c:
    echo "int main() { return 0; }" > blah.c

clean:
    rm -f blah*

当我尝试使用Make Blah运行此操作时,它似乎可以正常工作,并输出可执行文件,以下记录以下标准输出:

$ make blah
echo "int main() { return 0; }" > blah.c
gcc -g -c -o blah.o blah.c
gcc blah.o -o blah

我尝试适应最小的C ++程序,并提出以下makefile:

blah: blah.o

blah.cc:
    echo "#include<iostream>\nint main() { std::cout << 123 << std::endl; }" >> blah.cc

clean:
    rm -f blah*

当我尝试`blah时,我遇到了一个错误:

echo "#include<iostream>\nint main() { std::cout << 123 << std::endl; }" >> blah.cc
g++    -c -o blah.o blah.cc
cc   blah.o   -o blah
/usr/bin/ld: blah.o: warning: relocation against `_ZSt4cout' in read-only section `.text'
/usr/bin/ld: blah.o: in function `main':
blah.cc:(.text+0x10): undefined reference to `std::cout'
/usr/bin/ld: blah.cc:(.text+0x18): undefined reference to `std::ostream::operator<<(int)'
/usr/bin/ld: blah.cc:(.text+0x1f): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
/usr/bin/ld: blah.cc:(.text+0x2a): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
/usr/bin/ld: blah.o: in function `__static_initialization_and_destruction_0(int, int)':
blah.cc:(.text+0x61): undefined reference to `std::ios_base::Init::Init()'
/usr/bin/ld: blah.cc:(.text+0x7c): undefined reference to `std::ios_base::Init::~Init()'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
make: *** [<builtin>: blah] Error 1

在我看来,make仍在运行cc命令,我怀疑这就是为什么错误发生。

为什么会发生这种情况?如何解决?

This article shows the following example for compiling a minimal C program with implicit rules using make.

CC = gcc
CFLAGS = -g

blah: blah.o

blah.c:
    echo "int main() { return 0; }" > blah.c

clean:
    rm -f blah*

When I attempt to run this using make blah it seems to work fine and outputs an executable with the following being logged in standard output:

$ make blah
echo "int main() { return 0; }" > blah.c
gcc -g -c -o blah.o blah.c
gcc blah.o -o blah

I tried to adapt this for a minimal C++ program, and came up with the following Makefile:

blah: blah.o

blah.cc:
    echo "#include<iostream>\nint main() { std::cout << 123 << std::endl; }" >> blah.cc

clean:
    rm -f blah*

When I try `make blah, I run into an error:

echo "#include<iostream>\nint main() { std::cout << 123 << std::endl; }" >> blah.cc
g++    -c -o blah.o blah.cc
cc   blah.o   -o blah
/usr/bin/ld: blah.o: warning: relocation against `_ZSt4cout' in read-only section `.text'
/usr/bin/ld: blah.o: in function `main':
blah.cc:(.text+0x10): undefined reference to `std::cout'
/usr/bin/ld: blah.cc:(.text+0x18): undefined reference to `std::ostream::operator<<(int)'
/usr/bin/ld: blah.cc:(.text+0x1f): undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::endl<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&)'
/usr/bin/ld: blah.cc:(.text+0x2a): undefined reference to `std::ostream::operator<<(std::ostream& (*)(std::ostream&))'
/usr/bin/ld: blah.o: in function `__static_initialization_and_destruction_0(int, int)':
blah.cc:(.text+0x61): undefined reference to `std::ios_base::Init::Init()'
/usr/bin/ld: blah.cc:(.text+0x7c): undefined reference to `std::ios_base::Init::~Init()'
/usr/bin/ld: warning: creating DT_TEXTREL in a PIE
collect2: error: ld returned 1 exit status
make: *** [<builtin>: blah] Error 1

It seems to me that make is still running a cc command, which I suspect is why the error occurs.

Why is this happening and how can I fix it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

素衣风尘叹 2025-02-10 13:32:12

在我的系统上,制作程序的隐式规则是:

%: %.o
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@

在其中

LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)

使用make -np -f/dev/null检查自己。

您可以通过更改link.o来解决问题,以使用$(cxx),也可以将配方添加到blah规则中。

On my system, the implicit rule for producing programs is:

%: %.o
        $(LINK.o) $^ $(LOADLIBES) $(LDLIBS) -o $@

where

LINK.o = $(CC) $(LDFLAGS) $(TARGET_ARCH)

Check for yourself with make -np -f/dev/null.

You can either solve the problem by changing LINK.o to use $(CXX), or adding a recipe to the blah rule.

不羁少年 2025-02-10 13:32:12

C对象文件需要与CC链接,而C ++对象则需要将文件与C ++链接,如果您希望所有所需的LIB自动包含在内。由于两者的名称都是相同的,因此只能有一个自动规则可以链接二进制文件。默认规则是链接C对象文件。

您可以设置cc = $(cxx)来更改默认规则用于链接的内容。

C object files need to be linked with cc while C++ objects files need to be linked with c++ if you expect all the required libs to automatically included. Since the name for both is the same there can only be one automatic rule to link a binary. The default rule is to link C object files.

You can set CC = $(CXX) to change what the default rule uses to link.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文