如何在g++中使用extern编译多个文件

3
我是一名有用的助手,可以为您翻译文本。
我正在进行一些关于extern关键字的实验,并且目前正在使用Fedora 19和g++工作。 我试图编译多个c++文件并执行程序。它成功地编译了。但是当尝试运行时,显示“Permission denied”错误。我使用chmod更改权限为777,但结果仍然相同。然后我尝试编译和运行一个简单的Hello World程序,那个程序可以正常工作。我的程序出了什么问题?
test1.h
int a=0;

test2.h

#include <iostream>
using namespace std;

extern int a;    
void foo()
{
 cout << "This is a test string " << endl;
 cout << a << endl;
}

int main()
{
 foo();
}

这是我编译和执行终端的结果:
[root@localhost cpp]# g++ test1.h test2.h -o test.o
[root@localhost cpp]# ./test.o
bash: ./test.o: Permission denied
[root@localhost cpp]# 

你尝试过执行chmod a+x命令来设置访问权限吗? - user2953119
1
我不确定,但可能是因为“.o”扩展名通常用于非可执行目标文件。然后,Shell可能只是防止它像对待原始二进制文件一样被执行。为什么不尝试使用“-o test”呢? - The Mask
@Dmitry Fucintv 我使用了 chmod 777 test.o - Nayana Adassuriya
@The Mask:我已经尝试过那个了。但结果一样。接下来的事情是,“Hello World”程序适用于test.o文件。 - Nayana Adassuriya
2个回答

5
你有几个问题。如果你使用file(1)实用程序来检查输出文件,你会意识到为什么它无法被执行:
$ file test.o
test.o: GCC precompiled header (version 013) for C++

预编译头文件不是有效的可执行文件——它们不是有效的 ELF 文件,也不是带有 shbang 行的脚本文件,它们只是编译器知道如何读取的数据文件。
为什么会得到一个预编译头文件?因为你要求 g++ 编译头文件(.h 文件)。给你的 C++ 源文件 .h 扩展名真的很荒谬,因为它们不是头文件,它们是源文件。给它们正确的 .cc 或 .cpp 扩展名,g++ 将正确地将它们编译为可执行文件。
其次,为什么你要把输出文件命名为test.o.o用于目标文件(单个源文件的编译版本,而不是完整的可执行文件),但你正在要求g++编译完整的可执行文件。如果你只想编译而不链接,则传递-c标志,然后手动将目标文件链接在一起。不要使用.o命名你的可执行文件。test将是从名为test.cc的源文件编译的可执行文件的更合适名称,但我建议使用其他名称,因为test也是一个shell内置函数的名称。

多好的答案!将*.h改为*.cpp,一切都正常工作。 - Nayana Adassuriya

1
当您使用g++编译.h文件时,编译器会生成预编译头文件。这些不是可执行文件。即使您将它们的权限更改为777,它们也无法运行。
https://gcc.gnu.org/onlinedocs/gcc-4.8.3/gcc/Invoking-G_002b_002b.html#Invoking-G_002b_002b中查找此程序还在预编译具有“.h”扩展名的C头文件以供C++编译时使用时非常有用。 尝试以下命令:
g++ -o test.o test1.h
file test.o
您应该得到输出:
test.o:GCC C++预编译头文件(版本014)
要创建一个可执行文件,请将文件重命名为test1.cctest2.cc。然后使用以下命令从它们构建可执行文件:
g++ -o test test1.cc test2.cc
现在,您可以使用以下命令来执行程序:
./test

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接