PostgreSQL開發(fā) - 編譯配置

PostgreSQL用的是autoconf和automake來管理編譯的。

image

從這個(gè)圖可以看到autoscan,automake,aclocal,autoconf,autoheader一共5個(gè)命令工具。

  1. autoscan, 目測(cè)沒有用到, 直接手工修改configgure.in
  2. aclocal, 生成aclocal.m4
  3. autoheader, 生成src/config/pg_config.h.in
  4. automake, 生成Makefile.in
  5. autoconf, 生成configure
  6. configure生成config.hMakefile
  7. 最后使用make命令讀取Makefile執(zhí)行編譯和安裝等操作

m4

http://www.gnu.org/software/m4/m4.html

M4是一個(gè)Unix宏處理器, 用于將輸入賦值到模板中并展開成輸出. 可以使用簡(jiǎn)單的運(yùn)算和字符串操作, 主要用于編譯前的預(yù)處理. 主要是因?yàn)閍utoconf而使用. M4存在于各種類Unix系統(tǒng)中, 并且已經(jīng)被POSIX(Portable Operating System Interface)標(biāo)準(zhǔn)化 .

m4中的m應(yīng)該就是macro。

在PostgreSQL源碼里的config目錄下有一堆m4文件。

aclocal

aclocal是一個(gè)perl腳本程序,它的定義是:aclocal - create aclocal.m4 by scanning configure.ac(configure.in)。
autoconf需要GNU m4宏處理器來處理aclocal.m4,以生成configure腳本。

autoconf

https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.69/autoconf.html

Autoconf 是一個(gè)可擴(kuò)展的M4宏集合, 用于產(chǎn)生shell腳本來自動(dòng)配置軟件源碼. 這些腳本可以自動(dòng)適配多種類Unix的操作系統(tǒng). 需要與automake, libtool合用產(chǎn)生可移植的軟件.

configure.in

舊的項(xiàng)目是configure.in, 現(xiàn)在新的項(xiàng)目都是configure.ac了。
一般是基于 autoscan生成的configure.scan修改而來或者純手工編寫。

PostgreSQL的configure.in文件說明:

dnl Process this file with autoconf to produce a configure script.
dnl configure.in
dnl
dnl Developers, please strive to achieve this order:
dnl
dnl 0. Initialization and options processing
dnl 1. Programs
dnl 2. Libraries
dnl 3. Header files
dnl 4. Types
dnl 5. Structures
dnl 6. Compiler characteristics
dnl 7. Functions, global variables
dnl 8. System services
dnl
dnl Read the Autoconf manual for details.
dnl

常用預(yù)定義宏:

基礎(chǔ)設(shè)置

AC_INIT(PACKAGE, VERSION, BUG_REPORT_EMAIL)
AC_PREREQ(VERSION) # 最小支持的autoconf版本號(hào)
AC_CONFIG_SRCDIR(FILE) # safe check 確保configure的確是在正確的目錄中被執(zhí)行的
AC_CONFIG_AUX_DIR(DIR) # 輔助目錄地址,存放install-sh和depcomp等輔助工具文件,若不指定會(huì)在當(dāng)前目錄直接創(chuàng)建輔助工具文件

src/template

--with-template=的值對(duì)應(yīng)的配置模板, 一類操作系統(tǒng)是一個(gè)單獨(dú)的文件, 如果這里沒有對(duì)應(yīng)系統(tǒng)的模板, 就用--with-template來指定一個(gè)接近的。

Makefile

PostgreSQL使用GNUMakefile進(jìn)行編譯, 但是在根目錄有一個(gè)Makefile, 這個(gè)文件的說明如下:

# The PostgreSQL make files exploit features of GNU make that other
# makes do not have. Because it is a common mistake for users to try
# to build Postgres with a different make, we have this make file
# that, as a service, will look for a GNU make and invoke it, or show
# an error message if none could be found.

就是說, 手工寫這個(gè)Makefile是為了防止用戶搞錯(cuò), 用了其他的make來編譯。
其他的make會(huì)執(zhí)行Makefile, 而這個(gè)Makefile會(huì)重新調(diào)用GNU make
GNU make會(huì)先找到GNUMakefile從而繞過這個(gè)Makefile文件。

PostgreSQL的編譯目標(biāo)

  1. all : 包含其他所有目標(biāo)
  2. check
  3. install
  4. installdirs
  5. installcheck
  6. installcheck-parallel
  7. uninstall
  8. clean
  9. distclean
  10. maintainer-clean
  11. dist
  12. distcheck
  13. world
  14. check-world
  15. install-world
  16. installcheck-world

GNUMakefile.in

這個(gè)文件可以用automake生成, 也可以手工寫。PostgreSQL里的這個(gè)文件看著像是手工寫的。

src/Makefile.global.in

GNUMakefile.in文件的第一步就是引入這個(gè)文件, 用于設(shè)置全局的變量。
其他文件夾下的所有Makefile第一件事也是引入這個(gè)文件。

#------------------------------------------------------------------------------
# All PostgreSQL makefiles include this file and use the variables it sets,
# which in turn are put here by the configure script. There is no need for
# users to edit this file -- if it turns out to be necessary then that's a
# bug.
#
# A makefile that includes this file needs to set the variable subdir to
# the relative path from the top to itself and top_builddir to the relative
# path from itself to the top before including this file. (The "top" is the
# parent directory of the directory this file is in.)
#------------------------------------------------------------------------------

其他Makefile引入本文件之前,需要定義以下兩個(gè)變量:

  1. subdir : 當(dāng)前Makefile文件相對(duì)于根目錄的相對(duì)路徑
  2. top_builddir : 相對(duì)于當(dāng)前Makefile文件的根路徑

主要設(shè)置的變量

  1. 從PGXS讀取PostgreSQL的信息bindir,datadir,sysconfdir,includedir等等。
  2. PostgreSQL的功能特性開關(guān): with_*, enable_*, python_*等等。
  3. 編譯器的變量: CC,GCC,LIBS等等
  4. 安裝最終調(diào)用的shell是install-sh: install_sh = $(SHELL) $(top_srcdir)/config/install-sh -c
  5. 生成/更新一些頭文件, 譬如:
    1. 更新配置狀態(tài): $(top_builddir)/config.status
    2. $(top_builddir)/src/include/pg_config.h
    3. $(top_builddir)/src/include/stamp-h
    4. $(top_builddir)/src/include/pg_config_ext.h
    5. $(top_builddir)/src/interfaces/ecpg/include/ecpg_config.h
  6. 定義recurse函數(shù),用于遞歸處理子目錄, 它有3個(gè)參數(shù):
    1. $1: targets to make recursive (defaults to list of standard targets)
    2. $2: list of subdirs (defaults to SUBDIRS variable)
    3. $3: target to run in subdir (defaults to current element of $1)
      函數(shù)體:
    foreach target, $(if $1,$1,$(standard_targets)), 
      foreach subdir, $(if $2,$2,$(SUBDIRS)), 
        eval $(call _create_recursive_target,$(target),$(subdir), $(if $3,$3,$(target)))
    
  7. Native language support: include $(top_srcdir)/src/nls-global.mk
  8. LLVM support

PostgreSQL的Makefile分布

基本上, 每個(gè)子目錄都有一個(gè)Makefile的, 然后編譯的時(shí)候, 通過./configure讀取GNUMakefile.in生成GNUMakefile, 然后make讀取GNUMakefile通過遞歸的方式依次調(diào)用各個(gè)子目錄里的這些Makefile逐個(gè)目錄編譯, 最終完成整個(gè)編譯。

src/
  backend/
    access/Makefile
      brin/Makefile
      common/Makefile
      gin/Makefile
      gist/Makefile
      hash/Makefile
      heap/Makefile
      index/Makefile    --------------> 這個(gè)是索引訪問方法的API
      nbtree/Makefile
      rmgrdesc/Makefile --------------> the rmgr descriptor routines
      nbtree/Makefile
      spgist/Makefile
      table/Makefile    --------------> 這個(gè)是表訪問方法的API
      tablesample/Makefile
      transam/Makefile
    bootstrap/Makefile      --------------> routines to support running postgres in 'bootstrap' mode
    catalog/Makefile
      system_views.sql
      information_schema.sql
      Catalog.pm
      sql_features.txt : sql特性支持情況
      sql_feature_packages.txt : sql特性支持情況
      genbki.pl : Perl script that generates postgres.bki.  The BKI files are used to initialize the postgres template database.
    commands/Makefile
    foreign/Makefile   --------------> support for foreign-data wrappers, servers and user mappings.
    jit/Makefile
      llvm/Makefile    --------------> the LLVM JIT provider, building it into a shared library.
    lib/Makefile
    libpq/Makefile     --------------> libpq subsystem (backend half of libpq interface)
    main/Makefile
    nodes/Makefile
    optimizer/Makefile
      geqo/Makefile    --------------> the genetic query optimizer module
      path/Makefile
      plan/Makefile
      prep/Makefile
      util/Makefile
    parser/Makefile
    partitioning/Makefile
    po/*.po --------------> simplified 某種語言 translation file for PostgreSQL server
    port/Makefile  --------------> 有一些.s文件,是匯編?
    postmaster/Makefile
    regex/Makefile
    replication/Makefile
      libpqwalreceiver/Makefile ---->是一個(gè)動(dòng)態(tài)庫, receive WAL during streaming replication 
      logical/Makefile
      pgoutput/Makefile   ---->是一個(gè)動(dòng)態(tài)庫, standard logical replication output plugin
    rewrite/Makefile
    snowball/Makefile
    statistics/Makefile
    storage/Makefile
      buffer/Makefile
      file/Makefile
      freespace/Makefile
      ipc/Makefile
      large_object/Makefile
      lmgr/Makefile
      page/Makefile
      smgr/Makefile
      sync/Makefile
    tcop/Makefile   ----> 這個(gè)是什么代碼??
    tsearch/Makefile   ----> 還有一些字典文件在這里邊
    utils/Makefile
      adt/Makefile  ----> dt應(yīng)該是data type, 但是a代表什么?
      cache/Makefile
      error/Makefile
      fmgr/Makefile
      hash/Makefile
      init/Makefile
      mb/Makefile
      misc/Makefile
      mmgr/Makefile
      resowner/Makefile
      sort/Makefile
      time/Makefile
  bin/  ----------> client programs, 這下面的是一堆客戶端工具命令
  makefiles/
    pgxs.mk   -----> contrib目錄下的插件需要引用它
  port/Makefile
  template/
  test/ -------> 這個(gè)目錄存放了各種各樣的測(cè)試代碼
  timezone/
  tutorial/

這些文件的結(jié)構(gòu)都非常相似。

Makefile知識(shí)

call函數(shù)

call函數(shù)是唯一一個(gè)可以用來創(chuàng)建新的參數(shù)化的函數(shù)。你可以寫一個(gè)非常復(fù)雜的表達(dá)式,這個(gè)表達(dá)式中,你可以定義許多參數(shù),然后你可以用call函數(shù)來向這個(gè)表達(dá)式傳遞參數(shù)。其語法是:

$(call 表達(dá)式, 參數(shù)1, 參數(shù)2,...)

當(dāng)make執(zhí)行這個(gè)函數(shù)時(shí),參數(shù)中的變量,如$(1),$(2),$(3)等,會(huì)被參數(shù),,依次取代。而返回值就是call函數(shù)的返回值。例如:

    reverse =  $(1) $(2)
    foo = $(call reverse,a,b)

那么,foo的值就是“a b”。當(dāng)然,參數(shù)的次序是可以自定義的,不一定是順序的,如:

    reverse = $(2) $(1)
    foo = $(call reverse,a,b)

此時(shí)的foo的值就是“b a”。

TAS

src/backend/port/Makefile
port是對(duì)各種底層架構(gòu)的適配, 其中出現(xiàn)了TAS, 這里科普下它是什么:

PostgreSQL中使用spinlock來對(duì)資源進(jìn)行加鎖。TAS lock是最簡(jiǎn)單的spinlock。當(dāng)然spinlock可以用信號(hào)量來實(shí)現(xiàn)。但是據(jù)PostgreSQL的早期報(bào)告顯示,內(nèi)核提供的信號(hào)量將大大降低性能。所以學(xué)習(xí)TAS lock對(duì)我們提高軟件性能是大有幫助的。
TAS就是Test And Set。它要做的就是跟一個(gè)變量進(jìn)行Test。如果條件滿足對(duì)其Set另外一個(gè)值,如果條件不滿足,就繼續(xù)等待。但是所有這些都是原子操作。
Windows提供了一個(gè)API:InterlockedCompareExchange。PostgreSQL的Windows版本就是利用它來實(shí)現(xiàn)TAS的。

https://blog.csdn.net/gp_community/article/details/109719815
https://www.iteye.com/blog/aoogoo-591059

參考文檔:

  1. postgresql 編譯源碼時(shí),在預(yù)編譯configure中,添加配置選項(xiàng)
  2. 編寫configure.ac
  3. configure.ac介紹
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容