首頁 運維 linux運維 linux中gmake是什麼

linux中gmake是什麼

Nov 09, 2022 pm 07:04 PM
linux

在linux中,gmake就是GUN make,是一種流行的、常用的用於構建C語言軟體的程序,用於構建Linux內核和其他常用的GNU/Linux程序和軟體庫。 GNU Make是一個可以自動執行shell命令並幫助執行重複任務的程式;它通常用於將檔案轉換成其他形式,例如將原始程式碼檔案編譯成程式或程式庫。

linux中gmake是什麼

本教學操作環境:linux7.3系統、Dell G3電腦。

gmake就是GUN make,因為在linux外的平台上,make一般被佔用了,所以GUN make只好叫gmake了。

GNU Make是一種流行的、常用的用於建構C語言軟體的程式。用於建構Linux核心和其他常用的GNU/Linux程式和軟體庫。

大多數嵌入式軟體開發人員在職業生涯中的某個時候都會使用GNU Make,要么使用它來編譯小型庫,要么建立整個專案。儘管有很多很多的選項可以取代Make,但是由於它的特性集和廣泛的支持,它仍然通常被選擇為新軟體的建構系統。

本文解釋了GNU Make的一般概念和特性,並包括瞭如何最大限度地利用Make構建的建議!這是我最喜歡/最常用的Make概念和功能的簡要介紹.

什麼是GNU Make?

GNU Make是一個可以自動執行shell指令並幫助執行重複任務的程式。它通常用於將檔案轉換成其他形式,例如將原始程式碼檔案編譯成程式或程式庫。

它透過追蹤先決條件和執行命令層次結構來產生目標來實現這一點。

儘管GNU Make手冊很長,但我建議閱讀一下,因為它是我找到的最好的參考:https://www.gnu.org/software/make/manual/html_node/index. html

何時選擇Make

Make適用於建置小型C/ c 專案或函式庫,這些專案或函式庫將包含在另一個項目的建構系統中。大多數建置系統都有辦法整合基於make的子專案。

對於較大的項目,您會發現更現代的建置系統更容易使用。

在以下情況下,我建議使用非Make的建置系統:

當正在建置的目標(或檔案)數量為(或最終將為)數百時。需要一個「配置」步驟,它設定和保存變數、目標定義和環境配置。此專案將保持內部或私有,將不需要由終端使用者建置。您會發現調試是一項令人沮喪的工作。您需要建立的是跨平台的,可以在macOS、Linux和Windows上建置。在這些情況下,您可能會發現使用CMake、Bazel、Meson或其他現代建置系統是一種更愉快的體驗。

呼叫Make

執行make將從目前目錄載入名為Makefile的文件,並嘗試更新預設目標(稍後會詳細介紹目標)。

Make將依序搜尋名為GNUmakefile、makefile和makefile的檔案

你可以使用-f/-file參數指定一個特定的makefile:

#$ make - f foo.mk 你可以指定任意數量的目標,列出它們作為位置參數:

#典型目標$ make clean all 你可以用-C參數傳遞Make目錄,它會運行Make,就像它首先被cd到那個目錄一樣。

$ make -C some/sub/directory 有趣的事實:git也可以和-C一起運行,達到同樣的效果!

並行呼叫

如果提供-j或-l選項,Make可以並行運行作業。我被告知的一個指導原則是,將作業限制設定為處理器核心數量的1.5倍:

#a machine with 4 cores: make -j make -j 有趣的是,我發現使用-l“負載限制”選項的CPU利用率比使用-j“工作”選項略好。儘管YMMV !

有幾種方法可以透過程式設計方式找到目前機器的CPU計數。一個簡單的方法是使用python multiprocessing.cpu_count()函數來獲得支援的系統的線程數量(注意與超線程系統,這將消耗大量的計算機資源,但可能是更可取的讓讓產生無限的工作)。

#在子shell中呼叫python的cpu_count()函數 make -l (python -c "import multiprocessing;print (multiprocessing.cpu_count())」)

並行呼叫期間的輸出

如果Make正在並行執行的命令有大量輸出,您可能會看到在stdout上交錯輸出。為了處理這個問題,Make有一個選項-output -sync。

我建議使用-output-sync=recurse,它將在每個目標完成時列印recipe的全部輸出,而不會分散其他recipe輸出。

如果recipe使用遞迴Make,它也會一起輸出整個遞歸Make的輸出。

對Makefile的剖析 Makefile包含用於產生目標的規則。 Makefile的一些基本元件如下所示:

#Comments are prefixed with the '#' symbol

#A variable assignment
FOO = "hello there!"

#A rule creating target "test", with "test.c" as a prerequisite
test: test.c
 # The contents of a rule is called the "recipe", and is
 # typically composed of one or more shell commands.
 # It must be indented from the target name (historically with
 # tabs, spaces are permitted)

 # Using the variable "FOO"
 echo $(FOO)

 # Calling the C compiler using a predefined variable naming
 # the default C compiler, '$(CC)'
 $(CC) test.c -o test
登入後複製

讓我們看看上面範例的每個部分。

變數

變數使用語法$(FOO),其中FOO是變數名稱。

變數包含純字串,因為Make沒有其他資料類型。附加到一個變數將會新增一個空格和新的內容:

FOO = one
FOO += two
# FOO is now "one two"

FOO = one
FOO = $(FOO)two
# FOO is now "onetwo"
登入後複製

#變數賦值

##在GNU Make語法中,變數的賦值方式有兩種:

右邊的表達式是逐字賦值給變數的-這很像C/ c 中的宏,在使用變數時對表達式求值:

FOO = 1
BAR = $(FOO)
FOO = 2
# prints BAR=2
$(info BAR=$(BAR))
登入後複製
將一個表達式的結果賦值給一個變數;表達式在賦值時展開:

FOO = 1
BAR := $(FOO)
FOO = 2
# prints BAR=1
$(info BAR=$(BAR))
登入後複製
注意:上面的$(info …)函數用於列印表達式,在偵錯makefile時非常方便!*'

未明確、隱式或未自動設定的變數將計算為空字串。

環境變數

環境變數被攜帶到Make執行環境中。以下面的makefile為例:

$(info YOLO variable = $(YOLO))
登入後複製
如果我們在執行make時在shell指令中設定了變數YOLO,我們將設定這個值:

$ YOLO="hello there!" make
YOLO variable = hello there!
make: *** No targets.  Stop.
登入後複製
注意:Make印出「No targets」錯誤,因為我們的makefile沒有列出目標!

如果你使用?=賦值語法,Make只會在變數沒有值的情況下賦值:

Makefile:

#默认CC为gcc
CC ? = gcc
登入後複製
然後我們可以重寫makefile中的$(CC):

$ CC=clang make

另一個常見的模式是允許插入額外的標誌。在makefile中,我們將追加變數而不是直接賦值給它。

CFLAGS = -Wall

這允許從環境中傳入額外的標誌:

$ CFLAGS='-Werror=conversion -Werror=double-promotion' make
登入後複製
這是非常有用的!

最重要的變數

變數所使用的一個特殊類別稱為覆蓋變數。使用此命令列選項將覆蓋設定在環境中的或Makefile中的值!

Makefile:

# any value set elsewhere
YOLO = "not overridden"
$(info $(YOLO))
登入後複製
命令:

##

# setting "YOLO" to different values in the environment + makefile + overriding
# variable, yields the overriding value
$ YOLO="environment set" make YOLO='overridden!!'
overridden!!
make: *** No targets.  Stop.
登入後複製

有針對性的變數這些變數只在recipe上下文中可用。它們也適用於任何必備配方!

# set the -g value to CFLAGS
# applies to the prog.o/foo.o/bar.o recipes too!
prog : CFLAGS = -g
prog : prog.o foo.o bar.o
 echo $(CFLAGS) # will print '-g'
登入後複製

隱含變數這些都是由Make預先定義的(除非用同名的任何其他變數類型重寫)。一些常見的例子:

$(CC) - the C compiler (gcc)
$(AR) - archive program (ar)
$(CFLAGS) - flags for the C compiler
Full list here:

https://www.gnu.org/software/make/manual/html_node/Implicit-Variables.html
登入後複製

自動變數這些是Make設定的特殊變量,在recipe上下文中可用。它們對於防止重複的名字很有用(Don 't Repeat Yourself)。

一些常見的自動變數:

# $@ : the target name, here it would be "test.txt"
test.txt:
 echo HEYO > $@

# $^ : name of all the prerequisites
all.zip: foo.txt test.txt
 # run the gzip command with all the prerequisites "$^", outputting to the
 # name of the target, "$@"
 gzip -c $^ > $@
See more at: https://www.gnu.org/software/make/manual/html_node/Automatic-Variables.html
登入後複製

#目標(目標)目標是規則語法的左邊:

arget: prerequisite
 recipe
登入後複製
target幾乎總是命名檔案。這是因為Make使用最後修改時間來追蹤target是否比其prerequistite更新或更早,以及是否需要重新建構它!

當呼叫Make時,你可以透過將其指定為位置參數來指定想要建構的target:

# make the 'test.txt' and 'all.zip' targets
make test.txt all.zip
登入後複製

如果您没有在命令中指定目标,Make将使用makefile中指定的第一个目标,称为“默认目标”(如果需要,也可以覆盖默认目标)。

虚假phony目标

有时候设置元目标是很有用的,比如all, clean, test等等。在这些情况下,您不希望Make检查名为all/clean等的文件。

Make提供.PHONY目标语法,将目标标记为不指向文件:

假设我们的项目构建了一个程序和一个库foo和foo.a;如果我们想要 在默认情况下,我们可以创建一个'all'规则来构建两者 .PHONY:all all : foo foo.a

如果你有多个假目标,一个好的模式可能是将每个目标都附加到定义它的.PHONY中:

# the 'all' rule that builds and tests. Note that it's listed first to make it
# the default rule
.PHONY: all
all: build test

# compile foo.c into a program 'foo'
foo: foo.c
 $(CC) foo.c -o foo

# compile foo-lib.c into a library 'foo.a'
foo.a: foo-lib.c
 # compile the object file
 $(CC) foo-lib.c -c foo-lib.o
 # use ar to create a static library containing our object file. using the
 # '$@' variable here to specify the rule target 'foo.a'
 $(AR) rcs $@ foo-lib.o

# a phony rule that builds our project; just contains a prerequisite of the
# library + program
.PHONY: build
build: foo foo.a

# a phony rule that runs our test harness. has the 'build' target as a
# prerequisite! Make will make sure (pardon the pun) the build rule executes
# first
.PHONY: test
test: build
 ./run-tests.sh
登入後複製

请注意! !. phony目标总是被认为是过期的,因此Make将总是运行这些目标的配方(因此也运行任何具有. phony先决条件的目标!)小心使用! !

隐式规则

隐含规则由Make提供。我发现使用它们会让人感到困惑,因为在幕后发生了太多的行为。你偶尔会在野外遇到它们,所以要小心。

# this will compile 'test.c' with the default $(CC), $(CFLAGS), into the program
# 'test'. it will handle prerequisite tracking on test.c
test: test.o
Full list of implicit rules here:

https://www.gnu.org/software/make/manual/html_node/Catalogue-of-Rules.html
登入後複製

模式的规则

模式规则允许你编写一个通用规则,通过模式匹配应用于多个目标:

# Note the use of the '$<&#39; automatic variable, specifying the first
# prerequisite, which is the .c file
%.o: %.c
 $(CC) -c $< -o $@
登入後複製

or

OBJ_FILES = foo.o bar.o

# Use CC to link foo.o + bar.o into &#39;program&#39;. Note the use of the &#39;$^&#39;
# automatic variable, specifying ALL the prerequisites (all the OBJ_FILES)
# should be part of the link command
program: $(OBJ_FILES)
    $(CC) -o $@ $^
登入後複製

先决条件

如上所述,Make将在运行规则之前检查这些目标。它们可以是文件或其他目标。

如果任何先决条件比目标更新(修改时间),Make将运行目标规则。

在C项目中,你可能有一个将C文件转换为目标文件的规则,如果C文件发生变化,你希望目标文件重新生成:

foo.o: foo.c
 # use automatic variables for the input and output file names
 $(CC) $^ -c $@
登入後複製

自动的先决条件

对于C语言项目来说,一个非常重要的考虑是,如果C文件的#include头文件发生了变化,那么将触发重新编译。这是通过gcc/clang的-M编译器标志完成的,它将输出一个.d文件,然后用Make include指令导入。

.d文件将包含.c文件的必要先决条件,因此任何头文件的更改都会导致重新构建。

点击这里查看更多详情:

https://www.gnu.org/software/make/manual/html_node/Automatic-Prerequisites.html

http://make.mad-scientist.net/papers/advanced-auto-dependency-generation/

基本形式可能是:

# these are the compiler flags for emitting the dependency tracking file. Note
# the usage of the &#39;$<&#39; automatic variable
DEPFLAGS = -MMD -MP -MF $<.d

test.o: test.c
    $(CC) $(DEPFLAGS) $< -c $@

# bring in the prerequisites by including all the .d files. prefix the line with
# &#39;-&#39; to prevent an error if any of the files do not exist
-include $(wildcard *.d)
登入後複製

Order-only 先决条件

这些先决条件只有在不存在的情况下才会构建;如果它们比目标更新,则不会触发目标重新构建。

典型的用法是为输出文件创建一个目录;将文件发送到目录将更新其mtime属性,但我们不希望由此触发重新构建。

OUTPUT_DIR = build

# output the .o to the build directory, which we add as an order-only
# prerequisite- anything right of the | pipe is considered order-only
$(OUTPUT_DIR)/test.o: test.c | $(OUTPUT_DIR)
 $(CC) -c $^ -o $@

# rule to make the directory
$(OUTPUT_DIR):
 mkdir -p $@
登入後複製

recipe

“recipe”是创建目标时要执行的shell命令列表。它们被传递到子shell中(默认为/bin/sh)。如果target在recipe运行后更新,则认为规则是成功的(但如果没有更新,则不视为错误)。

foo.txt:
 # a simple recipe
 echo HEYO > $@
登入後複製

如果配方中的任何一行返回非零退出代码,Make将终止并打印一条错误消息。你可以通过前缀-字符来告诉Make忽略非零退出码:

.PHONY: clean
clean:
 # we don't care if rm fails
 -rm -r ./build
登入後複製

在recipe行前面加上@将禁止在执行之前echo该行:

clean:
 @# this recipe will just print 'About to clean everything!'
 @# prefixing the shell comment lines '#' here also prevents them from
 @# appearing during execution
 @echo About to clean everything!
登入後複製

Make会在运行recipe上下文中展开变量/函数表达式,但不会处理它。如果你想访问shell变量,请使用$:

USER = linus

print-user:
 # print out the shell variable $USER
 echo $$USER

 # print out the make variable USER
 echo $(USER)
登入後複製

function

Make函数的调用语法如下:

$(function-name arguments) 其中arguments是用逗号分隔的参数列表。

For example:

FILES=$(wildcard *.c)

# you can combine function calls; here we strip the suffix off of $(FILES) with
# the $(basename) function, then add the .o suffix
O_FILES=$(addsuffix .o,$(basename $(FILES)))

# note that the GNU Make Manual suggests an alternate form for this particular
# operation:
O_FILES=$(FILES:.c=.o)
登入後複製

用户定义函数

reverse = $(2) $(1)

foo = $(call reverse,a,b)

# recursive wildcard (use it instead of $(shell find . -name '*.c'))
# taken from https://stackoverflow.com/a/18258352
rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d))

C_FILES = $(call rwildcard,.,*.c)
登入後複製

shell函数

你可以让Make调用一个shell表达式并捕获结果:

TODAYS_DATE=$(shell date --iso-8601)

不过,我在使用这个功能时很谨慎;它会增加对你使用的任何程序的依赖,所以如果你正在调用更奇特的程序,确保你的构建环境是受控的(例如在容器中或使用Conda)。

make的条件表达式

FOO=yolo
ifeq ($(FOO),yolo)
$(info foo is yolo!)
else
$(info foo is not yolo :( )
endif

# testing if a variable is set; unset variables are empty
ifneq ($(FOO),)  # checking if FOO is blank
$(info FOO is unset)
endif

# "complex conditional"
ifeq ($(FOO),yolo)
$(info foo is yolo)
else ifeq ($(FOO), heyo)
$(info foo is heyo)
else
$(info foo is not yolo or heyo :( )
endif
登入後複製

make include

sources.mk:

SOURCE_FILES :=
bar.c
foo.c \

Makefile:

include sources.mk

OBJECT_FILES = $(SOURCE_FILES:.c=.o)

%.o: %.c (CC) -c ^ -o $@

make eval

# generate rules for xml->json in some weird world
FILES = $(wildcard inputfile/*.xml)

# create a user-defined function that generates rules
define GENERATE_RULE =
$(eval
# prereq rule for creating output directory
$(1)_OUT_DIR = $(dir $(1))/$(1)_out
$(1)_OUT_DIR:
 mkdir -p $@

# rule that calls a script on the input file and produces $@ target
$(1)_OUT_DIR/$(1).json: $(1) | $(1)_OUT_DIR
 ./convert-xml-to-json.sh $(1) $@
)

# add the target to the all rule
all: $(1)_OUT_DIR/$(1).json
endef

# produce the rules
.PHONY: all
all:

$(foreach file,$(FILES),$(call GENERATE_RULE,$(file)))
登入後複製

请注意,使用Make的这个特性的方法可能会让人很困惑,添加一些有用的注释来解释意图是什么,对您未来的自己会很有用!

VPATH

VPATH是一个特殊的Make变量,它包含Make在查找先决条件和目标时应该搜索的目录列表。

它可以用来将对象文件或其他派生文件发送到./build目录中,而不是把src目录弄得乱七八糟:

# This makefile should be invoked from the temporary build directory, eg:
# $ mkdir -p build && cd ./build && make -f ../Makefile

# Derive the directory containing this Makefile
MAKEFILE_DIR = $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))

# now inform Make we should look for prerequisites from the root directory as
# well as the cwd
VPATH += $(MAKEFILE_DIR)

SRC_FILES = $(wildcard $(MAKEFILE_DIR)/src/*.c)

# Set the obj file paths to be relative to the cwd
OBJ_FILES = $(subst $(MAKEFILE_DIR)/,,$(SRC_FILES:.c=.o))

# now we can continue as if Make was running from the root directory, and not a
# subdirectory

# $(OBJ_FILES) will be built by the pattern rule below
foo.a: $(OBJ_FILES)
 $(AR) rcs $@ $(OBJ_FILES)

# pattern rule; since we added ROOT_DIR to VPATH, Make can find prerequisites
# like `src/test.c` when running from the build directory!
%.o: %.c
 # create the directory tree for the output file  
 echo $@
 mkdir -p $(dir $@)
 # compile
 $(CC) -c $^ -o $@
登入後複製

touch file

# our tools are stored in tools.tar.gz, and downloaded from a server
TOOLS_ARCHIVE = tools.tar.gz
TOOLS_URL = https://httpbin.org/get

# the rule to download the tools using wget
$(TOOLS_ARCHIVE):
 wget $(TOOLS_URL) -O $(TOOLS_ARCHIVE)

# rule to unpack them
tools-unpacked.dummy: $(TOOLS_ARCHIVE)
 # running this command results in a directory.. but how do we know it
 # completed, without a file to track?
 tar xzvf $^
 # use the touch command to record completion in a dummy file
 touch $@
登入後複製

调试makefile

对于小问题,我通常使用printf的Make等效函数,即$(info/warning/error)函数,例如当检查不工作的条件路径时:

ifeq ($(CC),clang)
$(error whoops, clang not supported!)
endif
登入後複製

要调试为什么规则在不应该运行的情况下运行(或者相反),可以使用——debug选项:https://www.gnu.org/software/make/manual/html_node/Options-Summary.html

我建议在使用此选项时将stdout重定向到文件,它会产生大量输出。

profile

For profiling a make invocation (e.g. for attempting to improve compilation times), this tool can be useful:

https://github.com/rocky/remake

Check out the tips here for compilation-related performance improvements:

https://interrupt.memfault.com/blog/improving-compilation-times-c-cpp-projects

verbose flag

# Makefile for building the 'example' binary from C sources

# Verbose flag
ifeq ($(V),1)
Q :=
else
Q := @
endif

# The build folder, for all generated output. This should normally be included
# in a .gitignore rule
BUILD_FOLDER := build

# Default all rule will build the 'example' target, which here is an executable
.PHONY:
all: $(BUILD_FOLDER)/example

# List of C source files. Putting this in a separate variable, with a file on
# each line, makes it easy to add files later (and makes it easier to see
# additions in pull requests). Larger projects might use a wildcard to locate
# source files automatically.
SRC_FILES = \
    src/example.c \
    src/main.c

# Generate a list of .o files from the .c files. Prefix them with the build
# folder to output the files there
OBJ_FILES = $(addprefix $(BUILD_FOLDER)/,$(SRC_FILES:.c=.o))

# Generate a list of depfiles, used to track includes. The file name is the same
# as the object files with the .d extension added
DEP_FILES = $(addsuffix .d,$(OBJ_FILES))

# Flags to generate the .d dependency-tracking files when we compile.  It's
# named the same as the target file with the .d extension
DEPFLAGS = -MMD -MP -MF $@.d

# Include the dependency tracking files
-include $(DEP_FILES)

# List of include dirs. These are put into CFLAGS.
INCLUDE_DIRS = \
    src/

# Prefix the include dirs with '-I' when passing them to the compiler
CFLAGS += $(addprefix -I,$(INCLUDE_DIRS))

# Set some compiler flags we need. Note that we're appending to the CFLAGS
# variable
CFLAGS += \
    -std=c11 \
    -Wall \
    -Werror \
    -ffunction-sections -fdata-sections \
    -Og \
    -g3

# Our project requires some linker flags: garbage collect sections, output a
# .map file
LDFLAGS += \
    -Wl,--gc-sections,-Map,$@.map

# Set LDLIBS to specify linking with libm, the math library
LDLIBS += \
    -lm

# The rule for compiling the SRC_FILES into OBJ_FILES
$(BUILD_FOLDER)/%.o: %.c
 @echo Compiling $(notdir $<)
 @# Create the folder structure for the output file
 @mkdir -p $(dir $@)
 $(Q) $(CC) $(CFLAGS) $(DEPFLAGS) -c $< -o $@

# The rule for building the executable "example", using OBJ_FILES as
# prerequisites. Since we're not relying on an implicit rule, we need to
# explicity list CFLAGS, LDFLAGS, LDLIBS
$(BUILD_FOLDER)/example: $(OBJ_FILES)
 @echo Linking $(notdir $@)
 $(Q) $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@

# Remove debug information for a smaller executable. An embedded project might
# instead using [arm-none-eabi-]objcopy to convert the ELF file to a raw binary
# suitable to be written to an embedded device
STRIPPED_OUTPUT = $(BUILD_FOLDER)/example-stripped

$(STRIPPED_OUTPUT): $(BUILD_FOLDER)/example
 @echo Stripping $(notdir $@)
 $(Q)objcopy --strip-debug $^ $@

# Since all our generated output is placed into the build folder, our clean rule
# is simple. Prefix the recipe line with '-' to not error if the build folder
# doesn't exist (the -f flag for rm also has this effect)
.PHONY: clean
clean:
 - rm -rf $(BUILD_FOLDER)
登入後複製

$ V=1 make

make 建議

#讓Make發揮最大作用的建議清單:

target通常應該是真實的文件。當發出子MAKE指令時,總是使用(MAKE)。盡量避免使用.phony目標。如果規則產生任何檔案工件,請考慮將其作為目標,而不是冒名! 盡量避免使用隱含的規則。對於C文件,確保使用.d自動包含追蹤! 小心使用元編程。在規則中使用自動變數。總是嘗試使用@作為食譜輸出路徑,這樣你的規則和Make的路徑就完全相同了。在makefile中自由地使用註釋,特別是在使用了複雜的行為或微妙的語法時。你的同事(還有未來的自己)會感謝你的。使用-j或-l選項並行運行Make ! 盡量避免使用touch命令來追蹤規則完成.

#其他

##您還可能在開放原始碼專案中遇到automake(請尋找./configure腳本)。這是一個產生makefile的相關工具,值得一看(特別是如果您正在編寫需要廣泛移植的C軟體)。

今天有許多GNU Make的競爭者,我鼓勵大家去研究它們。一些例子:

CMake非常流行(Zephyr專案使用了它),值得一看。它讓out-of-tree 建構非常容易Bazel使用宣告式語法(vs. Make的命令式方法) Meson是一個像cmake一樣的元建構器,但預設使用Ninja作為後端,可以非常快速

#相關推薦:《

Linux影片教學

以上是linux中gmake是什麼的詳細內容。更多資訊請關注PHP中文網其他相關文章!

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

vscode需要什麼電腦配置 vscode需要什麼電腦配置 Apr 15, 2025 pm 09:48 PM

VS Code 系統要求:操作系統:Windows 10 及以上、macOS 10.12 及以上、Linux 發行版處理器:最低 1.6 GHz,推薦 2.0 GHz 及以上內存:最低 512 MB,推薦 4 GB 及以上存儲空間:最低 250 MB,推薦 1 GB 及以上其他要求:穩定網絡連接,Xorg/Wayland(Linux)

Linux體系結構:揭示5個基本組件 Linux體系結構:揭示5個基本組件 Apr 20, 2025 am 12:04 AM

Linux系統的五個基本組件是:1.內核,2.系統庫,3.系統實用程序,4.圖形用戶界面,5.應用程序。內核管理硬件資源,系統庫提供預編譯函數,系統實用程序用於系統管理,GUI提供可視化交互,應用程序利用這些組件實現功能。

vscode終端使用教程 vscode終端使用教程 Apr 15, 2025 pm 10:09 PM

vscode 內置終端是一個開發工具,允許在編輯器內運行命令和腳本,以簡化開發流程。如何使用 vscode 終端:通過快捷鍵 (Ctrl/Cmd ) 打開終端。輸入命令或運行腳本。使用熱鍵 (如 Ctrl L 清除終端)。更改工作目錄 (如 cd 命令)。高級功能包括調試模式、代碼片段自動補全和交互式命令歷史。

git怎麼查看倉庫地址 git怎麼查看倉庫地址 Apr 17, 2025 pm 01:54 PM

要查看 Git 倉庫地址,請執行以下步驟:1. 打開命令行並導航到倉庫目錄;2. 運行 "git remote -v" 命令;3. 查看輸出中的倉庫名稱及其相應的地址。

notepad怎麼運行java代碼 notepad怎麼運行java代碼 Apr 16, 2025 pm 07:39 PM

雖然 Notepad 無法直接運行 Java 代碼,但可以通過借助其他工具實現:使用命令行編譯器 (javac) 編譯代碼,生成字節碼文件 (filename.class)。使用 Java 解釋器 (java) 解釋字節碼,執行代碼並輸出結果。

vscode在哪寫代碼 vscode在哪寫代碼 Apr 15, 2025 pm 09:54 PM

在 Visual Studio Code(VSCode)中編寫代碼簡單易行,只需安裝 VSCode、創建項目、選擇語言、創建文件、編寫代碼、保存並運行即可。 VSCode 的優點包括跨平台、免費開源、強大功能、擴展豐富,以及輕量快速。

Linux的主要目的是什麼? Linux的主要目的是什麼? Apr 16, 2025 am 12:19 AM

Linux的主要用途包括:1.服務器操作系統,2.嵌入式系統,3.桌面操作系統,4.開發和測試環境。 Linux在這些領域表現出色,提供了穩定性、安全性和高效的開發工具。

vscode終端命令不能用 vscode終端命令不能用 Apr 15, 2025 pm 10:03 PM

VS Code 終端命令無法使用的原因及解決辦法:未安裝必要的工具(Windows:WSL;macOS:Xcode 命令行工具)路徑配置錯誤(添加可執行文件到 PATH 環境變量中)權限問題(以管理員身份運行 VS Code)防火牆或代理限制(檢查設置,解除限制)終端設置不正確(啟用使用外部終端)VS Code 安裝損壞(重新安裝或更新)終端配置不兼容(嘗試不同的終端類型或命令)特定環境變量缺失(設置必要的環境變量)

See all articles