Есть ли библиотека Delphi, которая возвращает все действующие исходные пути для проекта?

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

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

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

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


person mjn    schedule 09.06.2009    source источник
comment
Для какой конкретной версии Delphi вы хотите это узнать?   -  person Lars Truijens    schedule 09.06.2009
comment
Delphi 2009 - потому что он намного сложнее с конфигурациями сборки, которые можно даже унаследовать и могут содержать макросы, такие как '$ (DCC_UnitSearchPath)' - это кажется сложнее, чем ожидалось ...   -  person mjn    schedule 09.06.2009


Ответы (2)


Вы можете использовать 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.
person Ondrej Kelle    schedule 09.06.2009
comment
Выглядит многообещающе, большое вам спасибо! Взгляну на ОТА повнимательнее. Легко ли получить список исходных файлов проекта (всех файлов, которые были явно добавлены в DPR)? Я также посмотрю на исходники GExpert / cnWizard. - person mjn; 10.06.2009
comment
Да, с помощью OTA вы можете перечислять модули проекта. Взгляните на интерфейс IOTAProject. В частности, IOTAProject40 методы GetModuleCount, GetModule. - person Ondrej Kelle; 10.06.2009

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

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

msbuild /t:Rebuild

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

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

person mjn    schedule 11.06.2009