當前位置:首頁 » 編程軟體 » 編譯系統自動生成函數條件

編譯系統自動生成函數條件

發布時間: 2025-03-05 22:45:20

1. 請教Scons python 編譯問題

一、概述

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

二、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內容如下:

[cpp]view plain

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

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

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


  • SConscript內容 :

  • [cpp]view plain

  • 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查看環境變數的內容:

    [cpp]view plain

  • env=Environment()

  • dict=env.Dictionary()

  • keys=dict.keys()

  • keys.sort()

  • forkeyinkeys:

  • print"constructionvariable='%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如下:

    [cpp]view plain

  • 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如下:

    [cpp]view plain

  • 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:

    [cpp]view plain

  • 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:

2. 編譯程序與什麼有關

編譯程序與編程語言、編譯器設計、計算機系統結構、操作系統以及計算機性能等多個方面有關。

首先,編譯程序與編程語言密切相關。編譯器是將高級編程語言編寫的源代碼轉換為機器語言或低級語言的工具,因此不同的編程語言需要不同的編譯器。例如,C語言編譯器將C語言源代碼轉換為機器語言,而Java編譯器將Java源代碼轉換為位元組碼。

其次,編譯程序的設計和實現需要考慮計算機系統結構。不同的計算機體系結構有不同的指令集和寄存器集,因此編譯器需要生成與特定體系結構兼容的機器代碼。例如,x86架構的計算機使用不同的指令集和寄存器集,與ARM架構的計算機不同,因此針對這兩種架構的編譯器會生成不同的機器代碼。

此外,編譯程序還與操作系統密切相關。操作系統提供了許多系統調用和庫函數,編譯器需要將這些調用和函數與生成的機器代碼鏈接起來,以便程序能夠在特定的操作系統上運行。例如,Windows操作系統和Linux操作系統提供了不同的系統調用和庫函數,因此針對這兩個操作系統的編譯器會生成不同的鏈接代碼。

最後,編譯程序還與計算機性能有關。編譯器可以優化生成的機器代碼,以提高程序的運行效率。例如,編譯器可以使用不同的演算法和技術來優化循環、減少內存訪問、提高並行性等等。這些優化可以提高程序的性能,但也可能增加編譯時間和生成的代碼大小。

綜上所述,編譯程序與編程語言、編譯器設計、計算機系統結構、操作系統以及計算機性能等多個方面有關。編譯器是將高級編程語言轉換為機器語言的重要工具,它的設計和實現需要考慮多個因素,包括語言特性、系統結構、操作系統和性能要求等等。

3. 析構函數的作用是什麼

析構函數的作用是什麼如下:

(3)編譯系統自動生成函數條件擴展閱讀:

函數介紹

與構造函數相反,當對象結束其生命周期,如對象所在的函數已調用完畢時,系統會自動執行析構函數。以C++語言為例:析構函數名也應與類名相同,只是在函數名前面加一個位取反符,例如~stud( ),以區別於構造函數。它不能帶任何參數,也沒有返回值(包括void類型)。

只能有一個析構函數,不能重載。如果用戶沒有編寫析構函數,編譯系統會自動生成一個預設的析構函數(即使自定義了析構函數,編譯器也總是會為我們合成一個析構函數。

熱點內容
電腦進手機伺服器我的世界 發布:2025-03-06 09:30:08 瀏覽:829
伺服器如何通過域名訪問不同埠 發布:2025-03-06 09:30:06 瀏覽:592
netty項目源碼 發布:2025-03-06 09:29:13 瀏覽:647
file命令linux 發布:2025-03-06 09:28:34 瀏覽:882
安卓手機怎麼寫帶框的數字 發布:2025-03-06 09:11:09 瀏覽:326
登錄遠程linux伺服器 發布:2025-03-06 09:07:28 瀏覽:94
抖管家源碼 發布:2025-03-06 09:05:49 瀏覽:656
明日之後安卓如何跟蘋果賬號玩 發布:2025-03-06 08:56:04 瀏覽:438
豆瓣伺服器為什麼經常卡死 發布:2025-03-06 08:47:32 瀏覽:808
安卓基岩版我的世界如何啟用連鎖 發布:2025-03-06 08:46:20 瀏覽:459