-
Notifications
You must be signed in to change notification settings - Fork 4
/
m_crossinstaller.pas
executable file
·186 lines (166 loc) · 9.07 KB
/
m_crossinstaller.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
unit m_crossinstaller;
{ General crossinstaller/updater module
Copyright (C) 2012-2013 Reinier Olislagers, Ludo Brands
This library is free software; you can redistribute it and/or modify it
under the terms of the GNU Library General Public License as published by
the Free Software Foundation; either version 2 of the License, or (at your
option) any later version with the following modification:
As a special exception, the copyright holders of this library give you
permission to link this library with independent modules to produce an
executable, regardless of the license terms of these independent modules,and
to copy and distribute the resulting executable under terms of your choice,
provided that you also meet, for each linked independent module, the terms
and conditions of the license of that module. An independent module is a
module which is not derived from or based on this library. If you modify
this library, you may extend this exception to your version of the library,
but you are not obligated to do so. If you do not wish to do so, delete this
exception statement from your version.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
for more details.
You should have received a copy of the GNU Library General Public License
along with this library; if not, write to the Free Software Foundation,
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
}
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils,fpcuputil;
type
CompilerType=(ctBootstrap,ctInstalled);
{ TCrossInstaller }
TCrossInstaller = class(TObject)
protected
FBinUtilsPath: string; //the cross compile binutils (as, ld etc). Could be the same as regular path if a binutils prefix is used.
FBinutilsPathInPath: boolean;
FBinUtilsPrefix: string; //can be empty, if a prefix is used to separate binutils for different archs in the same directory, use it
FCompilerUsed: CompilerType;
FCrossModuleName: string; //used for identifying module to user in messages
FCrossOpts: TStringList; //Options to be added to CROSSOPT by the calling code. XP= (binutils prefix) is already done, no need to add it
FFPCCFGSnippet: string; //snippet to be added to fpc.cfg in order to find binutils/libraries etc
FLibsPath: string; //path for target environment libraries
FTargetCPU: string; //cpu for the target environment. Follows FPC names
FTargetOS: string; //operating system for the target environment. Follows FPC names
// Sets FBinutilspath if file LookFor found in Directory. Returns true if found.
function SearchBinUtil(Directory, LookFor: string): boolean;
public
// In your descendent, implement this function: you can download libraries or check for their existence for normal cross compile libs:
function GetLibs(Basepath:string):boolean;virtual; abstract;
// In your descendent, implement this function: you can download libraries or check for their existence for Lazarus LCL cross compile libs:
// Note: the libraries should be presumably under the basepath using the Lazarus naming convention??
function GetLibsLCL(LCL_Platform:string; Basepath:string):boolean;virtual; abstract;
// In your descendent, implement this function: you can download cross compile binutils or check for their existence
function GetBinUtils(Basepath:string):boolean;virtual;
// Parses space-delimited crossopt parameters and sets the CrossOpt property
procedure SetCrossOpt(CrossOpts: string);
// Which compiler should be used for cross compilation.
// Normally the bootstrap compiler, but cross compilers may need the installed compiler
// (often a trunk version, though there's no tests yet that check trunk is installed)
property CompilerUsed: CompilerType read FCompilerUsed;
// Represents arguments for CROSSOPT parameter
// No need to add XP= (binutils prefix): calling code will do this
// CROSSOPT: Compiler makefile allows to specify compiler options that are only used during the actual crosscompiling phase (i.e. not during the initial bootstrap cycle)
// Also used in fpc.cfg snippet to set options when compiling for cross target
property CrossOpt: TStringList read FCrossOpts;
// Conditional define snippet for fpc.cfg used to specify library locations etc
// Can be empty
// Does not include the #IFDEF CPU<x> and #ENDIF parts where the target cpu is filled in
property FPCCFGSnippet: string read FFPCCFGSnippet;
// Path where libraries used for target systems are. May be empty if not needed.
property LibsPath:string read FLibsPath;
// Path where binutils used for target systems are. May be empty if not used.
property BinUtilsPath:string read FBinUtilsPath;
// Indicates if binutils directory is used as the last entry in PATH when cross compiling.
// Can be useful if make scripts forget to include the complete path to the binutils path
// (e.g. some versions of the DOS crosscompiler)
property BinUtilsPathInPath: boolean read FBinutilsPathInPath;
// Prefix used before executable names for binutils (e.g. before as.exe). May be empty.
property BinUtilsPrefix:string read FBinUtilsPrefix;
// Target processor (in FPC notation). Used to select cross compiler
property TargetCPU:string read FTargetCPU;
// Target Operating System (in FPC notation). Used to select cross compiler
property TargetOS:string read FTargetOS;
constructor Create;
destructor Destroy; override;
end;
Procedure
RegisterExtension(Platform:string;Extension:TCrossInstaller);
Var
CrossInstallers:TStringList=nil;
implementation
{ TCrossInstaller }
procedure RegisterExtension(Platform:string;Extension:TCrossInstaller);
begin
if not assigned(CrossInstallers) then
CrossInstallers:=TStringList.Create;
CrossInstallers.AddObject(Platform,TObject(Extension));
end;
function TCrossInstaller.SearchBinUtil(Directory, LookFor: string): boolean;
begin
FBinUtilsPath:=ExcludeTrailingPathDelimiter(SafeExpandFileName(Directory));
result:=FileExists(IncludeTrailingPathDelimiter(FBinUtilsPath)+LookFor);
// Report results to user. SearchBinUtil will probably only be called until
// its result is true; if it's called more times, it still ok to keep the
// user informed about succesful searches.
if result then
infoln(FCrossModuleName + ': found binutil '+LookFor+
' in directory '+FBinUtilsPath, etInfo)
else
infoln(FCrossModuleName + ': searched but did not find binutil '+LookFor+
' in directory '+FBinUtilsPath, etInfo);
end;
function TCrossInstaller.GetBinUtils(Basepath: string): boolean;
var
i:integer;
begin
// Add user-selected CROSSOPT to fpc.cfg snippet
// Descendents can add more fpc.cfg snippets but shouldn't remove what the user chose
for i:=0 to FCrossOpts.Count-1 do
begin
if i<FCrossOpts.Count-1 then
FFPCCFGSnippet:=FFPCCFGSnippet+FCrossOpts[i]+LineEnding
else
FFPCCFGSnippet:=FFPCCFGSnippet+FCrossOpts[i];
end;
end;
procedure TCrossInstaller.SetCrossOpt(CrossOpts: string);
// A bit rough-and-ready but hopefully there won't be too many quoting etc problems
var
Parser: TStringList;
begin
Parser:=TStringList.Create;
try
Parser.Delimiter:=' ';
Parser.QuoteChar:=''''; //single '. Assume entire CROSSOPT argument is surround by double quotes; indifividual parameters by single.
Parser.StrictDelimiter:=false; //ignore quoting characters
Parser.DelimitedText:=CrossOpts;
FCrossOpts.Clear;
FCrossOpts.AddStrings(Parser);
finally
Parser.Free;
end;
end;
constructor TCrossInstaller.Create;
begin
// Help ensure our implementers do the right thing with the variables
// in their extensions
FCompilerUsed:=ctBootstrap; //use bootstrap compiler for cross compiling by default
FBinUtilsPath:='Error: cross compiler extension must set FBinUtilsPath: the cross compile binutils (as, ld etc). Could be the same as regular path if a binutils prefix is used.';
FBinutilsPathInPath:=false; //don't add binutils directory to path when cross compiling
FBinUtilsPrefix:='Error: cross compiler extension must set FBinUtilsPrefix: can be empty, if a prefix is used to separate binutils for different archs in the same directory, use it';
FCrossOpts:=TStringList.Create;
FFPCCFGSnippet:='Error: cross compiler extension must set FFPCCFGSnippet: this can be quite short but must exist';
FLibsPath:='Error: cross compiler extension must set FLibsPath: path for target environment libraries';
FTargetCPU:='Error: cross compiler extension must set FTargetCPU: cpu for the target environment. Follows FPC names.';
FTargetOS:='Error: cross compiler extension must set FTargetOS: operating system for the target environment. Follows FPC names';
end;
destructor TCrossInstaller.Destroy;
begin
FCrossOpts.Free;
inherited Destroy;
end;
finalization
if assigned(CrossInstallers) then
CrossInstallers.Destroy;
end.