Swarmkit笔记(16)——运行“make setup”命令

在运行“make”或“make xxx”命令之前,要先运行“make setup”命令。否则,“make”会失败:

# make
......
 lint
/bin/sh: 1: golint: not found
......

make generate”也会失败:

# make generate
 bin/protoc-gen-gogoswarm
 generate
mockgen -package exec -destination controller_test.mock.go -source controller.go Controller StatusReporter
agent/exec/controller_test.go:17: running "mockgen": exec: "mockgen": executable file not found in $PATH
protoc -I.:../protobuf:../vendor:../vendor/github.com/gogo/protobuf --gogoswarm_out=plugins=grpc+deepcopy+raftproxy+authenticatedwrapper,import_path=github.com/docker/swarmkit/api,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto,Mtimestamp/timestamp.proto=github.com/docker/swarmkit/api/timestamp,Mduration/duration.proto=github.com/docker/swarmkit/api/duration,Mgoogle/protobuf/descriptor.proto=github.com/gogo/protobuf/protoc-gen-gogo/descriptor,Mplugin/plugin.proto=github.com/docker/swarmkit/protobuf/plugin:. types.proto specs.proto objects.proto control.proto dispatcher.proto ca.proto snapshot.proto raft.proto health.proto resource.proto
protoc -I.:../../vendor:../../vendor/github.com/gogo/protobuf --gogoswarm_out=plugins=grpc+deepcopy+raftproxy+authenticatedwrapper,import_path=github.com/docker/swarmkit/api/duration,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. duration.proto
protoc -I.:../../vendor:../../vendor/github.com/gogo/protobuf --gogoswarm_out=plugins=grpc+deepcopy+raftproxy+authenticatedwrapper,import_path=github.com/docker/swarmkit/api/timestamp,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. timestamp.proto
protoc -I.:/usr/local --gogoswarm_out=import_path=github.com/docker/swarmkit/protobuf/plugin,Mgoogle/protobuf/descriptor.proto=github.com/gogo/protobuf/protoc-gen-gogo/descriptor:. plugin.proto
protoc -I.:../../../../vendor --gogoswarm_out=plugins=deepcopy,import_path=github.com/docker/swarmkit/protobuf/plugin/deepcopy/test:. deepcopy.proto
protoc -I.:../../../../vendor --gogoswarm_out=plugins=grpc+raftproxy,import_path=github.com/docker/swarmkit/protobuf/plugin/raftproxy/test:. service.proto
Makefile:43: recipe for target 'generate' failed
make: *** [generate] Error 1

参考Why does “make generate” fail?

调试Makefile的工具——remake

这两天在调试开源项目的一个Makefile,发现了remake这个工具(项目主页:http://bashdb.sourceforge.net/remake/),真的很好用。稍微大型点的开源项目,Makefile都很复杂,一旦出了错,很令人抓狂。而这个remake工具产生的输出能把整个编译过程的来龙去脉打印的很清楚。举例如下,一个简单的编译Linux模块的Makefile

ifneq ($(KERNELRELEASE),)
        obj-m := hello.o
else
        KDIR ?= /lib/modules/`uname -r`/build
default:
        $(MAKE) -C $(KDIR) M=$$PWD
endif

执行remake -x命令:

# remake -x
Reading makefiles...
Updating goal targets....
 File 'default' does not exist.
Must remake target 'default'.
Makefile:8: target 'default' does not exist
##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
remake -C /lib/modules/`uname -r`/build M=$PWD
##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Reading makefiles...
Updating goal targets....
 File 'all' does not exist.
Must remake target 'all'.
remake[1]: Entering directory '/usr/src/linux-3.12.49-6-obj/x86_64/default'
Makefile:26: target 'all' does not exist
##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
remake -C ../../../linux-3.12.49-6 O=/usr/src/linux-3.12.49-6-obj/x86_64/default/.
##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Reading makefiles...
Updating goal targets....
 File '_all' does not exist.
   File 'sub-make' does not exist.
     File 'FORCE' does not exist.
    Must remake target 'FORCE'.
    Successfully remade target file 'FORCE'.
  Must remake target 'sub-make'.
Makefile:195: update target 'sub-make' due to: FORCE
##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
echo "make[1]: Entering directory \`/usr/src/linux-3.12.49-6-obj/x86_64/default'"
##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
make[1]: Entering directory `/usr/src/linux-3.12.49-6-obj/x86_64/default'
##>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
remake -C /usr/src/linux-3.12.49-6-obj/x86_64/default \
KBUILD_SRC=/usr/src/linux-3.12.49-6 \
KBUILD_EXTMOD="/root/Documents/test" -f /usr/src/linux-3.12.49-6/Makefile \

##<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
......

可以看到,输出了非常详细的日志信息,很方便debug

 

Linux kernel 笔记 (32)——“make“和”make modules“

以下摘自LKD:

After the kernel configuration is set—however you do it—you can build it with a single command:
$ make
Unlike kernels before 2.6, you no longer need to run make dep before building the kernel—the dependency tree is maintained automatically.You also do not need to specify a specific build type, such as bzImage, or build modules separately, as you did in old versions.The default Makefile rule will handle everything.

也就是在2.6版本以后的Linux kernel中,执行makemake all命令即包含了make modules。也可参加这个帖子

 

Linux kernel 笔记 (31)——“make help”命令

make help命令列出编译kernel时的选项帮助信息:

linux-4cy8:/usr/src/linux/build # make help
make -C /usr/src/linux-3.0.101-63 O=/usr/src/linux-3.0.101-63/build/. help
Cleaning targets:
  clean           - Remove most generated files but keep the config and
                    enough build support to build external modules
  mrproper        - Remove all generated files + config + various backup files
  distclean       - mrproper + remove editor backup and patch files

Configuration targets:
  config          - Update current config utilising a line-oriented program
  nconfig         - Update current config utilising a ncurses menu based program
  menuconfig      - Update current config utilising a menu based program
  xconfig         - Update current config utilising a QT based front-end
  gconfig         - Update current config utilising a GTK based front-end
  oldconfig       - Update current config utilising a provided .config as base
  localmodconfig  - Update current config disabling modules not loaded
  localyesconfig  - Update current config converting local mods to core
  silentoldconfig - Same as oldconfig, but quietly, additionally update deps
  defconfig       - New config with default from ARCH supplied defconfig
  savedefconfig   - Save current config as ./defconfig (minimal config)
  allnoconfig     - New config where all options are answered with no
  allyesconfig    - New config where all options are accepted with yes
  allmodconfig    - New config selecting modules when possible
  alldefconfig    - New config with all symbols set to default
  randconfig      - New config with random answer to all options
  listnewconfig   - List new options
  oldnoconfig     - Same as silentoldconfig but set new symbols to n (unset)

Other generic targets:
  all             - Build all targets marked with [*]
* vmlinux         - Build the bare kernel
* modules         - Build all modules
  modules_install - Install all modules to INSTALL_MOD_PATH (default: /)
  firmware_install- Install all firmware to INSTALL_FW_PATH
                    (default: $(INSTALL_MOD_PATH)/lib/firmware)
  dir/            - Build all files in dir and below
  dir/file.[oisS] - Build specified target only
  dir/file.lst    - Build specified mixed source/assembly target only
                    (requires a recent binutils and recent build (System.map))
  dir/file.ko     - Build module including final link
  modules_prepare - Set up for building external modules
  tags/TAGS       - Generate tags file for editors
  cscope          - Generate cscope index
  gtags           - Generate GNU GLOBAL index
  kernelrelease   - Output the release version string
  kernelversion   - Output the version stored in Makefile
  headers_install - Install sanitised kernel headers to INSTALL_HDR_PATH
                    (default: /usr/src/linux-3.0.101-63/build/usr)

Static analysers
  checkstack      - Generate a list of stack hogs
  namespacecheck  - Name space analysis on compiled kernel
  versioncheck    - Sanity check on version.h usage
  includecheck    - Check for duplicate included header files
  export_report   - List the usages of all exported symbols
  headers_check   - Sanity check on exported headers
  headerdep       - Detect inclusion cycles in headers
  coccicheck      - Check with Coccinelle.

Kernel packaging:
  rpm-pkg             - Build both source and binary RPM kernel packages
  binrpm-pkg          - Build only the binary kernel package
  deb-pkg             - Build the kernel as an deb package
  tar-pkg             - Build the kernel as an uncompressed tarball
  targz-pkg           - Build the kernel as a gzip compressed tarball
  tarbz2-pkg          - Build the kernel as a bzip2 compressed tarball
  tarxz-pkg           - Build the kernel as a xz compressed tarball
  perf-tar-src-pkg    - Build perf-3.0.101.tar source tarball
  perf-targz-src-pkg  - Build perf-3.0.101.tar.gz source tarball
  perf-tarbz2-src-pkg - Build perf-3.0.101.tar.bz2 source tarball
  perf-tarxz-src-pkg  - Build perf-3.0.101.tar.xz source tarball

Documentation targets:
 Linux kernel internal documentation in different formats:
  htmldocs        - HTML
  pdfdocs         - PDF
  psdocs          - Postscript
  xmldocs         - XML DocBook
  mandocs         - man pages
  installmandocs  - install man pages generated by mandocs
  cleandocs       - clean all generated DocBook files

Architecture specific targets (x86):
* bzImage      - Compressed kernel image (arch/x86/boot/bzImage)
  install      - Install kernel using
                  (your) ~/bin/installkernel or
                  (distribution) /sbin/installkernel or
                  install to $(INSTALL_PATH) and run lilo
  fdimage      - Create 1.4MB boot floppy image (arch/x86/boot/fdimage)
  fdimage144   - Create 1.4MB boot floppy image (arch/x86/boot/fdimage)
  fdimage288   - Create 2.8MB boot floppy image (arch/x86/boot/fdimage)
  isoimage     - Create a boot CD-ROM image (arch/x86/boot/image.iso)
                  bzdisk/fdimage*/isoimage also accept:
                  FDARGS="..."  arguments for the booted kernel
                  FDINITRD=file initrd for the booted kernel

  i386_defconfig           - Build for i386
  x86_64_defconfig         - Build for x86_64

  make V=0|1 [targets] 0 => quiet build (default), 1 => verbose build
  make V=2   [targets] 2 => give reason for rebuild of target
  make O=dir [targets] Locate all output files in "dir", including .config
  make C=1   [targets] Check all c source with $CHECK (sparse by default)
  make C=2   [targets] Force check of all c source with $CHECK
  make W=n   [targets] Enable extra gcc checks, n=1,2,3 where
                1: warnings which may be relevant and do not occur too often
                2: warnings which occur quite often but may still be relevant
                3: more obscure warnings, can most likely be ignored
                Multiple levels can be combined with W=12 or W=123
  make RECORDMCOUNT_WARN=1 [targets] Warn about ignored mcount sections

Execute "make" or "make all" to build all targets marked with [*]
For further info see the ./README file

很有用!!

 

Linux kernel 笔记 (27)——“make clean”和“make mrproper”的区别

参考Recompiling the kernel

Sometimes, you’ll change things so much that make can’t figure out how to recompile the files correctly. make clean will remove all the object and kernel object files (ending in .o and .ko) and a few other things. make mrproper will do everything make clean does, plus remove your config file, the dependency files, and everything else that make config creates. Be sure to save your config file in another file before running make mrproper. Afterwards, copy the config file back to .config and start over, beginning at make menuconfig. A make mrproper will often fix strange kernel crashes that make no sense and strange compilation errors that make no sense.

make clean删除objectkernel object文件,还有其它一些文件。make mrpropermake clean的超集,它还会删除config文件,依赖文件,以及其它make config生成的文件。

 

Linux kernel 笔记 (26)——利用“make -j”提高编译`kernel`速度

首先看一下-j选项在make命令中的含义:

-j [jobs], --jobs[=jobs]
        Specifies the number of jobs (commands) to run simultaneously.   If  there  is  more  than  one  -j
        option,  the  last  one is effective.  If the -j option is given without an argument, make will not
        limit the number of jobs that can run simultaneously.

也就是-j指定并行工作的job数量,例如make -j4。如果-j选项后面没有参数,则不会限制job数。

再参考《Linux kernel development》:

By default, make spawns only a single job because Makefiles all too often have incorrect dependency information.With incorrect dependencies, multiple jobs can step on each other’s toes, resulting in errors in the build process.The kernel’s Makefiles have correct dependency information, so spawning multiple jobs does not result in failures.To build the kernel with multiple make jobs, use

$ make -jn

Here, n is the number of jobs to spawn. Usual practice is to spawn one or two jobs per processor. For example, on a 16-core machine, you might do

$ make -j32 > /dev/null

可以看到指定job数是系统core数量2倍是一种推荐的做法。

 

Linux kernel 笔记 (22)——一个简单的模块Makefile

LDD3Compiling and Loading一节的编译模块的Makefile为例:

# If KERNELRELEASE is defined, we've been invoked from the
# kernel build system and can use its language.
ifneq ($(KERNELRELEASE),)
    obj-m := hello.o 

# Otherwise we were called directly from the command
# line; invoke the kernel build system.
else

    KERNELDIR ?= /lib/modules/$(shell uname -r)/build
    PWD  := $(shell pwd)

default:
    $(MAKE) -C $(KERNELDIR) M=$(PWD) modules

endif

当在命令行执行make命令时(当前工作目录即模块源文件所在目录),因为当前模块所在目录里没有定义KERNELRELEASE,所以执行else部分,即把KERNELDIRPWD变量赋值。

接下来执行“$(MAKE) -C $(KERNELDIR) M=$(PWD) modules”命令。-C选项的含义是把目录切换到KERNELDIR目录下,然后读取KERNELDIR目录下的MakefileM选项是在编译modules再切换回模块所在目录。此时由于KERNELRELEASE变量已经定义,即可以得知需要编译obj-m

参考资料:
Understanding a make file for making .ko files