5

我尝试使用文件 main.cpp、factorial.cpp、hello.cpp 和 function.h 创建一个 Makefile 在 Linux 命令窗口上键入“make”时,它显示:

g++ -c -o hello main.o factorial.o hello.o
g++: main.o: linker input file unused because linking not done
g++: factorial.o: linker input file unused because linking not done
g++: hello.o: linker input file unused because linking not done

我是第一次制作 Makefile。请提出建议可能是什么问题?Makefile 包含以下代码->

hello: main.o factorial.o hello.o
        g++ -c -o hello main.o factorial.o hello.o

main.o: main.cpp
        g++ -c -o main.o main.cpp

factorial.o: factorial.cpp
        g++ -c -o factorial.o factorial.cpp

hello.o: hello.cpp
        g++ -c -o hello.o hello.cpp

如果您想查看单个文件内容:1)main.cpp

#include<iostream>
#include"functions.h"
using namespace std;
int main()
{
    print_hello();
    cout << endl;
    cout << "The factorial of 5 is " << factorial(5) << endl;
    return 0;
}

2) 你好.cpp

#include<iostream>
#include "functions.h"
using namespace std;

void print_hello()
{
    cout << "Hello World!";
}

3) 阶乘.cpp

#include "functions.h"

int factorial(int n)
{
    if(n!=1)
    {
        return(n * factorial(n-1));
    }
    else return 1;
}

4) 函数.h

 void print_hello();  
 int factorial(int n);
4

4 回答 4

7

告诉它不要链接的-c参数:g++

-c 编译或汇编源文件,但不链接。链接阶段根本没有完成。最终输出是每个源文件的目标文件形式。

你绝对不想要-c这里:

hello: main.o factorial.o hello.o
        g++ -c -o hello main.o factorial.o hello.o
于 2013-08-12T05:46:15.007 回答
5

您还可以使用规则和模式使其更通用:

SRC_DIR = ./src
OBJ_DIR = ./bin/obj
BIN_DIR = ./build/bin

# List all the sources
SRCS = A.cpp B.cpp

# Define the rule to make object file from cpp
$(OBJ_DIR)/%.o : $(SRC_DIR)/%.cpp
    g++ -o $@ $(INCLUDES) $(CPPFLAGS) -c $^

TARGET_BIN = $(BIN_DIR)/test

all : make_dirs $(TARGET_BIN)

$(TARGET_BIN) : $(SRCS:%.cpp=$(OBJ_DIR)/%.o)
    g++ $(LDFLAGS) -o $@ $^ $(LDLIBS)

make_dirs :
    mkdir -p $(OBJ_DIR)
    mkdir -p $(BIN_DIR)

使用这种方法,您有几个好处:

  • 易于使用:您只需指定一次源文件,而无需关心每个目标文件的处理:工作由单一规则完成。

  • 更易于维护:每次您需要更改编译器或链接器选项时,您都在单个规则中进行,而不是针对每个翻译单元。

于 2013-08-12T05:55:06.933 回答
3

您在该行中有一个错误:

    g++ -c -o hello main.o factorial.o hello.o

人 gcc 说:... the -c option says not to run the linker.

此选项仅用于生成对象文件。当它通过时,gcc 将不会启动链接器来生成可执行文件或共享库。

于 2013-08-12T05:49:40.027 回答
2

从以上所有答案中可以清楚地看出,由于使用-cin g++ -c -o hello main.o factorial.o hello.o,它阻止了链接。从相应的 .cpp 或 .h 等文件创建目标文件后,需要链接这些文件。在没有链接的情况下,由于每个文件都是可以执行某些任务的完整程序的一部分,因此无法完成任何有用的操作,因为这些文件是依赖的。所以,我们必须链接这些依赖的部分来运行我们的完整程序。

一个基本的视频教程,用于轻松学习以两种方法(即依赖项和模式规则)制作 Makefile 在这里。它以依赖方法为例,然后引入模式规则作为制作长 Makefile 的更好方法。


要了解编译和链接之间的区别,此链接可能很有用。

于 2013-08-14T04:25:58.727 回答