-2

我正在尝试编译并运行我的 C 程序。该程序使用线程。我正在使用带有 Ubuntu 终端的 WSL 运行 Windows 10。(也尝试使用 Ubuntu 虚拟机)这是我用于所有程序的“默认”Makefile 格式(更改每个程序的名称和标志)

CC=gcc
CFLAGS=-I. -w -pthread
DEPS = v1.h
version1: v1

%.o: %.c $(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS)

v1: v1.o
    $(CC) -o v1 v1.o

这是我第一次在 C 中使用线程,这让我发现了 -pthread。我发现你需要将它添加到标志中(我用 CFLAGS 做了)。出于某种原因,当我在上面运行这个 makefile 时出现错误,找不到 pthread 函数,我注意到修复它的方法是通过更改这一行:

$(CC) -o v1 v1.o -pthread

最后添加 pthread 。所有这一切都让我对标志进行了一些研究,在搜索 gcc 的手册页和谷歌之后,我发现这些问题没有简单的答案:

  1. 为什么我需要将 -pthread 添加到 .o 任务和 .c 任务?为什么仅将其添加到一个还不够?
  2. 什么是 -w 标志?我知道它代表“警告”,但 -w 和 -Wall 之间有什么区别?
  3. 什么是-I。旗帜?再次,我发现它代表“包含”,但我不确定它在做什么。我的 makefile 使用或不使用该标志。

谢谢你。

4

2 回答 2

1

1:为什么我需要在.o 任务和.c 任务中添加-pthread?为什么仅将其添加到一个还不够?

根据man gcc

-pthread 通过 pthreads 库添加对多线程的支持。此选项为预处理器和链接器设置标志。

您需要为-pthreadMakefile 的编译器和链接器部分指定选项:

CC=gcc
CFLAGS=-I. -w -pthread
LDFLAGS=-pthread
DEPS = v1.h
version1: v1

%.o: %.c $(DEPS)
    $(CC) -c -o $@ $< $(CFLAGS)

v1: v1.o
    $(CC) -o v1 v1.o $(LDFLAGS)

2:什么是-w标志?我知道它代表“警告”,但 -w 和 -Wall 之间有什么区别?

检查警告选项信息gcc

-w
    Inhibit all warning messages.
-Wall
    This enables all the warnings about constructions that some users consider
    questionable, and that are easy to avoid (or modify to prevent the
    warning), even in conjunction with macros. This also enables some
    language-specific warnings described in C++ Dialect Options and
    Objective-C and Objective-C++ Dialect Options. 
-Wextra
    This enables some extra warning flags that are not enabled by -Wall.
    (This option used to be called -W. The older name is still supported,
    but the newer name is more descriptive.) 

基本上,-w禁用所有警告。请谨慎使用。我建议你-Wall改用。

3:什么是-I。旗帜?

检查目录搜索信息的选项gcc

-I dir
-iquote dir
-isystem dir
-idirafter dir
    Add the directory dir to the list of directories to be searched for
    header files during preprocessing.

-I.Makefile 中的选项指示编译器也在 Makefile 目录中查找头文件。.在 Linux 世界中代表当前目录

于 2020-05-25T10:38:57.683 回答
1

为什么我需要将 -pthread 添加到 .o 任务和 .c 任务?

因为您使用 posix 线程库中的函数。


为什么仅将其添加到一个还不够?

因为编译器(编译.c成的.o)和链接器(它将多个链接.o到一个可执行文件)都需要了解这些函数。编译器检查函数是否存在于库中,链接器将您在代码中使用的正确函数连接到库中的符号。


什么是 -w 标志?

来自man gcc

-w 禁止所有警告消息。

请不要使用-w. 通常-Wall -Wextra用于启用所有可能的警告并在编译时捕获尽可能多的问题。


我知道它代表“警告”,但 -w 和 -Wall 之间有什么区别?

-w禁用警告,-Wall启用指定的警告列表


什么是-I。旗帜?

来自man gcc

-我目录

将目录 dir 添加到预处理期间要搜索头文件的目录列表中。

它将目录添加到预处理器的搜索路径中。preprocessos 的工作之一是找到 where #include <this files are>#include在“预处理器搜索路径”中搜索语句中的文件。-I将路径添加到此列表。


是 LDFLAGS 还是 LDFLAGS?

makefile手册它是LDFLAGS....

LDFLAGS 代表什么?

ld标志。


旁注:This is my "default" Makefile format im using for all my programs make是一位老爷爷——已经 40 多岁了。我建议学习一个在当今世界更容易处理的构建系统,比如cmake.

于 2020-05-25T10:48:29.680 回答