0%

Options

npm root - Current installation root path.
npm root -g - The global installation root path.
npm uninstall - After executing this command, you should also remove the items in the package.json file and delete the package-lock.json file and the node_modules directory.

Reference

Where does npm install packages?
Cannot Uninstall two npm Packages

安装

sudo apt install net-tools

手册

man 7 socket - socket options
man 7 tcp - tcp options

文件系统

/proc/sys/net/ipv4/ip_local_port_range

概念

网关(Gateway)

网关(Gateway)是一个网络节点,它充当其他网络之间的访问点或网关。网关通常用于连接不同的网络,并且可以在不同的协议之间进行转换。网关设备可以是路由器、服务器或其他网络设备。当本地网络中的设备需要与外部网络通信时,它们会将数据包发送到网关,网关再将数据包转发到目标网络。

举例: 假设你的本地网络使用的IP地址范围是192.168.1.0/24,而你的网关IP地址是192.168.1.1。当你的计算机需要访问外部网络(例如互联网)时,它会将数据包发送到网关(192.168.1.1),然后由网关将数据包转发到目标网络。

在Linux系统中,你可以使用ip route命令查看默认网关。例如:

在这个例子中,default via 192.168.1.1 dev eth0表示默认网关是192.168.1.1,你的计算机通过网络接口eth0与网关连接。

子网(CIDR表示法)

CIDR(Classless Inter-Domain Routing,无类别域间路由)是一种用于分配IP地址和路由的标准,使用斜杠(/)后跟一个数字来表示子网掩码的位数。

在CIDR表示法中,192.168.1.0/24表示一个子网,其中/24表示子网掩码为255.255.255.0。这意味着子网中有256个IP地址(从0到255),但其中两个地址是保留的:

  1. 网络地址192.168.1.0,用于标识子网本身。
  2. 广播地址192.168.1.255,用于向子网中的所有设备发送广播消息。

因此,有效的主机IP地址范围是从192.168.1.1192.168.1.254,共254个可用的IP地址。

The link-local address range refers to IP addresses that are used for communication within a single network segment or link. These addresses are not routable, meaning they are not intended to be used for communication beyond the local network segment.

For IPv4, the link-local address range is 169.254.0.0/16. This range is automatically assigned to network interfaces when no other IP address is available (e.g., when DHCP fails). Devices on the same local network can communicate with each other using these addresses without requiring a router.

For IPv6, the link-local address range is fe80::/10. These addresses are automatically configured on all IPv6-enabled interfaces and are used for local network communication.

The IP address range 169.254.0.0/16 is regarded as link-local because it is reserved for link-local addresses by the Internet Assigned Numbers Authority (IANA). These addresses are used for communication within a single network segment or link and are not routable beyond that segment.

Characteristics of Link-Local Addresses:

  • Automatic Assignment: Devices automatically assign themselves an IP address from the 169.254.0.0/16 range if they cannot obtain an IP address through DHCP.
  • Non-Routable: These addresses are not meant to be routed across different network segments. They are only valid within the local network.
  • Zero Configuration: Link-local addresses allow devices to communicate without manual configuration or a DHCP server.

Example:
When a device fails to get an IP address from a DHCP server, it might assign itself an address like 169.254.1.2. Other devices on the same local network segment will also have addresses in the 169.254.0.0/16 range, allowing them to communicate directly.

命令

ip

NAME

ip - show / manipulate routing, devices, policy routing and tunnels.
1
2
3
$ ip route get 8.8.8.8
8.8.8.8 via 192.168.1.1 dev eth0 src 192.168.1.100 uid 1000
cache

说明:

  • 8.8.8.8: The destination IP address for which the route is being queried.
  • via 192.168.1.1: The gateway IP address through which the destination can be reached.
  • dev eth0: The network interface (e.g., eth0) used to reach the destination.
  • src 192.168.1.100: The source IP address used for sending packets to the destination.
  • uid 1000: The user ID of the process that issued the command.
  • cache: Indicates that the route information is cached.
1
2
3
4
$ ip route show
default via 192.168.1.1 dev eth0
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100
169.254.0.0/16 dev idrac proto kernel scope link src 169.254.1.2

说明:该命令用于显示路由表:

  • default via 192.168.1.1 dev eth0: The default route, packets to any destination not in the routing table will be sent to 192.168.1.1 via the eth0 interface.
  • 192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.100: A route for the 192.168.1.0/24 network (destination network), directly reachable via the eth0 interface, with the source IP 192.168.1.100.
  • 192.168.1.0/24: Destination network.
  • dev eth0: Interface eth0.
  • proto kernel: Added by the kernel.
  • scope link: Directly reachable.
  • src 192.168.1.100: Source IP address.
  • 169.254.0.0/16: Link-local address range.

netstat / ss

NAME

ss - another to investigate sockets.

Reference

查看进程占用的端口

COMMANDS

ss -lnpt

OPTIONS

-n, --numberic

-l, --listening

-t, --tcp
    Note: Only established (non-listening) connections.

-a, --all
    Display both listening and non-linstening (for TCP this means established connections) sockets.

-u, --udp

-p, --process

lsof

Options:

-n inhibits the conversion of network numbers to host names for network files.

-P inhibits the conversion of port numbers to port names for network files.

-i specifies the Internet addresses

    multiple addresses (up to a limit of 100) may be specified with multiple options.

    An Internet address is specified in the form (Items in square brackets are optional.):

    [46][protocol][@hostname|hostaddr][:service|port]

    where:
    46 specifies the IP version, IPv4 or IPv6
        that applies to the following address.
        '6' may be be specified only if the UNIX
        dialect supports IPv6.  If neither '4' nor
        '6' is specified, the following address
        applies to all IP versions.
    protocol is a protocol name - TCP, UDP
    hostname is an Internet host name.  Unless a
        specific IP version is specified, open
        network files associated with host names
        of all versions will be selected.
    hostaddr is a numeric Internet IPv4 address in
        dot form; or an IPv6 numeric address in
        colon form, enclosed in brackets, if the
        UNIX dialect supports IPv6.  When an IP
        version is selected, only its numeric
        addresses may be specified.
    service is an /etc/services name - e.g., smtp -
        or a list of them.
    port is a port number, or a list of them.

-s list file size

-s p:s  exclude(^)|select protocol (p = TCP|UDP) states by name(s).

Examples:

1
2
3
lsof -i:<port>
lsof -i -P -n | grep LISTEN
lsof -nP -iTCP -sTCP:LISTEN

nc/netcat/nmap

socket

Create a TCP or a UNIX domain socket and connect to stdin/out.

Installation:

sudo apt-get install socket

电影链接

Midsomer Murders: Season 1 Episode 2 - Written in Blood

台词

Phoenix turned and fired twice, the 34 millimetre bullets spitting through the air and splintering the brickwork two inches to the left of the Russia thug’s shoulder. A moment later came the reply of the Uzi semiautomatic and Phoenix twisted round. 菲尼克斯转身开了两枪,34毫米的子弹在空中喷射,将俄罗斯暴徒肩膀左侧两英寸砖墙击碎。过一会儿,乌兹半自动冲锋枪回应了,菲尼克斯扭过身来。

Her lips, searching in the sapphire, honeyscented darkness, found his; cool, forceful, unresisting, and as the frozen waves crashed down. 当冰冷、有力、不可抗拒的浪汹涌而下的时候,她的嘴唇在蓝宝石般散发着蜜香的夜色中寻找,找到了他的嘴唇。

-Got your meeting, have you? 你要去开会,对吗?
-Yes, I’m on my way. 是的,我正在去。

He pulled her towards him, his powerful, masculine hands tearing at the silk faric of her Gaultier nightshirt.

The repetitive beat of the innercity drum.

1887, Sebastian Lyddiard, greatgrandson of Herbert Lyddiard, who served under Sir John Jervis against Napoleon. 对抗拿破仑。

The Right Honourable William Lyddiard. 威廉·利迪亚德阁下。

-Do you ever regret marrying hime, Amy? I wonder if you ever think that but for you he might still be alive? 你后悔嫁给他吗,埃米?我不知道你是否想过,如果不是因为你,他可能现在还活着?
-(Amy) No. 没有想过。
-Well I do. 我想过。

-So we come to the question of which writer we invite to address us? 所以我们打算请哪位作家来给我们做演讲呢?
-How about Jilly Cooper?
-I think he said a writer.
-Do you think we could interest Frederick Forsythe?
-I rather doubt it.
-Oh, it’s a wonderful idea, Gerald. Especially since you’re writing a thriller. I think Frederick Forsythe would be first rate! 我认为Frederick Forsythe是第一流的。
-He’d never come. He’d just pretend he didn’t have time. They always do.
-I’d like Seamus Heaney.
-The poet?
-Not another poet. That last one was such a ghastly little man.

词汇

screenplay by 剧本由……写成
millimetre 毫米
phoenix 凤凰,这里是人名,菲尼克斯
spit 吐,唾
thug 恶棍,暴徒
twist 扭,拧,捻
brickwork 砖砌体,砖墙
splinter n. 碎片,弹片; v. 碎裂。
Uzi semiautomatic 乌兹半自动冲锋枪(Uzi submachine gun)。Uzi 冲锋枪是由以色列国防军 (IDF) 上尉(后来的少校)Uziel Gal 在 1948 年阿以战争后设计的。
sapphire 蓝宝石
honey 蜂蜜,蜜
scent 香味(a pleasant natural smell);scented 散发香味的
resist 抗拒的;unresisted 不可抗拒的。
masculine 男性的。
tear 撕,撕破,撕毁;拆;泪水。
nightshirt 睡衣
scum 浮渣
scum-bag 渣子袋,这里应该是“渣男”、“人渣”的意思,骂人的话。
hum 哼声
greatgrandson 曾孙
Sir 爵士
Napoleon 拿破仑
The Right Honourable 阁下。其中,Right是副词,意思是’very’ or ‘fully’。从语法上说,The Right Honourable 是形容短语,直接用来称呼人名或者某人用来自称都是不正确的,应该与其引用的名称或名称一起使用第三人称。
address 演讲
first rate 第一流
pretend 假装
ghastly US:/ˈɡæst.li/ UK:/ˈɡɑːst.li/ 阴森的,可怕的,非常坏的
bestseller 畅销书

Specify the search path for pkg_check_modules: Solution

1
set(ENV{PKG_CONFIG_PATH} "${CMAKE_SOURCE_DIR}/libs/opencv-install/lib/pkgconfig")

find_package

hexo修改默认端口号

参考博客

添加目录

https://blog.ligos.net/2016-07-25/Writing-Content-On-Hexo.html
https://medium.com/employbl/create-a-custom-blog-theme-with-hexo-js-b24c82eb9271#.viurzqeac
https://hexo.io/docs/themes
https://hexo.io/docs/templates
https://hexo.io/docs/helpers

Add pages

Commands

1
2
3
4
5
# The following command generate a 'categories/index.md' file
hexo new page categories

hexo new page tags
hexo new page about

Refers to Hexo NeXT Theme categories and tags page

Plugins

Display PDF

函数

ibv_fork_init

文档 ibv_fork_init

模板: int ibv_fork_init(void)

输入参数: 无

输出参数: 无

返回值: 0 on success, -1 on error. If the call fails, errno will be set to indicate the reason for the failure.

描述: ibv_fork_init 初始化 libverbs 的数据结构来安全地处理 fork() 并避免数据损坏,不论 fork() 是被显式调用还是隐式调用(比如在 system() 中被调用)。
如果所有的父进程总是阻塞直至所有的子进程结束或使用 exec() 改变地址空间,那么 ibv_fork_init 可以不被调用。

该函数在支持 madviseMADV_DONTFORK 标记的 Linux 内核(2.6.17或更高)上可以工作。

设置环境变量 RDMAV_FORK_SAFEIBV_FORK_SAFE 环境变量为任意值,有着与 ibv_fork_init 相同的效果。

设置 RDMAV_HUGEPAGES_SAFE 为任意值,以告诉库需要检查内核为内存域(memory regions)使用的底层内存页的大小。如果应用程序直接或通过库(如 libhugtlbfs )间接使用大内存页(博主注:即大于4KB)时,该环境变量是必须的。(博主注:ibv_fork_init 将检查 RDMAV_HUGEPAGES_SAFE

调用 ibv_fork_init 将降低性能,因为每个内存注册都将有一个额外的系统调用和分配附加的内存以追踪内存域(memory regions)。
确切的性能损失取决于工作负载,通常不会很大。

设置 RDMAV_HUGEPAGES_SAFE 会为所有的内存注册增加更多的开销。

文档

Documentation: RDMA Aware Networks Programming User Manual v1.6

Local Documentation

Sun Network QDR InfiniBand Gateway Switch Topic Set

RDMA知乎专栏

用户态的Verbs API手册跟代码在一个仓库维护,手册地址:https://github.com/linux-rdma/rdma-core/tree/master/libibverbs/man

有很多在线的man page网站可以查阅这些接口的说明,比如官方的连接:https://man7.org/linux/man-pages/man3/ibv_post_send.3.html

也有一些其他非官方网页,支持在线搜索:https://linux.die.net/man/3/ibv

查阅系统man page
如果你使用的商用OS安装了rdma-core或者libibverbs库,那么可以直接用man命令查询接口:

1
man ibv_post_send

查询Mellanox的编程手册
RDMA Aware Networks Programming User Manual Rev 1.7》,最新版是2015年更新的。该手册写的比较详尽,并且附有示例程序,但是可能与最新的接口有一些差异。Mellanox VPI®(Virtual Procotol Interconnect)架构为同时支持InfiniBand和以太网语义的网络适配器和交换机提供高性能、低延迟和可靠的方法。

Book: Linux Kernel Networking - Implementation and Theory

Dotan’s blog: Dotan Barak, an InfiniBand Expert. Dotan is a Senior Software Manager at Mellanox Technologies working on RDMA Technologies.

性能分析工具(profiling)

Blog: Tips and tricks to optimize your RDMA code

libibprof

IB简介

RDMA - Remote Direct Memory Access 远程直接内存存取。

InfiniBand是一种高性能计算机网络通信标准,它具有极高的吞吐量和极低的延迟。如果您需要使用InfiniBand进行编程,您需要使用支持InfiniBand的编程语言(如C++)来编写代码。

机构和组织:

OFA: Open Fabrics Alliance.

IBTA: InfiniBand Trade Association.

概念

  • CQ - Complete Queue 完成队列
  • WQ - Work Queue 工作队列
  • WR - Work Request 工作请求
  • QP - Queue Pairs 队列对(Send-Receive)
  • SQ - Send Queue 发送队列
  • RQ - Receive Queue 接收队列
  • PD - Protection Domain 保护域,将QP和MR结合在一起
  • MR - Memory Region 内存区域。一块经注册过的且本地网卡可以读写的内存区域。包含R_Key和L_Key。
  • SGE - Scatter/Gather Elements 分散/聚集元素。
  • R_Key - Remote Key
  • L_Key - Local Key
  • CA - (Host) Channel Adapter, an inifiniband network interface card.
  • NIC - Network Interface Card 网卡。
  • LID - Local Identifier.
  • CM - Connection Manager.

其他常见缩写:

  • RC - reliable connected.
  • SCSI - Small Computer System Interface 小型计算机系统接口。
  • SRP - SCSI RDMA Protocol. / Secure Remote Password.

博客:https://blog.51cto.com/liangchaoxi/4044818

安装

InfiniBand 和 RDMA 相关软件包

sudo apt-get install infiniband-diags
sudo apt install ibverbs-utils

API

以下是一些支持InfiniBand的C++库:

Infinity:这是一个轻量级的C++ RDMA库,用于InfiniBand网络。它提供了对两侧(发送/接收)和单侧(读/写/原子)操作的支持,并且是一个简单而强大的面向对象的ibVerbs抽象。该库使用户能够构建使用RDMA的复杂应用程序,而不会影响性能1

OFED:这是一个开放式Fabrics Enterprise Distribution,它提供了对InfiniBand和RoCE(RDMA over Converged Ethernet)技术的支持。OFED提供了一组用户空间库和驱动程序,可用于构建支持RDMA的应用程序2

以下是使用Infinity库编写支持InfiniBand的C++代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
// 创建新上下文
infinity::core::Context *context = new infinity::core::Context();

// 创建队列对
infinity::queues::QueuePairFactory *qpFactory = new infinity::queues::QueuePairFactory(context);
infinity::queues::QueuePair *qp = qpFactory->connectToRemoteHost(SERVER_IP, PORT_NUMBER);

// 创建并向网络注册缓冲区
infinity::memory::Buffer *localBuffer = new infinity::memory::Buffer(context, BUFFER_SIZE);

// 从远程缓冲区读取(单向)并等待完成
infinity::memory::RegionToken *remoteBufferToken = new infinity::memory::RegionToken(REMOTE_BUFFER_INFO);
infinity::requests::RequestToken requestToken(context);
qp->read(localBuffer, remoteBufferToken, &requestToken);
requestToken.waitUntilCompleted();

// 将本地缓冲区的内容写入远程缓冲区(单向)并等待完成
qp->write(localBuffer, remoteBufferToken, &requestToken);
requestToken.waitUntilCompleted();

// 将本地缓冲区的内容通过队列对发送(双向)并等待完成
qp->send(localBuffer, &requestToken);
requestToken.waitUntilCompleted();

// 关闭连接
delete remoteBufferToken;
delete localBuffer;
delete qp;
delete qpFactory;
delete context;

以下是使用OFED库编写支持InfiniBand的C++代码示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
// 创建新上下文
struct ibv_context *context = ibv_open_device(*device);

// 创建完成端口
struct ibv_pd *pd = ibv_alloc_pd(context);

// 创建队列对
struct ibv_qp_init_attr qp_init_attr;
memset(&qp_init_attr, 0, sizeof(qp_init_attr));
qp_init_attr.send_cq = cq;
qp_init_attr.recv_cq = cq;
qp_init_attr.qp_type = IBV_QPT_RC;
qp_init_attr.cap.max_send_wr = 1;
qp_init_attr.cap.max_recv_wr = 1;
qp_init_attr.cap.max_send_sge = 1;
qp_init_attr.cap.max_recv_sge = 1;
struct ibv_qp *qp = ibv_create_qp(pd, &qp_init_attr);

// 创建并向网络注册缓冲区
char *localBuffer = (char *)malloc(BUFFER_SIZE);
struct ibv_mr *mr = ibv_reg_mr(pd, localBuffer, BUFFER_SIZE, IBV_ACCESS_LOCAL_WRITE | IBV_ACCESS_REMOTE_READ | IBV_ACCESS_REMOTE_WRITE);

// 连接到远程主机
struct sockaddr_in remoteAddress;
memset(&remoteAddress, 0, sizeof(remoteAddress));
remoteAddress.sin_family = AF_INET;
remoteAddress.sin_port = htons(PORT_NUMBER);
inet_pton(AF_INET, SERVER_IP, &remoteAddress.sin_addr);
struct rdma_cm_id *cmId;
rdma_create_id(*eventChannel, &cmId, NULL, RDMA_PS_TCP);
rdma_resolve_addr(cmId, NULL, (struct sockaddr *)&remoteAddress, RESOLVE_TIMEOUT_MS);

// 等待连接完成
rdma_wait_event(*eventChannel, RDMA_CM_EVENT_ESTABLISHED);
rdma_ack_cm_event(cmEvent);

// 获取远程缓冲区信息
struct ibv_wc wc;
ibv_post_recv(qp, &recvWr, &badRecvWr);
do {
ibv_poll_cq(cq, 1, &wc);
} while (wc.status != IBV_WC_SUCCESS || wc.opcode != IBV_WC_RECV_RDMA_WITH_IMM || wc.imm_data != htonl(IMM_DATA));
remoteBufferInfo.rkey = ntohl(wc.imm_data >> 8);
remoteBufferInfo.vaddr = wc.wr_id;

// 将本地缓冲区的内容写入远程缓冲区(单向)
struct ibv_send_wr sendWr;
memset(&sendWr, 0, sizeof(sendWr));
sendWr.wr_id = 0;
sendWr.opcode = IBV_WR_RDMA_WRITE_WITH_IMM;
sendWr.sg_list = &localSge;
sendWr.num_sge = 1;
sendWr.send_flags = IBV_SEND_SIGNALED;
sendWr.wr.rdma.remote_addr = remoteBufferInfo.vaddr;
sendWr.wr.rdma.rkey = remoteBufferInfo.rkey;
localSge.addr = (uintptr_t)localBuffer;
localSge.length = BUFFER_SIZE;
localSge.lkey = mr->lkey;
ibv_post_send(qp, &sendWr, &badSendWr);

// 关闭连接
ibv_dereg_mr(mr);
free(localBuffer);
ibv_destroy_qp(qp);
ibv_dealloc_pd(pd);
ibv_close_device(context);

Linux manual page

Command-Line

文档:https://docs.nvidia.com/networking/pages/viewpage.action?pageId=43719572

  • ibstat

  • ibhosts - 查看所有的IB hosts。

  • ibnetdiscover - discover InfiniBand topology.

  • ibv_devices - list RDMA devices.

  • ibv_devinof - Print information about RDMA devices available for use from userspace.

  • ibv_rc_pingpong - Run a simple ping-pong test over InfiniBand via the reliable connected (RC) transport.

  • targetcli - administration shell for storage targets

    targetcli is a shell for viewing, editing, and saving the configuration of the kernel’s target subsystem,
    also known as LIO. It enables the administrator to assign local storage resources backed by either files,
    volumes, local SCSI devices, or ramdisk, and export them to remote systems via network fabrics, such as iSCSI or FCoE.

  • srp_daemon - Discovers and connects to InfiniBand SCSI RDMA Protocol (SRP) targets in an IB fabric.

  • ibsrpdm - List InfiniBand SCSI RDMA Protocol (SRP) targets on an IB fabric.

liraries

devid: device ID library. Refer to here.

ibverbs: 使得用户空间进程能够使用RDMA verbs(即进行RDMA操作)。Refer to here.

dl: Dynamic Loader.

Makefile默认shell

Makefile 默认的 shell 是 /bin/sh:
查看 Makefile 默认的 shell:
$(warning ${SHELL}) # 查看默认 shell

如果在 Makefile 开头加上以下语句,可以指定 shell:
SHELL := /bin/bash

Makefile 的 shell 命令似乎每一条都会新开辟一个 shell 环境来执行,因为每条 shell 命令似乎都执行了一次 .cshrc 脚本。
要想在同一个 shell 环境中执行所有命令,则需要使用分号分割并转义换行符。

Makefile环境变量

你可以通过设置环境变量 MAKEFLAGS 来让所有的子shell都将 make 认作 make -n:
export MAKEFLAGS=”-n”
注:-n, –dry-run 表示只打印将要执行的命令,但是不真正执行它们。

Makefile 设置 PATH 环境变量:
PATH := mypath:$(PATH)
必须使用 “:=” ,因为 “:=” 是简单赋值,但是 “=” 会递归展开,会导致报错 “Recursive variable `PATH’ references itself (eventually)”。

Makefile 定义多行变量:使用 define 语句。
Makefile 接收命令行参数

非常奇特的现象:
$ make clean
cat clean.sh >clean
chmod a+x clean
因为 Makefile 文件中没有 clean 的 recipe,但是当前目录下有个 clean.sh 文件。
但是,当再次执行 make clean,clean 脚本还是不会被执行:
$ make clean
make: `clean’ is up to date.

特殊符号

空格

Makefile对空格的处理,似乎是:从第一个非空格开始,到明确的截止符(换行、逗号、括号、注释标记’#’等)为止。
a = b #注意末尾有3个空格
$(warning a=$(a)c)

结果:
a= b c

Makefile转义符:
字符 转义方法
$ $$
# #
\ \

注意:这里说的是Makefile中的转义符,不是bash中的转义符。

括号

引用变量时,Shell使用大括号,Makefile则大括号和小括号都行。但是在命令中使用Shell变量就需要使用大括号。

参考

Makefile调试方法

要调试 Makefile 并查看其执行过程,可以使用以下几种方法:
1. 使用 make 的 -n 或 –dry-run 选项:这将显示 Makefile 中的所有命令,而不会真正执行它们。
make -n
1. 使用 make 的 -d 或 –debug 选项:这将显示详细的调试信息,包括变量的展开和规则的匹配过程。
make -d
1. 使用 make 的 -p 或 –print-data-base 选项:这将打印所有的变量、规则和隐含规则。
make -p
1. 在 Makefile 中添加调试信息:你可以在 Makefile 中添加一些调试信息,例如使用 $(info …) 来打印变量的值。
print:
@$(foreach V, $(.VARIABLES), $(info $(V) = $($(V))))
1. 使用 make 的 -j 选项:如果你使用并行执行,可以使用 -j 选项来限制并行任务的数量,并更容易地跟踪输出。
make -j1

makefile打印所有变量的值:
debug:
@$(foreach V, $(.VARIABLES), $(info $(V) = $($(V))))
然后在命令行中运行:
make debug
这将打印所有变量及其值。

print-%:
@echo $* = $($*)

print-% 是一个 Makefile 目标,用于打印变量的值。具体步骤如下:
1. 定义一个目标 print-%,其中 % 是一个通配符,表示任意变量名。
2. 使用 @echo $* = $($*) 打印变量名和变量值。

示例代码:
print-%:
@echo $* = $($*)
使用方法:
在命令行中运行:
make print-VARIABLE_NAME
例如:
make print-XTENSA_SW_RELEASE
这将打印 XTENSA_SW_RELEASE 变量的值。

命令行参数

See here.

@: See here.

This works fine for me:

1
2
3
4
5
6
7
8
9
10
11
12
# If the first argument is "run"...
ifeq (run,$(firstword $(MAKECMDGOALS)))
# use the rest as arguments for "run"
RUN_ARGS := $(wordlist 2,$(words $(MAKECMDGOALS)),$(MAKECMDGOALS))
# ...and turn them into do-nothing targets
# TODO: What does the following line mean?
# $(eval $(RUN_ARGS):;@:)
endif

# "cmd" refers to any command
run:
cmd $(RUN_ARGS)

makefile同名目标处理方式

参考:

makefile将命令结果赋值给变量

Makefile中短划线

1
2
all:
-/bin/rm -rf *.log

其中,”-/bin/rm“的短划线”-“是一个特殊前缀,表示忽略命令执行过程的错误。

为每个源文件生成一个可执行程序

1
2
3
4
5
6
7
SRCS = $(wildcard *.c)

all: $(SRCS:.c=)

# Unnecessary, as the default rules are adequate.
.c:
gcc $(CPFLAGS) $< -o $@

最后两行其实不需要,默认规则已经足够了。

其中,$(SRCS:.c=.o)表示将变量SRCS中的每个单词(以空格分割)中的.c替换为.o。以上代码则是将所有.c都去掉。