日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

【c++】Scons|scons对比make

發布時間:2023/12/20 c/c++ 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【c++】Scons|scons对比make 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

目錄

簡略說明

什么是Scons

遺留疑問:Scons 和cmake 對比如何?

scons對比make

Scons使用

scons文件和命令

二、scons文件

三、scons的命令行參數

四、SConstruct提供的方法

scons報錯記錄?


簡略說明

(摘自:https://www.cnblogs.com/m-zhang-yang/p/13228299.html)

Scons命令

scons:進行代碼文件編譯

scons -Q:進行代碼文件編譯,不顯示Scons內部操作打印的信息,只顯示編譯信息

scons -c:清除編譯中間文件和可執行文件

Scons編譯腳本

Scons對應的編譯腳本名稱為SConstruct,就如同make對應的編譯腳本為makefile

SConstruct腳本編寫

編譯函數

Program():執行編譯操作,生成可執行文件

Library():執行編譯操作,生成靜態庫

StaticLibrary():執行編譯操作,生成靜態庫

SharedLibrary():執行編譯操作,生成動態庫

Environment():編譯環境

編譯參數

target,生成的執行文件名字

source,編譯文件

LIBS,依賴庫

LIBPATH,依賴庫路徑,有環境變量的可不添加,針對用戶庫或第三方庫

CPPPATH,頭文件路徑

CCFLAGS,編譯參數

其他函數

Split():將字符串分隔為列表

Glob('*.cpp'):加入所有文件

編譯參數可以以任意順序加入編譯函數,編譯函數依據編譯參數對代碼文件進行編譯。

一個簡單例子

將文件放在當前目錄,頭文件放在上級目錄。

str = Split('main.cpp display.cpp') Program('main',str,CPPPATH = '../'i,LIBS = 'pthread')

一個復雜項目的例子

大多項目都可以套用的格式,Program內參數多個文件需要以python列表形式作為入參,這里可以用Split對文件字符串分隔為列表輸入。直接用Glob('*.cpp')包含當前目錄所有需要編譯的cpp文件。


??

TARGETNAME = 'server'LIB = Split('jsoncpp logger ACE basetool tinyxml pthread dl rt')FILELIST = Glob('*.cpp')HEADFILEPATH = Split('../../common/include ../../3rd/ACE_wrappers ../../3rd/include/')LIB_DIR = Split('../../3rd/lib ../../common/lib')Program(target = TARGETNAME,source = FILELIST,LIBS = LIB,CPPPATH = HEADFILEPATH,LIBPATH = LIB_DIR)

? ? ?src:
? ? ?| ? ?SConstruct
? ? ?| ? ?libstlport.a
? ? ?| ? ?test.cpp
? ? ?| ? ? include(目錄):
? ? ? ? ? | ? ?foo.h
? ? ?| ? ?mA(目錄):
? ? ? ? ? | ? ?SConscript
? ? ? ? ? | ? ?func.cpp

什么是Scons

make

make 工具可以增量編譯,縮短編譯的時間,但?make 規則復雜,即使老鳥也望而生畏。

Scons是它的同類產品,做的事情跟make一樣,但更簡單,更容易。


Scons

Scons是一個開源、Python編寫的自動化構建工具,并且scons是跨平臺的,只要scons腳本寫的好,可以在Linux和Windows下隨意編譯。

SCons 的設計目標就是讓開發人員更容易、更可靠和更快速的建造軟件。

遺留疑問:Scons 和cmake 對比如何?

待研究。

SCons, CMake 算是第三代構建工具的兩個代表。

第一代 DSL 型構建語言 Makefile,是描述構建的規則和依賴關系的絕對王者。

第二代 autotools(automake) 系列,幾乎是是整個 Linux 的構建工具,能完成對環境依賴項的檢測。但是不是能夠輕松駕馭的。如果用 -j 用得比較多,肯定會遇到:出現鏈接錯誤,再次運行就能正確的情形。(gn 有 link pool 的支持優雅解決了這個問題)。

SCons, CMake 算是第三代構建工具的兩個代表了。
鏈接:https://www.zhihu.com/question/276415476/answer/557715322


《構建工具之shell,configure,make,cmake,scons,xmake簡析總結》:

https://blog.csdn.net/shixin_0125/article/details/78424747

scons對比make

與傳統的 make 工具比較,SCons 具有以下優點:

?1、?移植性:python能運行的地方,就能運行scons
?2、?擴展性:理論上scons只是提供了python的類,scons使用者可以在這個類的基礎上做所有python能做的事情。比如想把一個已經使用了Makefile大型工程切換到scons,就可以保留原來的Makefile,并用python解析Makefile中的編譯選項、源/目標文件等,作為參數傳遞給scons,完成編譯。
?3、?智能:Scons繼承了autoconf/automake的功能,自動解析系統的include路徑、typedef等;“以全局的觀點來看所有的依賴關系”

  • 使用 Python 腳本做為配置文件
  • 對于 C,C++ 和 Fortran, 內建支持可靠自動依賴分析 . 不用像 make 工具那樣需要 執行"make depends"和"make clean"就可以獲得所有的依賴關系。
  • 內建支持 C, C++, D, Java, Fortran, Yacc, Lex, Qt,SWIG 以及 Tex/Latex。 用戶還可以根據自己的需要進行擴展以獲得對需要編程語言的支持。
  • 支持 make -j 風格的并行建造。相比 make -j, SCons 可以同時運行 N 個工作,而 不用擔心代碼的層次結構。
  • 使用 Autoconf 風格查找頭文件,函數庫,函數和類型定義。
  • 良好的夸平臺性。SCons 可以運行在 Linux, AIX, BSD, HP/UX, IRIX, Solaris, Windows, Mac OS X 和 OS/2 上。
    ?

Scons使用

安裝

在 SCons 的官方網站上可以查每個平臺的具體安裝方法。

Win平臺的下載和安裝就不說了。

Linux下

方法1:

pip3??install scons

方法2:

下載tar包,執行以下命令即可:

tar -zxf scons-2.0.1.tar.gz
cd scons-2.0.1?
sudo python setup.py install

對于 Linux 來說,scons 會默認安裝到 /usr/loca/bin 目錄下,而在 Windows 平臺上,則會被安裝到 C:\Python25\Scripts 下。

使用

這里通過一個簡單的示例來說明。

一個hello.c源文件,一個SConstruct文件,后面再解釋。

SConstruct

Program("hello.c")

?hello.c

#include <stdio.h>

int main(void)
{
????printf("hello, world!\n");

????return 0;
}

運行Scons,得到如下:

$ scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
gcc -o hello.o -c hello.c
gcc -o hello hello.o
scons: done building targets.

$ ls
hello ?hello.c ?hello.o ?SConstruct

$?./hello?
hello, world!

就是這樣,程序編譯完成了。到這里Scons似乎與make沒有什么兩樣,同樣的操作,只是把scons換成make,SConstruct換成Makefile。

對,不同的地方就在于,下面的展示:

$ cat? SConstruct

Program("hello.c")

你沒看錯,就這一行,編譯就完成了!!!

事實確實如此,它比傳統的 Makefile 簡單很多。SConstruct 以 Python 腳本的語法編寫,你可以像編寫 Python 腳本一樣來編寫它。

其中的 Program 是編譯的類型,說明你準備想要建造一個可執行的二進制程序,它由 hello.c 文件來生成。

在這里,沒有指定生成的可執行程序的名字,SCons 會把源代碼文件名字的后綴去掉,用來作為可執行文件的名字。

我們甚至不需要像 Makefile 那樣指定清理的動作,就可以執行清理任務。在 SCons 中,執行清理任務由參數 -c 指定,如下 :

$ scons -c


scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Cleaning targets ...
Removed hello.o
Removed hello
scons: done cleaning targets.

$ ls
hello.c ?SConstruct
?

相關命令

SCons 支持的編譯(目標文件)類型有:

  • Program: Program("hello.c")編譯成可執行程序(在 Windows 平臺上即是 exe 文件),這是最常用的一種編譯類型。
  • Object:Object("hello.c") 只編譯成目標文件。使用這種類型,編譯結束后,只會產生目標文件。在 POSIX 系統中,目標文件以 .o 結尾,在 Windows 平臺上以 .OBJ 結尾。
  • Library: Library("hello.c") 編譯成庫文件。SCons 默認編譯的庫是指靜態鏈接庫。
  • StaticLibrary: StaticLibrary("hello.c") 顯示的編譯成靜態鏈接庫,與上面的 Library 效果一樣。
  • SharedLibrary: SharedLibrary("hello.c") 在 POSIX 系統上編譯動態鏈接庫,在 Windows 平臺上編譯 DLL。

如果不想使用 SConstruct 為你設置的默認可執行文件的名字,而是選擇你自己喜歡的名字,如 myhello,可以把 SConstruct 的內容修改為 :

Program('myhello', 'helloscons.c')
?

其中 myhello就是你想要的可執行文件的名字.

$ scons? -Q
gcc -o hello.o -c hello.c
gcc -o myhello hello.o
?

Scons入門簡介(https://blog.csdn.net/guotianqing/article/details/92003258)

其中,-Q 參數是減少編譯時的由 scons 產生的冗余信息。

顯式的指定使用某些庫:

指定一些編譯的宏定義,顯式的指定使用某些庫:

例子:?helloscons2 由?3 個源文件生成 : helloscon2.c, file1.c, file2.c,指定編譯選項,同時指定使用哪些具體的庫,SConstruct 文件 如下:
?

Program('helloscons2', ['helloscons2.c', 'file1.c', 'file2.c'],?
? ? ? ?LIBS = 'm',?
? ? ? ?LIBPATH = ['/usr/lib', '/usr/local/lib'],?
? ? ? ?CCFLAGS = '-DHELLOSCONS')
?

該 SConstruct 文件指出,它將生成名叫 helloscons2 的程序,該程序由 helloscons2.c, file1.c 和 file2.c 組成。

如果源程序代碼文件很多,glob(’*.c’) 來代替源代碼列表,如下 :

Program('helloscons2', Glob('*.c'))

配置文件中 LIBS,LIBAPTH 和 CCFLAGS 是 SCons 內置的關鍵字,它們的作用如下:

LIBS: 顯示的指明要在鏈接過程中使用的庫,如果有多個庫,應該把它們放在一個列表里面。這個例子里,我們使用一個稱為 m 的庫。
LIBPATH: 鏈接庫的搜索路徑,多個搜索路徑放在一個列表中。這個例子里,庫的搜索路徑是 /usr/lib 和 /usr/local/lib。
CCFLAGS: 編譯選項,可以指定需要的任意編譯選項,如果有多個選項,應該放在一個列表中。這個例子里,編譯選項是通過 -D 這個 gcc 的選項定義了一個宏 HELLOSCONS。
CPPPATH:指定頭文件的路徑


運行 scons 命令的時候,可以看到這些變量如何被使用的,讓我們執行一下 scons 命令 :

$ scons -Q?
gcc -o file1.o -c -DHELLOSCONS file1.c?
gcc -o file2.o -c -DHELLOSCONS file2.c?
gcc -o helloscons2.o -c -DHELLOSCONS helloscons2.c?
gcc -o helloscons2 helloscons2.o file1.o file2.o -L/usr/lib -L/usr/local/lib -lm
?

?更多內容

以上只是入門,還有更多知識等待學習。

如,通過Environment指定編譯環境,env = Environment(CC = 'g++'),指定使用g++編譯程序。

示例如下:

env = Environment(CC = 'g++')
env.Program("client", "client.c", LIBS = 'm', CPPPATH = '../include', CCFLAGS = '-std=c++11')
?

摘抄自:https://blog.csdn.net/guotianqing/article/details/92003258

scons文件和命令

二、scons文件

?scons中可能出現的文件:
??????? SConstruct,Sconstruct,sconstruct,SConscript

??? scons將在當前目錄以下次序 SConstruct,Sconstruct,sconstruct 來搜索配置文件,從讀取的第一個文件中讀取相關配置。
??? 在配置文件SConstruct中可以使用函數SConscript()函數來定附屬的配置文件。按慣例,這些附屬配置文件被命名為”SConscript”,當然也可以使用任意其它名字。

三、scons的命令行參數


??? scons: 執行SConstruct中腳本
??? scons -c?? clean
??? scons -Q? 只顯示編譯信息,去除多余的打印信息
??? scons -Q?? --implicit-cache hello 保存依賴關系
?????????????????? --implicit-deps-changed?? 強制更新依賴關系
?????????????????? --implicit-deps-unchanged? 強制使用原先的依賴關系,即使已經改變

四、SConstruct提供的方法

1、Program:生成可執行文件

??? Program('hello.c')? 編譯hello.c可執行文件,根據系統自動生成(hello.exe on Windows; hello on POSIX)
??? Program('hello','hello.c') 指定Output文件名(hello.exe on Windows; hello on POSIX)
??? Program(['hello.c', 'file1.c', 'file2.c']) 編譯多個文件,Output文件名以第一個文件命名
??? Program(source = "hello.c",target = "hello")
??? Program(target = "hello" , source = "hello.c")
??? Program('hello', Split('hello.c file1.c file2.c')) 編譯多個文件

??? Program(Glob("*.c"))
??? src = ["hello.c","foo.c"];Program(src)


??
2、Object:生成目標文件

??? Object('hello.c') 編譯hello.c目標文件,根據系統自動生成(hello.obj on Windows; hello.o on POSIX)
?


3、Library:生成靜態/動態庫文件

??? Library('foo', ['f1.c', 'f2.c', 'f3.c']) 編譯library
??? SharedLibrary('foo', ['f1.c', 'f2.c', 'f3.c']) 編譯 shared library
??? StaticLibrary('bar', ['f4.c', 'f5.c', 'f6.c']) 編譯 static library

??? 庫的使用:

??? Program('prog.c', LIBS=['foo', 'bar'], LIBPATH='.') 連接庫,不需加后綴或是前綴

4、SourceSignatures:判斷源文件是否修改


??? SourceSignatures('MD5')???? 根據內容是否改變,默認方式
??? SourceSignatures('timestamp') 根據修改時間

5、TargetSignatures:判斷目標文件是否改變


????TargetSignatures('build')?? 根據編譯結果
????TargetSignatures('content')? 根據文件內容,如果只是加了句注釋,將不會被重新編譯
?

6、Ignore:忽略依賴關系

????Ignore(hello, 'hello.h')? 忽略某個依賴關系

7、Depends:明確依賴關系

Depends(hello, 'other_file') 明確依賴關系?

8、SConscript:scons的配置文件。

??? 源文件的目錄結構如下:
??? src:
????|??? SConstruct
? ??|????test.cpp
? ? |??? mA(目錄):
? ?????? |???? SConscript
? ?????? |???? func.cpp
??? 其中test.cpp為主文件,中調用func.cpp中定義的函數
??
??? SConstruct內容如下:???????

subobj?=?SConscript(['mA/SConscript'])??

obj?=?subobj?+?Object(Glob("*.cpp"))??

Program("test",list(obj))??

??
??? SConscript內容 :? ??

obj?=?Object(Glob("*.cpp"))??

Return("obj")??

????
??? 上例中,在主目錄中執行 scons就可以編譯整個"工程"。SConstruct編譯主目錄中的test.cpp,并通過SConscript編譯mA目錄下的源文件,并最終生成可執行文件;SConscript用于編譯mA中的func.cpp并把生成的func.o傳遞給主目錄的SConstruct。


10.env:環境變量
???? 環境變量用于設置在編譯過程中的各種參數,可以用下面的SConstruct打印環境變量的所有信息(實際上env就是一個python字典)
???? 可以使用如下的SConstruct查看環境變量的內容:??

env?=?Environment()??

dict?=?env.Dictionary()??

keys?=?dict.keys()??

keys.sort()??

for?key?in?keys:??

????print?"construction?variable?=?'%s',?value?=?'%s'"?%?(key,?dict[key])??

??????
???? 環境變量的使用:


? ?????? env = Environment()?? #創建默認的環境變量,默認scons會按編譯器的默認選項來進行編譯
???????? import os
???????? env = Environment(CC = 'gcc',CCFLAGS = '-O2') #創建并設置環境 變量
???????? env.Program('foo.c')

???? 環境變量的復制:


? ?????? env = Environment(CC = 'gcc')
???????? opt = env.Clone(CCFLAGS = '-O2')
???????? dbg = env.Clone(CCFLAGS = '-g')

???? 環境變量的替換:


???????? env = Environment(CCFLAGS = '-DDEFINE1')
???????? env.Replace(CCFLAGS = '-DDEFINE2')
???????? env.Program('foo.c')?


???? 環境變量的輸入輸出:用于統一多目錄源文件的編譯選項,如:


???? src:
? ?? |??? SConstruct
? ?? |??? libstlport.a
? ?? |??? test.cpp
? ?? |???? include(目錄):
? ??????? |??? foo.h
???? |??? mA(目錄):
????????? |??? SConscript
????????? |????func.cpp
???

???? test.cpp和mA/func.cpp都引用了include/foo.h,test.cpp調用了mA/func.cpp的功能函數,其中include/foo.h中定義了一個包含string類型的類。

???? SConstruct如下:? ? ??

env?=?Environment()??

flags?=?env.ParseFlags(['-pthread?-I/usr/include/stlport?','?-L?.'])??

env.MergeFlags(class_flags)??

subobj?=?SConscript(['mA/SConscript'])??

obj?=?subobj?+?env.Object(Glob("*.cpp"))??

env.Program("test",list(obj),LIBS?=?['libstlport.a'])??

??? mA/SConscrip如下:? ? ??

obj?=?Object(Glob("*.cpp"))??

Return("obj")??

??
????? 不出意外的話上邊的工程編譯可以通過,但是運行的時候會Aborted。因為test.cpp,mA/func.cpp都使用了包含string類型的那個類,但是由于編譯環境的不同,test.cpp認為string變量的大小是24字節, mA/func.cpp認為string變量的大小是4個字節(libstlport.a搗的鬼)。
?????

?????解決問題的辦法就是環境變量輸出,修改SConstruct和mA/SConscript如下:
????SConstruct:? ? ? ?

env?=?Environment()??

flags?=?env.ParseFlags(['-pthread?-I/usr/include/stlport?','?-L?.'])??

env.MergeFlags(class_flags)??

Export('env')??

subobj?=?SConscript(['mA/SConscript'],exports?=?'env')??

obj?=?subobj?+?env.Object(Glob("*.cpp"))??

env.Program("test",list(obj),LIBS?=?['libstlport.a'])??

?
????mA/SConscript:

Import('env')??

obj?=?env.Object(Glob("*.cpp"))??

Return("obj")??

scons報錯記錄?

現象:check for xxx……no

check for xxx……no,不一定是找不到xxx的錯誤,可能是生成某個庫,或者設置導致的錯誤,具體原因可以查看config.log文件:/home/ceastor/config.log

總結

以上是生活随笔為你收集整理的【c++】Scons|scons对比make的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。