編譯概念
來源於 :https://baike.baidu.com/item/%E7%BC%96%E8%AF%91/1258343?fr=aladdin
編譯的基本流程
編譯可以分為五個基本步驟:詞法分析、語法分析、語義分析及中間代碼的生成、優化、目標代碼的生成。這是每個編譯器都必須的基本步驟和流程, 從源頭輸入高級語言源程序輸出目標語言代碼。 [2]
來源於:https://baike.baidu.com/item/%E7%BC%96%E8%AF%91%E5%8E%9F%E7%90%86/4194?fr=aladdin
程序包編譯
程序包編譯安裝:
Application-VERSION-release.src.rpm --> 安裝后,使用 rpmbuild 命令制作成二進制格式的rpm 包,而后再安裝源代碼--> 預處理--> 編譯--> 匯編--> 鏈接--> 執行.
源代碼組織格式:
多文件: 文件中的代碼之間,很可能存在跨文件依賴關系
C 、C++ : make 項目管理器,configure腳本 --> Makefile.in --> Makefile java: maven
編譯安裝
C 語言源代碼編譯安裝三步驟:
1。./configure
(1) 通過選項傳遞參數,指定啟用特性、安裝路徑等;執行時會參考用戶的指定,以及makefile.in 文件生成makefile
(2) 檢查依賴到的外部環境,如依賴的軟件包
2。make(項目編輯器):
根據makefile 文件,構建應用程序
為了加快編譯速度,可以采用這條命令make -j 4 && make install。-j表示可以多進程,多線程的並發編譯。 如果處理器數量為4個,-j最多寫4。 3。make install: 復制文件到相應路徑 開發工具: 同時開發者也可以自己生成 configure。使用autoconf生成configure腳本,使用automake生成Makefile.in。 autoconf:生成configure 腳本 automake:生成Makefile.in 注意: 安裝前查看INSTALL ,README 開源程序源代碼的獲取: 官方自建站點: apache.org (ASF :Apache Software Foundation) mariadb.org ... 代碼托管: SourceForge.net Github.com code.google.com c/c++ 編譯器: gcc (GNU C Complier) 編譯C源代碼: 准備: 提供開發工具及開發環境 開發工具: make(項目編輯器), gcc等 開發環境: 開發庫,頭文件 glibc : 標准庫 實現: 通過“包組”提供開發組件,Development Tools ,Server Platform Development 第一步:configure 腳本 選項:指定安裝位置、指定啟用的特性 --help: 獲取其支持使用的選項 選項分類: 安裝路徑設定: --prefix=/PATH: 指定默認安裝位置, 默認為/usr/local/ --sysconfdir=/PATH :配置文件安裝位置 System types: 支持交叉編譯 Optional Features: 可選特性 --disable-FEATURE --enable-FEATURE[=ARG] Optional Packages: 可選包 --with-PACKAGE[=ARG], 依賴包 --without-PACKAGE, 禁用依賴關系 第二步:make(項目編輯器) 第三步:make install 安裝后的配置: (1) 二進制程序目錄導入至PATH 環境變量中,編輯文件/etc/profile.d/NAME.sh,export PATH=/PATH/TO/BIN:$PATH (2) 導入庫文件路徑(不用做)。 編輯/etc/ld.so.conf.d/NAME.conf,添加新的庫文件所在目錄至此文件中,讓系統重新生成緩存: ldconfig [-v] (3) 導入頭文件(不用做) 基於鏈接的方式實現: ln -sv (4) 導入幫助手冊 編輯/etc/man.config|man_db.conf 文件 添加一個MANPATH
原文鏈接:https://www.cnblogs.com/shenxm/p/8403751.html
5分鍾理解make/makefile/cmake/nmake
最近,有沒有被make、cmake、makefile... ... 這些東西繞暈了,看看下面的文章,也許就可以理解清楚了。
1. gcc
它是GNU Compiler Collection(就是GNU編譯器套件),也可以簡單認為是編譯器,它可以編譯很多種編程語言(括C、C++、Objective-C、Fortran、Java等等)。
我們的程序只有一個源文件時,直接就可以用gcc命令編譯它。
可是,如果我們的程序包含很多個源文件時,該咋整?用gcc命令逐個去編譯時,就發現很容易混亂而且工作量大,所以出現了下面make工具。
2. make
make工具可以看成是一個智能的批處理工具,它本身並沒有編譯和鏈接的功能,而是用類似於批處理的方式—通過調用makefile文件中用戶指定的命令來進行編譯和鏈接的。
3. makefile
這個是啥東西?
簡單的說就像一首歌的樂譜,make工具就像指揮家,指揮家根據樂譜指揮整個樂團怎么樣演奏,make工具就根據makefile中的命令進行編譯和鏈接的。makefile命令中就包含了調用gcc(也可以是別的編譯器)去編譯某個源文件的命令。
makefile在一些簡單的工程完全可以人工拿下,但是當工程非常大的時候,手寫makefile也是非常麻煩的,如果換了個平台makefile又要重新修改,這時候就出現了下面的Cmake這個工具。
4. cmake
cmake就可以更加簡單的生成makefile文件給上面那個make用。當然cmake還有其他更牛X功能,就是可以跨平台生成對應平台能用的makefile,我們就不用再自己去修改了。
可是cmake根據什么生成makefile呢?它又要根據一個叫CMakeLists.txt文件(學名:組態檔)去生成makefile。
5. CMakeList.txt
到最后CMakeLists.txt文件誰寫啊?親,是你自己手寫的。
6. nmake[1]
nmake又是啥東西?
nmake是Microsoft Visual Studio中的附帶命令,需要安裝VS,實際上可以說相當於linux的make,明白了么?

根據上面總結一下大體流程:[2]
1.用編輯器編寫源代碼,如.c文件。
2.用編譯器編譯代碼生成目標文件,如.o。
3.用鏈接器連接目標代碼生成可執行文件,如.exe。
但如果源文件太多,一個一個編譯那得多麻煩啊?於是人們想到,為啥不設計一種類似批處理的程序,來批處理編譯源文件呢?
於是就有了make工具,它是一個自動化編譯工具,你可以使用一條命令實現完全編譯。但是你需要編寫一個規則文件,make依據它來批處理編譯,這個文件就是makefile,所以編寫makefile文件也是一個程序員所必備的技能。
對於一個大工程,編寫makefile實在是件復雜的事,於是人們又想,為什么不設計一個工具,讀入所有源文件之后,自動生成makefile呢,於是就出現了cmake工具,它能夠輸出各種各樣的makefile或者project文件,從而幫助程序員減輕負擔。但是隨之而來也就是編寫cmakelist文件,它是cmake所依據的規則。(cmake中有很多設置庫的,此時還不是可執行文件,而make生成后才是二進制可執行文件。)
所以在編程的世界里沒有捷徑可走,還是要腳踏實地的。
原文鏈接:https://zhuanlan.zhihu.com/p/111110992?from_voters_page=true
一、編譯安裝概述
前面兩篇關於程序包管理器的文章談到,無論是使用rpm命令還是yum命令安裝的都是已編譯好的程序包,在整個安裝過程中用戶只需執行一條命令即可完成安裝。這樣帶來的好處是方便,但因為是安裝的是已編譯好的包,所以用戶的系統平台環境必須與rpm包制作者的系統平台環境相同。此外,如果用戶要安裝使用某程序上的某個功能,而rpm包制作者在編譯過程中默認沒有指定該功能的實現,這時候該怎么辦呢?更何況如果某程序只是提供源碼而沒有現成的rpm包。這時就需要用戶手動編譯安裝了,而編譯安裝就是將程序源代碼編譯成完全適合自己平台類型的程序包。
因此,用戶首先得獲得程序源碼包(SRPM, Source RPM)。RPM包的命名格式為:name-VERSION-release.arch.rpm,而程序源碼包(SRPM)的命名格式為:name-VERSION-release.src.rpm。可以發現,SRPM與RPM相比,將arch替換為src,說明SRPM包去掉了arch這一平台類型限制,因此經過用戶自己編譯安裝可以編譯成適合自己平台的程序包。
以下為編譯過程圖解(以C源代碼為例):
我們知道,程序源代碼一般為多文件組織格式,因此文件中的代碼文件之間很有可能存在跨文件的依賴關系,這將給用戶自行編譯安裝帶來了極大麻煩,因為對先編譯哪些文件、后編譯哪些文件根本無從知曉,因此這就需要項目管理器(或者項目構建器)了。C/C++的項目管理器為make,make工具可以在編譯過程中指定使用哪個預處理器進行預處理、使用哪個編譯器進行編譯以及先編譯什么程序文件、后編譯什么程序文件,甚至完成更為復雜的操作等,能幫助用戶快速地編譯安裝。make工具的執行依賴於makefile配置文檔,因此make執行的所有操作皆由makefile指定。makefile可由執行configure腳本生成。而在執行configure腳本時,configure會結合用戶通過命令行指定的選項以及各個Makefile.in模板文件來生成makefile文件。編譯完成之后即可使用make install命令將編譯好的程序包復制到用戶指定的各個目錄下。
二、C代碼編譯安裝三步驟
(1) 執行configure腳本(# ./configure [option...])
常用選項:
--help:獲得其支持使用的選項 --prefix=/PATH/TO/SOMEWHERE:指定默認安裝位置;默認為/usr/local/; --sysconfdir=/PATH/TO/SOMEWHERE:配置文件安裝位置; --enable-FEATURE[=ARG]:開啟指定特性以及安裝路徑;默認開啟時無須指定; --disable-FEATURE:關閉指定特性;默認關閉時無須指定; --with-PACKAGE[=ARG]:安裝指定依賴包以及其安裝路徑; --without-PACKAGE:不安裝指定依賴包;
執行configure腳本的作用:
①用戶可以通過選項傳遞參數給configure腳本,以指定啟用的功能特性、安裝路徑等;而configure腳本在執行的過程中會參考用戶的指定以及Makefile.in文件生成makefile文件;
②檢查程序指定要啟用的功能特性所依賴到的外部環境。
(2) 執行make程序
作用:
make會執行真正的編譯操作,但make本身並不是編譯器,它只是一個項目構建工具,make程序會根據執行configure腳本所生成的makefile文件,並調用所需要用到的編譯器來構建應用程序。
(3) 執行make install安裝操作
作用:
在前面的make程序執行之后,在當前目錄下會創建出已編譯完成的目標二進制格式的應用程序(包括二進制程序、庫文件、配置文件及幫助文檔等),而make install則會執行安裝操作,即把當前目錄下已編譯好的程序包(二進制程序、庫文件、配置文件及幫助文檔等)復制到用戶指定的各個目錄下。
注意:各個程序在編譯安裝過程中可能不盡相同,因此建議安裝前查看INSTALL, README。
三、編譯安裝后的配置
(1) 導出目標二進制程序目錄至PATH環境變量中
方法:
在生產環境中如果該二進制程序作為全局變量,可以在/etc/profile.d/目錄下創建/etc/profile.d/NAME.d文件,其中"NAME"可定義設置名稱。在該文件中寫入下面一行:
export PATH=PATH:/PATH/TO/BIN
這里的/PATH/TO/BIN即為目標二進制程序所在目錄。
如果要想編譯后的命令程序優先被查找到,可以添加在環境變量PATH的前面,如下:
export PATH=/PATH/TO/BIN:PATH
(2) 導出庫文件路徑
方法:
①在/etc/ld.so.conf.d/目錄下創建/etc/ld.so.conf.d/NAME.conf,其中NAME為自定義設置名稱。而后,添加新的庫文件所在目錄至此文件中即可。
②做完這一步之后,需要讓系統重新加載庫文件(重新生成緩存):
# ldconfig [-v]
查看當前系統上已加載的庫文件:
# ldconfig -p
(3) 導出頭文件(位於include目錄)
程序編譯安裝完成之后,一般在安裝路徑中會有include目錄,這個include目錄就是頭文件,頭文件的功能是把外部文件的內容包含到源文件中,例如外部函數等。在程序開始編譯之前,會執行一段預處理指令,而預處理指令則把頭文件的內容包含到源文件中。
如果要導出頭文件,可基於軟鏈接的方式來實現:
# ln -sv 頭文件目錄 鏈接頭文件目錄(/usr/include/NAME)
這里鏈接頭文件目錄一般為/usr/include/NAME,其中NAME可以是程序名,例如/usr/include/httpd。
(4) 導出幫助手冊
方法:
在CentOS 6上:
編輯/etc/man.config文件,添加一個MANPATH:
# MANPATH /PATH/TO/MAN
這里"/PATH/TO/MAN"為目標程序的安裝路徑下的幫助手冊目錄。
在CentOS 7上:
編輯/etc/man_db.conf文件,添加一個MANPATH:
# MANPATH_MAP /PATH/TO/BIN /PATH/TO/MAN
這里/PATH/TO/BIN是目標二進制程序所在目錄,/PATH/TO/MAN則是該程序的幫助手冊所在目錄。
本文出自 “Tab” 博客,請務必保留此出處http://xuweitao.blog.51cto.com/11761672/1905357
原文地址:http://xuweitao.blog.51cto.com/11761672/1905357
Nginx編譯安裝詳情
請點擊: Nginx多種安裝方式
某次安裝編譯工具報錯glibc-devel的解決過程
[root@mcwxxxxxxx-4 /etc/yum.repos.d]# yum install gcc ...... --> Finished Dependency Resolution Error: Package: gcc-4.8.5-44.el7.x86_64 (mcwself) Requires: glibc-devel >= 2.2.90-12 You could try using --skip-broken to work around the problem You could try running: rpm -Va --nofiles --nodigest [root@mcwxxxxxxx-4 /etc/yum.repos.d]# yum install glibc-devel --> Finished Dependency Resolution Error: Package: glibc-headers-2.17-325.el7_9.x86_64 (mcw2self) Requires: kernel-headers >= 2.2.1 Error: Package: glibc-headers-2.17-325.el7_9.x86_64 (mcw2self) Requires: kernel-headers You could try using --skip-broken to work around the problem You could try running: rpm -Va --nofiles --nodigest [root@mcwxxxxxxx-4 /etc/yum.repos.d]# rpm -qa|grep kernel-headers [root@mcwxxxxxxx-4 /etc/yum.repos.d]# cd /home/machangwei/ [root@mcwxxxxxxx-4 /home/machangwei]# rpm -ivh kernel-headers-3.10.0-1160.45.1.el7.x86_64.rpm warning: kernel-headers-3.10.0-1160.45.1.el7.x86_64.rpm: Header V3 RSA/SHA256 Signature, key ID f4a80eb5: NOKEY Preparing... ################################# [100%] Updating / installing... 1:kernel-headers-3.10.0-1160.45.1.e################################# [100%] [root@mcwxxxxxxx-4 /home/machangwei]# yum install glibc-devel [root@mcwxxxxxxx-4 /home/machangwei]# yum install gcc gcc-c++ Installed: gcc.x86_64 0:4.8.5-44.el7 gcc-c++.x86_64 0:4.8.5-44.el7 Dependency Installed: cpp.x86_64 0:4.8.5-44.el7 libmpc.x86_64 0:1.0.1-3.el7 libstdc++-devel.x86_64 0:4.8.5-44.el7 mpfr.x86_64 0:3.1.1-4.el Dependency Updated: libgcc.x86_64 0:4.8.5-44.el7 libgomp.x86_64 0:4.8.5-44.el7 libstdc++.x86_64 0:4.8.5-44.el7 [root@mcwxxxxxxx-4 /home/machangwei]# rpm -qa|egrep "gcc|gcc-c++|make" gcc-c++-4.8.5-44.el7.x86_64 make-3.82-24.el7.x86_64 gcc-4.8.5-44.el7.x86_64 libgcc-4.8.5-44.el7.x86_64 這次安裝總共裝了這些包:gcc|gcc-c++|make|glibc-devel|kernel-headers
編譯安裝的是可以遷移其它目錄和主機的
如果是編譯安裝的python和 sqlite等,編譯安裝指定某個目錄后,直接打包目錄,不只是能跨主機,也是能跨目錄的,不是非要在編譯安裝的目錄才能使用
比如下面這個,python3和sqlite都是編譯安裝到/opt目錄下的,但是直接打包放到別的目錄或者別的主機,照樣可以運行程序
詳情點擊 這里
是否