2009-06-09 5 views
6

Для статических инструментов анализа кода необходимо знать все эффективные пути источника для данного проекта Delphi, которые определены на уровне проекта и в глобальной конфигурации IDE.Есть ли библиотека Delphi, которая возвращает все эффективные исходные пути для проекта?

Есть ли библиотека Delphi, которая может собирать эту информацию о проекте?

Насколько я знаю, параметры реестра для Delphi IDE могут быть в разных местах, чтобы поддерживать несколько конфигураций. Но для данной комбинации местоположения реестра IDE и файла проекта должно быть возможно собрать исходные пути.

Редактировать: Другое решение - использовать переключатель --depends. Это заставит dcc32.exe записать файл «.d» со всеми именами файлов dcu проекта (и всех зависимостей), включая имена путей. Однако список файлов включает в себя юниты, которые уже скомпилированы, поэтому это неправильное решение для исходной проблемы.

+0

Любая конкретная версия Delphi, для которой вы хотите это знать? –

+0

Delphi 2009 - потому что это намного сложнее с конфигурациями сборки, которые могут даже наследоваться, и могут содержать макросы типа «$ (DCC_UnitSearchPath)» - это кажется сложнее, чем ожидалось ... – mjn

ответ

8

Просто нашел другое решение:

если запустить командную строку RAD Studio и запустить

msbuild /t:Rebuild 

в каталоге проекта, MSBuild покажет полную командную строку для вызова dcc32, включая все настройки пути. Перенаправление журнала сборки в файл (или замена dcc32.exe на собственную версию, которая только фиксирует параметры), и синтаксический анализ вывода кажется намного проще, чем для анализа файлов dproj.

Другим преимуществом является то, что он может использоваться в автоматических сборках/непрерывной интеграции.

10

API OpenTools можно использовать для получения пути поиска активного проекта (объединенного от активной конфигурации и набора параметров) и глобального пути библиотеки 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. 
+0

Это выглядит очень многообещающе, спасибо вам большое много! Я более подробно рассмотрю ОТА. Легко получить список исходных файлов проекта (все файлы, которые были добавлены явно в DPR)? Я также посмотрю на источники GExpert/cnWizard. – mjn

+0

Да, с OTA вы можете перечислить модули проекта. Посмотрите интерфейс IOTAProject. В частности, методы IOTAProject40 GetModuleCount, GetModule. –

Смежные вопросы