Menu

  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay
  • Home
  • Work
    • Cloud
      • Virtualization
      • IaaS
      • PaaS
    • Java
    • Go
    • C
    • C++
    • JavaScript
    • PHP
    • Python
    • Architecture
    • Others
      • Assembly
      • Ruby
      • Perl
      • Lua
      • Rust
      • XML
      • Network
      • IoT
      • GIS
      • Algorithm
      • AI
      • Math
      • RE
      • Graphic
    • OS
      • Linux
      • Windows
      • Mac OS X
    • BigData
    • Database
      • MySQL
      • Oracle
    • Mobile
      • Android
      • IOS
    • Web
      • HTML
      • CSS
  • Life
    • Cooking
    • Travel
    • Gardening
  • Gallery
  • Video
  • Music
  • Essay

AutoTools学习笔记

30
Dec
2011

AutoTools学习笔记

By Alex
/ in C,C++
/ tags GNU
0 Comments
GNU构建系统
可移植性代码的需求

开发一个C程序时,为了在不同环境下运行,可能需要考虑这些问题:

  1. 某些函数在某些环境下不存在,例如strtod()
  2. 同样功能的函数,名字不同,例如strchr() 与 index()
  3. 函数名称冲突,例如int setpgrp(void)、setpgrp(int, int)
  4. 函数在不同环境下行为不同,例如malloc(0)
  5. 函数可能定义在不同的头文件中,例如string.h 、 strings.h 、memory.h

为了解决这些问题,可以:

  1. 创建替换宏(substitution macros)
  2. 创建替换函数(substitution functions)

手工处理这类问题非常繁琐,1991年人们开始编写Shell脚本,来猜测GNU环境的设置,最终形成了configure这个工具:

  1. 探测系统中所需的函数、库、工具是否存在,根据结果生成config.h这个头文件,里面包含很多#define
  2. 生成构建软件包的Makefile文件
标准文件系统层次结构(Standard File System Hierarchy)

现在configure文件一般由AutoConf生成,默认情况下遵循如下的目录约定,这些目录决定如何安装程序的可执行文件、库、文档等内容:

 变量 默认值 
prefix /usr/local
exec-prefix $(prefix)
bindir $(exec-prefix)/bin
libdir $(exec-prefix)/lib
includedir $(prefix)/include
datarootdir $(prefix)/share
datadir $(datarootdir)
mandir $(datarootdir)/man
infodir $(datarootdir)/info

注:上述变量均可以作为configure的命令行参数使用,例如 ./configure --bindir=$HOME/bin 

configure的用法示例

执行 ./configure --help 可以看到configure的完整帮助,下面给出一些示例:

Shell
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
./configure
 
#指定目录前缀
./configure --prefix ~/usr
#指定程序前后缀
./configure --program-prefix=hello --program-suffix=exe
 
#configure自动检测很多设置,可以强制使用配置变量:
#      CC  C compiler command
#  CFLAGS  C compiler  flags
#     CXX  C++ compiler command
#CXXFLAGS  C++ compiler flags
# LDFLAGS  linker flags
#CPPFLAGS  C/C++ preprocessor flags
#使用./configure --help可获取完整列表
./configure --prefix ~/usr CC=gcc-3 CPPFLAGS=-I$HOME/usr/include LDFLAGS=-L$HOME/usr/lib
 
#配置交叉编译
#--build=BUILD,软件包在其上被编译的系统,一般就是当前系统,由config.guess猜测即可
#--host=HOST,编译好的库、可执行文件在其上运行的系统。只有在交叉编译的时候,才和--builid即本机不同
#--target=TARGET,只有在建立交叉编译环境时才用得到,正常编译/交叉编译都用不到。用于编译一套编译器,该编译器编译出的程序在target机器上运行
./configure --build i686-pc-linux-gnu --host i586-mingw32msvc
#checking for i586-mingw32msvc-strip... i586-mingw32msvc-strip
#checking for i586-mingw32msvc-gcc... i586-mingw32msvc-gcc
#checking for C compiler default output file name... a.exe
#checking whether the C compiler works... yes
#checking whether we are cross compiling... yes
#checking for suffix of executables... .exe
#checking for suffix of object files... o
#checking whether we are using the GNU C compiler... yes
#checking whether i586-mingw32msvc-gcc accepts -g... yes
#checking for i586-mingw32msvc-gcc option to accept ANSI C...
 
#依赖追踪仅仅在源代码改变以后需要,在install时可以安全禁用
.configure --disable-dependency-tracking
GNU Autotools
Hello World

假设在src目录下有如下一简单C程序:

main.c
C
1
2
3
4
5
6
7
#include
#include
int main(void)
{
    puts("HelloWorld!");
    return 0;
}

相关文件将按如下依赖关系生成:configure.helloworld

输入文件列表:

configure.ac
1
2
3
4
5
6
7
8
9
10
11
12
#初始化Autoconf,指定软件包的名称、版本号、缺陷报告地址
AC_INIT([amhello], [1.0], [bug-report@gmem.cc])
#初始化Automake,启用Automake警告,并将其报告为错误
AM_INIT_AUTOMAKE([foreign -Wall -Werror])
#检查C编译器
AC_PROG_CC
#声明config.h为输出头文件
AC_CONFIG_HEADERS([config.h])
#声明Makefile、src/Makefile为输出文件
AC_CONFIG_FILES([Makefile src/Makefile])
#输出所有声明的文件
AC_OUTPUT

Makefile.am
1
2
3
#在src目录下递归的构建,可以声明多个SUBDIR,顺序非常重要
SUBDIRS = src
#对于根目录,无任何其他声明

src/Makefile.am
1
2
3
4
5
6
#PROGRAMS表示在构建某个程序
#bin表示程序将安装在bin目录(默认/usr/local/bin)
#仅有一个名为hello的程序需要构建
bin_PROGRAMS = hello
#为了构建程序hello,需要编译main.c
hello_SOURCES = main.c

生成configure、Makefile已经构建、打包的命令示意: 

Shell
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
cd ~/amhello
autoreconf --install
#输出内容:
# configure.ac:2: installing './install-sh'
# configure.ac:2: installing './missing'
# src/Makefile.am: installing './depcomp'
#自动生成以下文件:
#Makefile.in、config.h.in、Makefile.in、configure*是配置模板文件
#aclocal.m4是configure.ac中使用的第三方宏定义
#depcomp* install-sh* missing*是构建过程中的辅助工具
#Autotools缓存文件:autom4te.cache/ : output.0 requests traces.1 output.1 traces.0
 
./configure
#checking...
#生成Makefile
#configure: creating ./config.status
#config.status: creating Makefile
#config.status: creating src/Makefile
#config.status: creating config.h
#config.status: executing depfiles commands
 
make
make distcheck
#========================================
#amhello archives ready for distribution:
#amhello-1.0.tar.gz
#========================================
tar ztf amhello-1.0.tar.gz
Autotools核心工具包
GNU Autoconf包
工具  说明 
autoconf

一个宏处理器(底层是GNU M4,但是带有很多预定义宏),从configure.ac(一个带有宏指令的Shell脚本)生成configure(一个完整的Shell脚本)

autoheader 从configure.ac生成config.h.in
autoreconf 按正确顺序运行所有工具
autoscan 扫描源代码以发现常见的可移植性问题、以及缺失的configure.ac中的宏定义
autoupdate 更新configure.ac中废弃的宏定义
ifnames 从#if/#ifdef/...指令中收集标识符
autom4te Autoconf的核心,驱动M4、实现上面工具需要的特性

Autoconf提供多种宏来进行常见的配置检查,仅包含宏定义、没有任何Shell语句的congure.ac也是常见的。

Autoconf与M4
Autoconf底层的宏处理器是M4,下面是其一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
#test.m4
m4_define(NAME1, Harry)    #宏参数会被处理。宏会被展开
m4_define(NAME2, Sally)    #宏参数参数可以用引号保护,例如 'Sally Wang'
m4_define(MET, $1 met $2)  #宏名称和参数之间不能有空格。引号前面的空格被忽略,引号中间、后面的空格被作为参数的内容
MET(NAME1, NAME2)
 
#测试
m4 -P test.m4
#输出
#
#
#
#Harry met Sally

由于引号'的特殊用途,因此,在Autoconf中,使用[]来代替'',Shell中不能使用[进行条件判断,而需要使用if test语句。

1
2
3
4
5
6
7
8
#Autoconf中的条件测试:
if test "$x" = "$y"; then ...
 
#使用AC DEFUN可以定义宏
AC_DEFUN([NAME1], [Harry, Jr.])
AC_DEFUN([NAME2], [Sally])
AC_DEFUN([MET], [$1 met $2])
MET([NAME1], [NAME2])

configure.ac的组成与预定义宏

 组成 说明以及重要的宏
准备(Prelude)
Shell
1
2
3
4
5
6
7
8
#强制Autoconf的初始化
AC_INIT(PACKAGE, VERSION, BUG-REPORT-ADDRESS)
#启用Automake,并进行初始化,检查依赖的工具是否存在
AM_INIT_AUTOMAKE([OPTIONS...])
#要求Autoconf的最低版本
AC_PREREQ(VERSION)
#例如install-sh、depcomp之类构建辅助脚本的存放目录
AC_CONFIG_AUX_DIR(DIRECTORY)
检查程序
Shell
1
2
3
4
5
6
7
8
9
10
11
#编译器检查,如果需要的话处理交叉编译器的搜索
AC_PROG_CC, AC_PROG_CXX, AC_PROG_F77
#寻找适合的实现,并设置$SED $YACC $LEX
AC_PROG_SED, AC_PROG_YACC, AC_PROG_LE
#设置VAR为第一个寻找到的PROGS,如果找不到,则设置为VAL-IF-NOT-FOUND
AC_CHECK_PROGS(VAR, PROGS, [VAL-IF-NOT-FOUND])
#举例:
AC_CHECK_PROGS([TAR], [tar gtar], [:])
if test "$TAR" = :; then
    AC_MSG_ERROR([This package needs tar.])
fi
检查库
Shell
1
2
3
4
5
#检查__LIBRARY是否存在,是否包含FUNCT,并根据检查结果分别执行ACT-IF-FOUND、ACT-IF-NOT
#如果ACT-IF-FOUND没有设置,则默认行为是:
#1、LIBS="-l__LIBRARY $LIBS" (Automake使用$LIBS进行链接)
#2、定义#define HAVE_LIB__LIBRARY
AC_CHECK_LIB(__LIBRARY, FUNCT, [ACT-IF-FOUND], [ACT-IF-NOT])
检查头文件
Shell
1
2
3
4
5
6
7
8
9
10
11
12
13
#检查每一个头文件,并定义C宏:#define HAVE_HEADER_H
AC_CHECK_HEADERS(HEADERS...)
 
AC_CHECK_HEADERS([sys/param.h unistd.h])
AC_CHECK_HEADERS([wchar.h])
 
#可能添加如下的宏定义:HAVE_SYS_PARAM_H, HAVE_UNISTD_H, HAVE_WCHAR_H
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
 
#检查一个头文件
AC_CHECK_HEADER(HEADER, [ACT-IF-FOUND], [ACT-IF-NOT]) 
输出文件
Shell
1
2
3
4
5
6
#从HEADER.h.in文件导出HEADER.h
AC_CONFIG_HEADERS(HEADERS...)
#从FILE.in文件导出FILE
#注意*.in是模板文件,其中的@XYZ@为占位符
#自动使用AC_SUBST定义的变量替换
AC_CONFIG_FILES(FILES...)
动作
Shell
1
2
3
4
5
6
7
8
9
10
11
12
#打印ERROR-DESCRIPTION并退出
AC_MSG_ERROR(ERROR-DESCRIPTION, [EXIT-STATUS])
#打印警告信息
AC_MSG_WARN(ERROR-DESCRIPTION)
#输出C宏定义到config.h
AC_DEFINE(VARIABLE, VALUE, DESCRIPTION)
 
/* DESCRIPTION */
#define VARIABLE VALUE
 
#在Makefile中定义VARIABLE为VALUE
AC_SUBST(VARIABLE, [VALUE])
GNU Automake包
 工具 说明 
automake 从Makefile.am、configure.ac推导出Makefile.in
aclocal 扫描configure.ac中使用的第三方宏定义、收集aclocal.m4中的定义

Automake辅助生成可移植的、GNU标准兼容的Makefile,它从简单的Makefile.am文件生成复杂的Makefile.in文件。

Makefile.am具有和Makefile类似的语法形式,但是通常只包含变量定义,Automake根据这些定义创建构建规则。在Makefile.am中包含额外的Makefile规则是允许的,Automake会将其保留,并输出到最终的Makefile。

在configure.ac中声明使用Automake

使用宏AM_INIT_AUTOMAKE([OPTIONS...]),可以在configure.ac中声明Automake,OPTIONS包括:

 选项 说明 
-Wall 开启所有警告
-Werror 将警告报告为错误
foreign 放松某些GNU标准的要求
1.11.1 要求最低1.11.1版本的Automake
dist-bzip2 在执行make dist、make distcheck时自动创建tar.bz2文件
tar-ustar 使用ustar格式创建tar归档文件

使用宏AC_CONFIG_FILES(FILES...)声明输出文件

Automake会为每一个存在FILE.am的FILE创建对应的FILE.in(模板)文件

configure.ac
1
2
#自动生成Makefile.am、sub/Makefile.am文件
AC_CONFIG_FILES([Makefile sub/Makefile])

Makefile.am中的where_PRIMARY惯例 

Makefile.am
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#使用如下形式(下划线分隔的三段字符串)声明目标
option_where_PRIMARY = targets ...
 
#其中option:
#dist 分发targets,默认
#nodist 不分发targets
 
#其中where: targets将被安装在(遵从标准文件系统层次结构)
#bin $(bindir)
#lib $(libdir)
#custom $(customdir ) 自定义目录
#noinst 不进行安装
#check 以 make check方式构建
 
#其中PRIMARY: targets被构建为何种组件
#PROGRAMS 可执行程序
#LIBRARIES 库
#LTLIBRARIES Libtool库
#HEADERS 头文件
#SCRIPTS 脚本
#DATA 数据

按目标设置标记

src/Makefile.am
1
2
3
4
5
6
7
8
9
10
11
#假设foo是一个程序或者库
#默认值:foo_XXXFLAGS = $(AM_XXXFLAGS)
foo_CFLAGS    #额外的C编译器标记
foo_CPPFLAGS  #额外的预处理器标记(-I、-D)
foo_LDADD     #foo为程序时:额外的链接对象、-l、-L
foo_LIBADD    #foo为库时:额外的链接对象、-l、-L
foo_LDFLAGS   #额外的连接器标记
 
#对于软件包内部的额外链接对象,应当保留原始的文件名
#-l、-L仅用于外部库
run_me_LDADD = ../lib/libcompat.a

声明源代码文件

Makefile.am
1
2
3
4
5
6
7
8
9
10
11
#目标foo、run-me编译为可执行程序,安装到bin目录
bin_PROGRAMS = foo run-me
#foo的源代码列表
foo_SOURCES = foo.c foo.h print.c print.h
#run-me的源代码列表(注意非alphanumeric字符-映射为_)
run_me_SOURCES = run.c run.h print.c
#注意:
#Automake自动计算从这些文件构建、链接的object列表
#头文件不是必须的,只是为了分发的需要,Automake不会分发不知道的文件
#可以为两个程序使用同样的Source
#根据.h、.c扩展名来推断是在编译、链接阶段使用某个原文件

Automake举例:静态库

Makefile.am
1
2
3
4
5
6
7
#目标libfoo.a、libbar.a作为库安装到$(libdir)
lib_LIBRARIES = libfoo.a libbar.a #注意名称必须满足lib*.a形式
#s声明两个目录的源代码文件
libfoo_a_SOURCES = foo.c privfoo.h
libbar_a_SOURCES = bar.c privbar.h
#目标foo.h、bar.h(公共头文件)被安装到$(includedir)
include_HEADERS = foo.h bar.h

Makefile.am的目录布局

注意每个目录下均需要一个Makefile文件,因此也就对应了Makefile.am文件。并且这些Makefile必须在configure.ac中一一声明,例如:

configure.ac
1
AC_CONFIG_FILES([Makefile lib/Makefile src/Makefile src/dira/Makefile src/dirb/Makefile])

make命令是在根目录运行的,Makefile.am可以声明构建子目录的顺序:

Makefile.am
1
SUBDIRS = lib src

src/Makefile.am
1
2
3
SUBDIRS = dira dirb .
#注意,默认当前目录在子目录构建完成后构建
#可以移动当前目录(.)的位置,改变此默认行为

 Parallel Build Trees (即VPATH Builds)

VPATH用于指定一组make需要搜索的目录的列表。

obj文件、程序、库在configure运行的$CWD下构建,但是源代码不一定需要在$CWD下——所谓构建树(build tree)、源码树(source tree):

  1. Make file、obj文件等处于构建树
  2. Make file.in、Make file.am、源代码等位于源码树

如果./configure在$CWD中运行,则两棵树一致,每个Makefile的config.status会定义$(srcdir),用来指定对应的源码目录

辅助库(Convenience Libraries)

所谓辅助库,是指仅仅在构建过程中使用的临时库:

lib/Makefile.am
1
2
noinst_LIBRARIES = libcompat.a  #noinst表示其为临时的
libcompat_a_SOURCES = xalloc.c xalloc.h

src/Makefile.am
1
2
3
4
5
6
7
8
LDADD = ../lib/libcompat.a  #使用临时库,LDADD在链接所有程序时自动添加
AM_CPPFLAGS = -I$(srcdir)/../lib #AM_CPPFLAGS包含额外的预处理标记
bin_PROGRAMS = foo run-me
foo_SOURCES = foo.c foo.h print.c print.h
run_me_SOURCES = run.c run.h print.c
#注意LDADD、AM_CPPFLAGS 也可以按目标逐一指定,以应用于一个程序
run_me_LDADD = ../lib/libcompat.a
run_me_CPPFLAGS = -I$(srcdir)/../lib

检查依赖库

configure.ac
1
2
3
4
5
6
#检查一个依赖库中的某个函数是否存在,并采取相应的动作
AC_CHECK_LIB(LIBRARY, FUNCT, [ACT-IF-FOUND], [ACT-IF-NOT])
 
#举例:
AC_CHECK_LIB([efence], [malloc], [EFENCELIB=-lefence]) #如果存在,则定义变量
AC_SUBST([EFENCELIB]) #在Makefile中声明变量

src/Makefile.am
1
run_me_LDADD = ../lib/libcompat.a $(EFENCELIB)

哪些文件被分发(Distributed)

 

  1. 所有使用***_SOURCES声明的源代码
  2. 所有使用***_HEADERS声明的头文件
  3. 所有使用dist_***_ SCRIPTS声明的脚本文件
  4. 所有使用dist_***_ DATA声明的数据文件
  5. 诸如ChangeLog, NEWS之类的常规文件
  6. EXTRA_DIST中列出的额外目录或者文件

条件构建(Conditional builds)

Makefile.am
1
2
3
4
5
6
7
8
bin_PROGRAMS = foo
#如果此变量为真,构建bar程序。但即使为假,也会分发
#WANT_BAR必须在configure.ac中声明和使用
if WANT_BAR  
  bin_PROGRAMS += bar
endif
foo_SOURCES = foo.c
bar_SOURCES = bar.c

configure.ac
1
2
3
4
5
6
#条件构建的声明,如果CONDITION指定的Shell指令成功,则NAME为真
AM_CONDITIONAL(NAME, CONDITION)
 
#举例:
AC_CHECK_HEADER([bar.h], [use_bar=yes])
AM_CONDITIONAL([WANT_BAR], [test "$use_bar" = yes])

扩展Automake规则

  1. Makefile.am中的内容几乎是逐字的复制到Makefile.in
  2. automake添加新的规则、变量到Makefile.in,以实现必须定义的变量的语义
  3. 某些较小的Makefile.in重写是通过条件构建来实现的
  4. 在Makefile.am中添加自己的规则是可以的,例如这些规则:
    1. 对维护有意义的目标的规则:例如make style-check
    2. 用于构建特殊目标的规则:例如为某些文件生成FAQ
  5. 可以定义对Automake无意义的变量,例如在自定义规则中使用

make命令失败时该怎么办

1
2
3
4
5
6
7
8
9
10
11
#在必要时尝试下面的方法
 
#手工运行autoreconf
autoreconf --install
 
#仍然无效,可以尝试
autoreconf --install --force
 
#甚至
make -k maintainer-clean
autoreconf --install --force

 

← Ubuntu下安装PHP
使用Python进行文本处理 →

Leave a Reply Cancel reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Related Posts

  • Cygwin知识集锦
  • CLion知识集锦
  • Visual Studio知识集锦
  • MinGW知识集锦
  • Windows下基于Eclipse CDT的C/C++开发

Recent Posts

  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
  • A Comprehensive Study of Kotlin for Java Developers
  • 背诵营笔记
  • 利用LangChain和语言模型交互
  • 享学营笔记
ABOUT ME

汪震 | Alex Wong

江苏淮安人,现居北京。目前供职于腾讯云,专注容器方向。

GitHub:gmemcc

Git:git.gmem.cc

Email:gmemjunk@gmem.cc@me.com

ABOUT GMEM

绿色记忆是我的个人网站,域名gmem.cc中G是Green的简写,MEM是Memory的简写,CC则是我的小天使彩彩名字的简写。

我在这里记录自己的工作与生活,同时和大家分享一些编程方面的知识。

GMEM HISTORY
v2.00:微风
v1.03:单车旅行
v1.02:夏日版
v1.01:未完成
v0.10:彩虹天堂
v0.01:阳光海岸
MIRROR INFO
Meta
  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
Recent Posts
  • Investigating and Solving the Issue of Failed Certificate Request with ZeroSSL and Cert-Manager
    In this blog post, I will walk ...
  • A Comprehensive Study of Kotlin for Java Developers
    Introduction Purpose of the Study Understanding the Mo ...
  • 背诵营笔记
    Day 1 Find Your Greatness 原文 Greatness. It’s just ...
  • 利用LangChain和语言模型交互
    LangChain是什么 从名字上可以看出来,LangChain可以用来构建自然语言处理能力的链条。它是一个库 ...
  • 享学营笔记
    Unit 1 At home Lesson 1 In the ...
  • K8S集群跨云迁移
    要将K8S集群从一个云服务商迁移到另外一个,需要解决以下问题: 各种K8S资源的迁移 工作负载所挂载的数 ...
  • Terraform快速参考
    简介 Terraform用于实现基础设施即代码(infrastructure as code)—— 通过代码( ...
  • 草缸2021
    经过四个多月的努力,我的小小荷兰景到达极致了状态。

  • 编写Kubernetes风格的APIServer
    背景 前段时间接到一个需求做一个工具,工具将在K8S中运行。需求很适合用控制器模式实现,很自然的就基于kube ...
  • 记录一次KeyDB缓慢的定位过程
    环境说明 运行环境 这个问题出现在一套搭建在虚拟机上的Kubernetes 1.18集群上。集群有三个节点: ...
  • eBPF学习笔记
    简介 BPF,即Berkeley Packet Filter,是一个古老的网络封包过滤机制。它允许从用户空间注 ...
  • IPVS模式下ClusterIP泄露宿主机端口的问题
    问题 在一个启用了IPVS模式kube-proxy的K8S集群中,运行着一个Docker Registry服务 ...
  • 念爷爷
      今天是爷爷的头七,十二月七日、阴历十月廿三中午,老人家与世长辞。   九月初,回家看望刚动完手术的爸爸,发

  • 6 杨梅坑

  • liuhuashan
    深圳人才公园的网红景点 —— 流花山

  • 1 2020年10月拈花湾

  • 内核缺陷触发的NodePort服务63秒延迟问题
    现象 我们有一个新创建的TKE 1.3.0集群,使用基于Galaxy + Flannel(VXLAN模式)的容 ...
  • Galaxy学习笔记
    简介 Galaxy是TKEStack的一个网络组件,支持为TKE集群提供Overlay/Underlay容器网 ...
TOPLINKS
  • Zitahli's blue 91 people like this
  • 梦中的婚礼 64 people like this
  • 汪静好 61 people like this
  • 那年我一岁 36 people like this
  • 为了爱 28 people like this
  • 小绿彩 26 people like this
  • 杨梅坑 6 people like this
  • 亚龙湾之旅 1 people like this
  • 汪昌博 people like this
  • 彩虹姐姐的笑脸 24 people like this
  • 2013年11月香山 10 people like this
  • 2013年7月秦皇岛 6 people like this
  • 2013年6月蓟县盘山 5 people like this
  • 2013年2月梅花山 2 people like this
  • 2013年淮阴自贡迎春灯会 3 people like this
  • 2012年镇江金山游 1 people like this
  • 2012年徽杭古道 9 people like this
  • 2011年清明节后扬州行 1 people like this
  • 2008年十一云龙公园 5 people like this
  • 2008年之秋忆 7 people like this
  • 老照片 13 people like this
  • 火一样的六月 16 people like this
  • 发黄的相片 3 people like this
  • Cesium学习笔记 90 people like this
  • IntelliJ IDEA知识集锦 59 people like this
  • Bazel学习笔记 38 people like this
  • 基于Kurento搭建WebRTC服务器 38 people like this
  • PhoneGap学习笔记 32 people like this
  • NaCl学习笔记 32 people like this
  • 使用Oracle Java Mission Control监控JVM运行状态 29 people like this
  • Ceph学习笔记 27 people like this
  • 基于Calico的CNI 27 people like this
  • Three.js学习笔记 24 people like this
Tag Cloud
ActiveMQ AspectJ CDT Ceph Chrome CNI Command Cordova Coroutine CXF Cygwin DNS Docker eBPF Eclipse ExtJS F7 FAQ Groovy Hibernate HTTP IntelliJ IO编程 IPVS JacksonJSON JMS JSON JVM K8S kernel LB libvirt Linux知识 Linux编程 LOG Maven MinGW Mock Monitoring Multimedia MVC MySQL netfs Netty Nginx NIO Node.js NoSQL Oracle PDT PHP Redis RPC Scheduler ServiceMesh SNMP Spring SSL svn Tomcat TSDB Ubuntu WebGL WebRTC WebService WebSocket wxWidgets XDebug XML XPath XRM ZooKeeper 亚龙湾 单元测试 学习笔记 实时处理 并发编程 彩姐 性能剖析 性能调优 文本处理 新特性 架构模式 系统编程 网络编程 视频监控 设计模式 远程调试 配置文件 齐塔莉
Recent Comments
  • qg on Istio中的透明代理问题
  • heao on 基于本地gRPC的Go插件系统
  • 黄豆豆 on Ginkgo学习笔记
  • cloud on OpenStack学习笔记
  • 5dragoncon on Cilium学习笔记
  • Archeb on 重温iptables
  • C/C++编程:WebSocketpp(Linux + Clion + boostAsio) – 源码巴士 on 基于C/C++的WebSocket库
  • jerbin on eBPF学习笔记
  • point on Istio中的透明代理问题
  • G on Istio中的透明代理问题
  • 绿色记忆:Go语言单元测试和仿冒 on Ginkgo学习笔记
  • point on Istio中的透明代理问题
  • 【Maven】maven插件开发实战 – IT汇 on Maven插件开发
  • chenlx on eBPF学习笔记
  • Alex on eBPF学习笔记
  • CFC4N on eBPF学习笔记
  • 李运田 on 念爷爷
  • yongman on 记录一次KeyDB缓慢的定位过程
  • Alex on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • will on Istio中的透明代理问题
  • haolipeng on 基于本地gRPC的Go插件系统
  • 吴杰 on 基于C/C++的WebSocket库
©2005-2025 Gmem.cc | Powered by WordPress | 京ICP备18007345号-2