2009-06-09 79 views
6

對於靜態代碼分析工具,有必要了解給定的Delphi項目的所有有效源路徑,這些路徑是在項目級別和全局IDE配置中定義的。是否有一個Delphi庫返回項目的所有有效源路徑?

是否有一個可以收集這種項目信息的Delphi庫?

據我所知,Delphi IDE的註冊表設置可以在不同的地方,以支持多種配置。但是對於IDE註冊表位置和項目文件的給定組合,應該可以收集源路徑。

編輯:另一種解決方案是使用--depends開關。這將導致dcc32.exe使用項目的所有dcu文件名(以及所有依賴項)寫入「.d」文件,其中包括路徑名。但是,文件列表包含已編譯的單元,因此它不是原始問題的正確解決方案。

+0

你想知道這個的任何特定的德爾福版本? – 2009-06-09 17:05:32

+0

德爾福2009年 - 因爲它更復雜的構建配置,甚至可以繼承,並可以包含像'$(DCC_UnitSearchPath)'這樣的宏 - 這似乎比預期更難... – mjn 2009-06-09 17:27:32

回答

8

剛剛找到另一種解決辦法:

如果我啓動RAD Studio命令提示符並運行

msbuild /t:Rebuild 
在項目目錄

,MSBuild的將顯示完整的命令行來調用dcc32,包括所有路徑設置。將生成日誌重定向到一個文件(或用一個只能捕獲參數的自制版本替換dcc32.exe)並解析輸出似乎比解析dproj文件容易得多。

另一個優點是它可以用於自動構建/持續集成。

10

您可以使用OpenTools API獲取活動項目的搜索路徑(從活動配置和選項集合並)和IDE的全局庫路徑。下面是我的快速測試設計包裝單位:

unit Unit1; 

interface 

uses 
    Windows, SysUtils, Classes, 
    ToolsAPI; 

type 
    TTestWizard = class(TNotifierObject, IOTAWizard, IOTAMenuWizard) 
    private 
    { IOTAWizard } 
    function GetIDString: string; 
    function GetName: string; 
    function GetState: TWizardState; 
    procedure Execute; 
    { IOTAMenuWizard } 
    function GetMenuText: string; 
    private 
    function AddLibraryPaths(Strings: TStrings): Integer; 
    function AddProjectSearchPaths(Strings: TStrings): Integer; 
    end; 

procedure Register; 

implementation 

uses 
    Dialogs, 
    DCCStrs, TypInfo; 

var 
    WizardIndex: Integer = -1; 

procedure GetEnvironmentVariables(Strings: TStrings); 
var 
    P: PChar; 
begin 
    P := nil; 
    Strings.BeginUpdate; 
    try 
    Strings.Clear; 
    P := GetEnvironmentStrings; 
    repeat 
     Strings.Add(P); 
     P := StrEnd(P); 
     Inc(P); 
    until P^ = #0; 
    finally 
    if Assigned(P) then 
     FreeEnvironmentStrings(P); 
    Strings.EndUpdate; 
    end; 
end; 

function EvaluateEnvironmentVariables(const S: string): string; 
var 
    Strings: TStringList; 
    I: Integer; 
begin 
    Result := S; 

    Strings := TStringList.Create; 
    try 
    GetEnvironmentVariables(Strings); 
    for I := 0 to Strings.Count - 1 do 
     Result := StringReplace(Result, Format('$(%s)', [Strings.Names[I]]), Strings.ValueFromIndex[I], 
     [rfReplaceAll, rfIgnoreCase]); 
    finally 
    Strings.Free; 
    end; 
end; 

procedure Register; 
begin 
    WizardIndex := (BorlandIDEServices as IOTAWizardServices).AddWizard(TTestWizard.Create); 
end; 

{ TTestWizard private: IOTAWizard } 

function TTestWizard.GetIDString: string; 
begin 
    Result := 'TOndrej.TestWizard'; 
end; 

function TTestWizard.GetName: string; 
begin 
    Result := 'TestWizard'; 
end; 

function TTestWizard.GetState: TWizardState; 
begin 
    Result := [wsEnabled]; 
end; 

procedure TTestWizard.Execute; 
var 
    Paths: TStrings; 
begin 
    Paths := TStringList.Create; 
    try 
    AddProjectSearchPaths(Paths); 
    AddLibraryPaths(Paths); 
    ShowMessage(EvaluateEnvironmentVariables(Paths.Text)); 
    finally 
    Paths.Free; 
    end; 
end; 

{ TTestWizard private: IOTAMenuWizard } 

function TTestWizard.GetMenuText: string; 
begin 
    Result := GetIDString; 
end; 

function TTestWizard.AddLibraryPaths(Strings: TStrings): Integer; 
var 
    Paths: TStringList; 
    EnvironmentOptions: IOTAEnvironmentOptions; 
begin 
    Paths := TStringList.Create; 
    try 
    Paths.Delimiter := ';'; 
    Paths.StrictDelimiter := True; 
    EnvironmentOptions := (BorlandIDEServices as IOTAServices).GetEnvironmentOptions; 
    Paths.DelimitedText := EnvironmentOptions.Values['LibraryPath']; 
    Strings.AddStrings(Paths); 
    Result := Paths.Count; 
    finally 
    Paths.Free; 
    end; 
end; 

function TTestWizard.AddProjectSearchPaths(Strings: TStrings): Integer; 
var 
    ActiveProject: IOTAProject; 
    Configurations: IOTAProjectOptionsConfigurations; 
    Configuration: IOTABuildConfiguration; 
    Paths: TStringList; 
begin 
    Result := -1; 
    ActiveProject := GetActiveProject; 
    if not Assigned(ActiveProject) then 
    Exit; 
    Configurations := ActiveProject.ProjectOptions as IOTAProjectOptionsConfigurations; 
    Configuration := Configurations.ActiveConfiguration; 
    if not Assigned(Configuration) then 
    Exit; 

    Paths := TStringList.Create; 
    try 
    Configuration.GetValues(sUnitSearchPath, Paths, True); 
    Strings.AddStrings(Paths); 
    Result := Paths.Count; 
    finally 
    Paths.Free; 
    end; 
end; 

initialization 

finalization 
    if WizardIndex <> -1 then 
    (BorlandIDEServices as IOTAWizardServices).RemoveWizard(WizardIndex); 

end. 
相關問題