操作系统检测makefile


249

我通常在几台不同的计算机和几种不同的操作系统上工作,它们是Mac OS X,Linux或Solaris。对于我正在从事的项目,我从远程git存储库中提取代码。

无论我在哪个终端上,我都希望能够从事自己的项目。到目前为止,我已经找到了通过在每次切换计算机时更改makefile来解决操作系统更改的方法。但是,这很繁琐,并且会引起很多头痛。

如何修改我的makefile,以便它检测到我正在使用的操作系统并相应地修改语法?

这是makefile:

cc = gcc -g
CC = g++ -g
yacc=$(YACC)
lex=$(FLEX)

all: assembler

assembler: y.tab.o lex.yy.o
        $(CC) -o assembler y.tab.o lex.yy.o -ll -l y

assembler.o: assembler.c
        $(cc) -o assembler.o assembler.c

y.tab.o: assem.y
        $(yacc) -d assem.y
        $(CC) -c y.tab.c

lex.yy.o: assem.l
        $(lex) assem.l
        $(cc) -c lex.yy.c

clean:
        rm -f lex.yy.c y.tab.c y.tab.h assembler *.o *.tmp *.debug *.acts

Answers:


282

这里已经有很多不错的答案,但是我想分享一个更完整的示例,包括:

  • 不假设unameWindows上存在
  • 还检测处理器

这里定义的CCFLAGS不一定是推荐的或理想的;它们正是我要添加OS / CPU自动检测的项目所使用的。

ifeq ($(OS),Windows_NT)
    CCFLAGS += -D WIN32
    ifeq ($(PROCESSOR_ARCHITEW6432),AMD64)
        CCFLAGS += -D AMD64
    else
        ifeq ($(PROCESSOR_ARCHITECTURE),AMD64)
            CCFLAGS += -D AMD64
        endif
        ifeq ($(PROCESSOR_ARCHITECTURE),x86)
            CCFLAGS += -D IA32
        endif
    endif
else
    UNAME_S := $(shell uname -s)
    ifeq ($(UNAME_S),Linux)
        CCFLAGS += -D LINUX
    endif
    ifeq ($(UNAME_S),Darwin)
        CCFLAGS += -D OSX
    endif
    UNAME_P := $(shell uname -p)
    ifeq ($(UNAME_P),x86_64)
        CCFLAGS += -D AMD64
    endif
    ifneq ($(filter %86,$(UNAME_P)),)
        CCFLAGS += -D IA32
    endif
    ifneq ($(filter arm%,$(UNAME_P)),)
        CCFLAGS += -D ARM
    endif
endif

8
可悲的是,PROCESSOR_ARCHITECTUREenvvar似乎是虚拟化的,具体取决于进程是32位还是64位。因此,如果您make是32位的并且尝试构建64位的应用程序,它将失败。结合使用它PROCESSOR_ARCHITEW6432为我工作(见这个那个
托马斯

4
如果make团队在os和arch上添加几个魔术变量,那就太麻烦了。
亚历克斯(Alex)

6
@JanusTroelsen:是否OS在非Windows系统上设置都没关系。将make未设置的内容与empty相同,这将导致跳转到uname-based块。您只需要在此处添加FreeBSD检查。
Trevor Robinson

3
这也打破了osx。/bin/sh: -c: line 0: syntax error near unexpected token ,Windows_NT'/ bin / sh:-c:第0行:ifeq (,Windows_NT)' make: *** [os] Error 2
k107 2016年

1
@kristi听起来您是作为shell命令而不是在makefile指令上下文中运行它的。
嘲讽了

119

没有参数的uname命令(http://developer.apple.com/documentation/Darwin/Reference/ManPages/man1/uname.1.html)应该告诉您操作系统名称。我会用它,然后根据返回值创建条件。

UNAME := $(shell uname)

ifeq ($(UNAME), Linux)
# do something Linux-y
endif
ifeq ($(UNAME), Solaris)
# do something Solaris-y
endif

为了明确起见,该行会出现在您的Makefile中。我刚刚在Cygwin和OSX的Makefiles中尝试过该构造,它按预期工作。可以尝试的方法:在命令行上键入uname。这将告诉您该操作系统的价值。OSX可能是“达尔文”。
dbrown0708,2009年

GnuWin32项目同时具有uname和Gnu作为本机Windows应用程序可用,使该技术可在命令提示符下以及Windows上的Cygwin移植到MingW。
RBerteig

当它在makefile中时,在我的Solaris机器上失败。uname命令在该系统上可用。
samoz

4
请注意,如果将其放在Maketarget中,则不能缩进。
nylund

4
“:=”语法不是特定于GNU Make的吗?
Ankur Sethi 2012年

40

使用两个简单的技巧来检测操作系统:

  • 首先环境变量 OS
  • 然后uname命令
ifeq ($(OS),Windows_NT)     # is Windows_NT on XP, 2000, 7, Vista, 10...
    detected_OS := Windows
else
    detected_OS := $(shell uname)  # same as "uname -s"
endif

或更安全的方法(如果不在Windows上并且uname不可用):

ifeq ($(OS),Windows_NT) 
    detected_OS := Windows
else
    detected_OS := $(shell sh -c 'uname 2>/dev/null || echo Unknown')
endif

如果您想区分Cygwin / MinGW / MSYS / Windows,Ken Jackson提出了一个有趣的选择。看到他的回答看起来像这样:

ifeq '$(findstring ;,$(PATH))' ';'
    detected_OS := Windows
else
    detected_OS := $(shell uname 2>/dev/null || echo Unknown)
    detected_OS := $(patsubst CYGWIN%,Cygwin,$(detected_OS))
    detected_OS := $(patsubst MSYS%,MSYS,$(detected_OS))
    detected_OS := $(patsubst MINGW%,MSYS,$(detected_OS))
endif

然后,您可以根据以下内容选择相关的内容detected_OS

ifeq ($(detected_OS),Windows)
    CFLAGS += -D WIN32
endif
ifeq ($(detected_OS),Darwin)        # Mac OS X
    CFLAGS += -D OSX
endif
ifeq ($(detected_OS),Linux)
    CFLAGS   +=   -D LINUX
endif
ifeq ($(detected_OS),GNU)           # Debian GNU Hurd
    CFLAGS   +=   -D GNU_HURD
endif
ifeq ($(detected_OS),GNU/kFreeBSD)  # Debian kFreeBSD
    CFLAGS   +=   -D GNU_kFreeBSD
endif
ifeq ($(detected_OS),FreeBSD)
    CFLAGS   +=   -D FreeBSD
endif
ifeq ($(detected_OS),NetBSD)
    CFLAGS   +=   -D NetBSD
endif
ifeq ($(detected_OS),DragonFly)
    CFLAGS   +=   -D DragonFly
endif
ifeq ($(detected_OS),Haiku)
    CFLAGS   +=   -D Haiku
endif

笔记:

  • 命令与之uname相同,uname -s因为选项-s--kernel-name)是默认选项。看看为什么uname -s比更好uname -o

  • 使用OS(而不是uname)简化了识别算法。您仍然可以单独使用uname,但是必须处理if/else块才能检查所有MinGW,Cygwin等的变体。

  • OS始终"Windows_NT"在不同的Windows版本上将环境变量设置为(请参阅%OS%Wikipedia上的环境变量)。

  • OS环境变量的替代方法MSVC(它检查MS Visual Studio的存在,请参阅使用Visual C ++的示例)。


下面,我提供一个使用makegcc构建共享库的完整示例:*.so*.dll取决于平台。该示例越简单越容易理解。

要在Windows上安装make和安装,gcc请参见CygwinMinGW

我的示例基于五个文件

 ├── lib
    └── Makefile
    └── hello.h
    └── hello.c
 └── app
     └── Makefile
     └── main.c

提醒: Makefile使用制表符缩进。复制粘贴到示例文件下方时的警告。

两个Makefile文件

1。 lib/Makefile

ifeq ($(OS),Windows_NT)
    uname_S := Windows
else
    uname_S := $(shell uname -s)
endif

ifeq ($(uname_S), Windows)
    target = hello.dll
endif
ifeq ($(uname_S), Linux)
    target = libhello.so
endif
#ifeq ($(uname_S), .....) #See https://stackoverflow.com/a/27776822/938111
#    target = .....
#endif

%.o: %.c
    gcc  -c $<  -fPIC  -o $@
    # -c $<  => $< is first file after ':' => Compile hello.c
    # -fPIC  => Position-Independent Code (required for shared lib)
    # -o $@  => $@ is the target => Output file (-o) is hello.o

$(target): hello.o
    gcc  $^  -shared  -o $@
    # $^      => $^ expand to all prerequisites (after ':') => hello.o
    # -shared => Generate shared library
    # -o $@   => Output file (-o) is $@ (libhello.so or hello.dll)

2。 app/Makefile

ifeq ($(OS),Windows_NT)
    uname_S := Windows
else
    uname_S := $(shell uname -s)
endif

ifeq ($(uname_S), Windows)
    target = app.exe
endif
ifeq ($(uname_S), Linux)
    target = app
endif
#ifeq ($(uname_S), .....) #See https://stackoverflow.com/a/27776822/938111
#    target = .....
#endif

%.o: %.c
    gcc  -c $< -I ../lib  -o $@
    # -c $<     => compile (-c) $< (first file after :) = main.c
    # -I ../lib => search headers (*.h) in directory ../lib
    # -o $@     => output file (-o) is $@ (target) = main.o

$(target): main.o
    gcc  $^  -L../lib  -lhello  -o $@
    # $^       => $^ (all files after the :) = main.o (here only one file)
    # -L../lib => look for libraries in directory ../lib
    # -lhello  => use shared library hello (libhello.so or hello.dll)
    # -o $@    => output file (-o) is $@ (target) = "app.exe" or "app"

要了解更多信息,请阅读cfi指出的自动变量文档

源代码

-- lib/hello.h

#ifndef HELLO_H_
#define HELLO_H_

const char* hello();

#endif

-- lib/hello.c

#include "hello.h"

const char* hello()
{
    return "hello";
}

-- app/main.c

#include "hello.h" //hello()
#include <stdio.h> //puts()

int main()
{
    const char* str = hello();
    puts(str);
}

构建

修复的复制粘贴Makefile(用一个列表替换前导空格)。

> sed  's/^  */\t/'  -i  */Makefile

make两个平台上的命令相同。给定的输出在类似Unix的操作系统上:

> make -C lib
make: Entering directory '/tmp/lib'
gcc  -c hello.c  -fPIC  -o hello.o
# -c hello.c  => hello.c is first file after ':' => Compile hello.c
# -fPIC       => Position-Independent Code (required for shared lib)
# -o hello.o  => hello.o is the target => Output file (-o) is hello.o
gcc  hello.o  -shared  -o libhello.so
# hello.o        => hello.o is the first after ':' => Link hello.o
# -shared        => Generate shared library
# -o libhello.so => Output file (-o) is libhello.so (libhello.so or hello.dll)
make: Leaving directory '/tmp/lib'

> make -C app
make: Entering directory '/tmp/app'
gcc  -c main.c -I ../lib  -o main.o
# -c main.c => compile (-c) main.c (first file after :) = main.cpp
# -I ../lib => search headers (*.h) in directory ../lib
# -o main.o => output file (-o) is main.o (target) = main.o
gcc  main.o  -L../lib  -lhello  -o app
# main.o   => main.o (all files after the :) = main.o (here only one file)
# -L../lib => look for libraries in directory ../lib
# -lhello  => use shared library hello (libhello.so or hello.dll)
# -o app   => output file (-o) is app.exe (target) = "app.exe" or "app"
make: Leaving directory '/tmp/app'

运行

该应用程序需要知道共享库在哪里。

在Windows上,一个简单的解决方案是将应用程序复制到该库中:

> cp -v lib/hello.dll app
`lib/hello.dll' -> `app/hello.dll'

在类Unix的操作系统上,可以使用LD_LIBRARY_PATH环境变量:

> export LD_LIBRARY_PATH=lib

在Windows上运行命令:

> app/app.exe
hello

在类似Unix的操作系统上运行命令:

> app/app
hello

感谢您的努力,但是主要的问题是检测操作系统。您的示例仅检测到Linux,否则完全假定为Windows。
Shahbaz 2013年

嗨@Shahbaz 没错,我的答案与其他答案没有不同的方法。而且,我的脚本假定平台不是Windows uname而是Windows。我仅举一个您可能不需要的示例,但这可能会帮助某人(在网络上)搜索Makefile为两种平台实现A的方法;-)我应该更改我的答案吗?干杯
olibre

尝试提出正确识别其他操作系统的方法!目的是找到一种不太复杂但更重要的是防弹的方法。也就是说,无论如何都不会犯错误。
2013年

1
@olibre感谢您提供的详细示例,非常感谢并帮助我快速入门。在该lib/Makefile示例中,target用于.soVS .dll。的并行示例对于应用程序文件名app/makefileempty stringvs .exe比较很有用。例如,我通常app.exe在类似Unix的操作系统上看不到。;-)

1
LSF?LFS?错别字?
富兰克林·于

19

我最近正在尝试回答这个问题。这是我的结论:

由于在Windows中,您不能确定该uname命令是否可用,因此可以使用gcc -dumpmachine。这将显示编译器目标。

uname如果要进行交叉编译,使用时可能还会有问题。

以下是可能的输出示例清单gcc -dumpmachine

  • mingw32
  • i686-pc-cygwin
  • x86_64-redhat-linux

您可以像下面这样在makefile中检查结果:

SYS := $(shell gcc -dumpmachine)
ifneq (, $(findstring linux, $(SYS)))
 # Do Linux things
else ifneq(, $(findstring mingw, $(SYS)))
 # Do MinGW things
else ifneq(, $(findstring cygwin, $(SYS)))
 # Do Cygwin things
else
 # Do things for others
endif

它对我来说效果很好,但是我不确定这是获取系统类型的可靠方法。至少它对MinGW可靠,而这正是我所需要的,因为它不需要Windows中具有uname命令或MSYS程序包。

综上所述,uname给你的系统,你正在编译,并gcc -dumpmachine为您提供了系统您的编译。


这是个好的观点。但是,还是不uname附带MinGW吗?尽管如此,有关交叉编译的额外说明还是很棒的。
沙巴兹(Shahbaz)2012年

2
@Shahbaz MinGW安装程序可以安装MSYS(其中包含uname),但这是可选的。仍然可以找到仅使用MinGW gcc工具的系统
phsym 2012年

1
在Clang是OS X和FreeBSD等默认编译器的任何地方都无法使用。
MarcusJ

@SebastianGodelet @MarcusJ一个简单的解决方法是$(shell $(CC) -dumpmachine)。从OS X Sierra开始,-dumpmachine命令可在Clang上使用。
Vortico

在OS X 10.12.5它x86_64-apple-darwin16.6.0和作品阉你怎么称呼它gcccc或者clang,而不是cl
MarcusJ

17

git的生成文件包含如何没有了autoconf / automake的,但仍然对unixy平台的大量工作管理的例子不胜枚举。


13
知道Git不会以某种方式使用Autofools,这让我感到厌恶...
Dan Molding

11
“自欺欺人”?那是故意的错字吗?:)
JesperE 2012年

6
它是。但经过深思熟虑,我认为我更喜欢“ Autostools”。:D
Dan Moulding

顺便说一句,您指的是谁?是Git还是Autotools人?:D
JesperE 2012年

8
英语是一种不精确的语言。怎么样:if (!usesAutotools(git)) aversionTo(autotools) = justified;我还要澄清,这只是我不喜欢的工具。我相信Autotools的人是好人。
Dan Molding 2012年

11

更新:我现在认为这个答案已经过时了。我在下方发布了一个新的完美解决方案。

如果您的makefile可能在非Cygwin Windows上运行,则uname可能不可用。这很尴尬,但这是一个潜在的解决方案。您必须先检查Cygwin才能排除它,因为它的PATH环境变量中也有WINDOWS 。

ifneq (,$(findstring /cygdrive/,$(PATH)))
    UNAME := Cygwin
else
ifneq (,$(findstring WINDOWS,$(PATH)))
    UNAME := Windows
else
    UNAME := $(shell uname -s)
endif
endif

到目前为止,这很好!你能告诉我一件事吗?我不使用Cygwin,但是我在PATH中的bin路径中安装了MinGW。如果我是uname从普通的cmd终端发出的,它将给我MINGW。我的意思是,我仍然uname不使用Cygwin。我也有git bash,但是我还没有尝试过一致(现在我在Linux中)。您能告诉我如何将这两个代码合并到您的代码中吗?
沙巴兹(Shahbaz)2012年

如果您确定uname可用,那是最好的解决方案。但是在我的环境中,每个人都在使用Windows,很少有人安装cygwinmingw,因此我无法保证任何标准甚至都可以使用。我目前在cmd shell中运行make.exe的上述代码遇到一些困难。Windows是一个非常令人沮丧的平台。
肯·杰克逊

我的意思是,在测试PATH中是否存在WINDOWS之前,请确保您未与cygwin打交道,如何确保未与MinGW打交道?例如,在Makefile中是否可以测试命令是否可以运行,如果uname不能运行,我们就会知道我们在Windows中吗?
沙巴兹(Shahbaz)2012年

我也在努力为这个Mingw / cygwin / shell-or-cmd / Linux找到一个干净的解决方案。归根结底,像预制或cmake之类的东西似乎是最好的主意。
艾萨克·尼基特帕斯

这不再是最好的解决方案。我发布的新解决方案通过查找';'来区分本机Windows。在PATH变量中,无需shell调用。
肯·杰克逊

7

这就是GNU的automake / autoconf设计要解决的工作。您可能要对其进行调查。

另外,您可以在不同的平台上设置环境变量,并使Makefile成为条件变量。


11
我强烈建议不要使用automake / autoconf。它们使用起来很麻烦,给您的文件和构建时间增加了很多开销。它们只是增加了复杂性,通常效果很小(系统之间仍然没有可移植性)。
Johannes Overmann

1
我花了几天时间学习make做自己想做的事。我现在是否也想进入automake / autoconf?-不 什么可以在makefile来完成,当然应该在Makefile来完成,如果只让我没有我想修改编译和链接,每次几站客点。
工程师

您的makefile支持几个平台?当您想要移植到许多平台时,automake和autoconf真正发挥了作用。
道格拉斯·里德

2
我不会需要无用的依赖关系,而更改整个构建系统只是为了找出要为其编译的OS。
MarcusJ

7

我终于找到了完美的解决方案,可以为我解决这个问题。

ifeq '$(findstring ;,$(PATH))' ';'
    UNAME := Windows
else
    UNAME := $(shell uname 2>/dev/null || echo Unknown)
    UNAME := $(patsubst CYGWIN%,Cygwin,$(UNAME))
    UNAME := $(patsubst MSYS%,MSYS,$(UNAME))
    UNAME := $(patsubst MINGW%,MSYS,$(UNAME))
endif

UNAME变量设置为Linux,Cygwin,MSYS,Windows,FreeBSD,NetBSD(或可能是Solaris,Darwin,OpenBSD,AIX,HP-UX)或未知。然后可以在整个Makefile的其余部分进行比较,以分隔所有OS敏感变量和命令。

关键是Windows使用分号来分隔PATH变量中的路径,而其他所有人都使用冒号。(可以使用名称中带有';'的Linux目录,然后将其添加到PATH中,这可能会破坏此记录,但是谁会这样做呢?)这似乎是检测本机Windows风险最小的方法,因为它可以不需要shell调用。Cygwin和MSYS PATH使用冒号,因此需要使用uname

请注意,OS环境变量可用于检测Windows,但不能区分Cygwin和本机Windows。测试报价的回声是可行的,但是它需要shell调用。

不幸的是,Cygwin在uname的输出中添加了一些版本信息,因此我添加了“ patsubst”调用,将其更改为“ Cygwin”。另外,MSYS的uname实际上具有以MSYS或MINGW开头的三个可能的输出,但是我也使用patsubst来将它们全部转换为'MSYS'。

如果区分在路径上有无uname.exe的本机Windows系统很重要,则可以使用此行代替简单的分配:

UNAME := $(shell uname 2>NUL || echo Windows)

当然,在所有情况下都需要GNU make,或者需要其他支持所使用功能的make


6

我今天遇到了这个问题,我在Solaris上需要它,因此这是POSIX标准方法(非常接近)。

#Detect OS
UNAME = `uname`

# Build based on OS name
DetectOS:
    -@make $(UNAME)


# OS is Linux, use GCC
Linux: program.c
    @SHELL_VARIABLE="-D_LINUX_STUFF_HERE_"
    rm -f program
    gcc $(SHELL_VARIABLE) -o program program.c

# OS is Solaris, use c99
SunOS: program.c
    @SHELL_VARIABLE="-D_SOLARIS_STUFF_HERE_"
    rm -f program
    c99 $(SHELL_VARIABLE) -o program program.c

1
在OSX上获取错误:“ Makefile:22:***缺少分隔符。停止。”。在这行上:“-@ make $(UNAME_S)”。
Czarek Tomczak 2014年

OSX可能不兼容,因此请按顺序尝试。(1)确保使用TAB作为行上的第一个字符(2)删除make前面的“-@”(2a)如果2起作用,请先尝试一个字符,然后再尝试另一个(3)确保已定义UNAME_S,请尝试回显$(UNAME_S)而不是-@ make $(UNAME_S)
Huckle

6

这是一个简单的解决方案,用于检查您是否处于Windows或posix式(Linux / Unix / Cygwin / Mac)环境中:

ifeq ($(shell echo "check_quotes"),"check_quotes")
   WINDOWS := yes
else
   WINDOWS := no
endif

它利用了类似posix的环境和Windows环境中都存在echo的事实,并且在Windows中shell不过滤引号。


1
$PATHecho
很不

@YoYoYonnY为什么您的路径引用了另一个回声?似乎是非常不可能的情况。
塞缪尔

1
并不是真的,git做到了,mingw做到了,cygwin做到了……我个人将C:\ Windows \ System32放在路径的底部。
yyny

1
这个“解决方案”对所有环境都“有效”,但是我的观点是,这种定义并不能安全地检测到窗户。如果要设置-mwindows标志或在.dll或之间进行选择.so,则此操作将失败。
yyny

1
@YoYoYonnY感谢您的澄清。在我的情况下,仅当我在Cygwin或Windows或Linux环境中时才关心,而不是在我所使用的操作系统中,因此这对我很有帮助。听起来您的需求与我的需求不同。
塞缪尔

3

请注意,Makefile对间距非常敏感。这是一个Makefile的示例,该文件在OS X上运行一个额外的命令,并在OS X和Linux上运行。总的来说,autoconf / automake是解决所有琐碎问题的方法。

UNAME:= $(shell一致-s)
CPP = g ++
CPPFLAGS = -pthread -ansi -Wall -Werror -pedantic -O0 -g3 -I / nexopia / include
LDFLAGS = -pthread -L / nexopia / lib -lboost_system

标题= data_structures.h http_client.h load.h lock.h search.h server.h thread.h实用工具.h
对象= http_client.o load.o lock.o search.o server.o thread.o utility.o vor.o

全部:vor

清洁:
    rm -f $(对象)vor

vor:$(对象)
    $(CPP)$(LDFLAGS)-o vor $(OBJECTS)
ifeq($(UNAME),达尔文)
    #设置Boost库的位置
    install_name_tool -change libboost_system.dylib /nexopia/lib/libboost_system.dylib vor
万一

%.o:%.cpp $(标题)Makefile
    $(CPP)$(CPPFLAGS)-c $

2

另一种方法是使用“配置”脚本。如果您已经在makefile中使用了一个,则可以使用uname和sed的组合来解决问题。首先,在您的脚本中,执行以下操作:

UNAME=uname

然后,为了将其放入您的Makefile中,请从Makefile.in开始,其内容应类似于

UNAME=@@UNAME@@

在里面。

UNAME=uname在位之后,在配置脚本中使用以下sed命令。

sed -e "s|@@UNAME@@|$UNAME|" < Makefile.in > Makefile

现在,您的makefile应该已经UNAME按需要定义了。仅剩if / elif / else语句!


第一个不应该是这个吗?UNAME = $(uname)
肯·杰克逊

0

我不得不检测两个Fedora版本之间的差异,以调整inkscape的命令行选项:
-在Fedora 31中,默认inkscape为1.0beta,使用--export-file
-在Fedora <31中,默认inkscape为0.92使用--export-pdf

我的Makefile包含以下内容

# set VERSION_ID from /etc/os-release

$(eval $(shell grep VERSION_ID /etc/os-release))

# select the inkscape export syntax

ifeq ($(VERSION_ID),31)
EXPORT = export-file
else
EXPORT = export-pdf
endif

# rule to convert inkscape SVG (drawing) to PDF

%.pdf : %.svg
    inkscape --export-area-drawing $< --$(EXPORT)=$@

这行得通,因为/etc/os-release其中包含一行

VERSION_ID=<value>

因此Makefile中的shell命令返回字符串VERSION_ID=<value>,然后eval命令对此进行操作以设置Makefile变量VERSION_ID。显然,可以根据其他元数据的存储方式对其他操作系统进行调整。请注意,在Fedora中,没有提供OS版本的默认环境变量,否则我会使用它!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.