root/trunk/sss/install.d

Revision 925, 8.9 kB (checked in by Gregor, 3 months ago)

sss/*: Much less verbose by default.

Line 
1 /**
2  * DSSS command "install"
3  *
4  * Authors:
5  *  Gregor Richards
6  *
7  * License:
8  *  Copyright (c) 2006, 2007  Gregor Richards
9  * 
10  *  Permission is hereby granted, free of charge, to any person obtaining a
11  *  copy of this software and associated documentation files (the "Software"),
12  *  to deal in the Software without restriction, including without limitation
13  *  the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  *  and/or sell copies of the Software, and to permit persons to whom the
15  *  Software is furnished to do so, subject to the following conditions:
16  * 
17  *  The above copyright notice and this permission notice shall be included in
18  *  all copies or substantial portions of the Software.
19  * 
20  *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21  *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23  *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  *  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  *  DEALINGS IN THE SOFTWARE.
27  */
28
29 module sss.install;
30
31 import std.file;
32 import std.stdio;
33 import std.string;
34
35 import hcf.path;
36 import hcf.process;
37
38 import sss.conf;
39 import sss.system;
40
41 /** Entry into the "install" command */
42 int install(char[][] buildElems, DSSSConf conf = null, char[] pname = null, char[][]* subManifest = null)
43 {
44     // get the configuration
45     if (conf is null)
46         conf = readConfig(buildElems);
47    
48     // get the corresponding sources
49     char[][] buildSources = sourcesByElems(buildElems, conf);
50    
51     // prepare to make a manifest
52     if (pname.length == 0) {
53         pname = conf.settings[""]["name"].dup;
54     }
55     char[][] manifest;
56     char[] manifestFile;
57     manifestFile = manifestPrefix ~ std.path.sep ~ conf.settings[""]["name"] ~ ".manifest";
58     manifest ~= "share" ~ std.path.sep ~ "dsss" ~ std.path.sep ~ "manifest" ~ std.path.sep ~
59         pname ~ ".manifest";
60    
61     /// Copy in the file and add it to the manifest
62     void copyAndManifest(char[] file, char[] prefix, char[] from = "")
63     {
64         copyInFile(file, prefix, from);
65        
66         // if the prefix starts with the installation prefix, strip it
67         if (prefix.length > forcePrefix.length &&
68             prefix[0..forcePrefix.length] == forcePrefix)
69             prefix = prefix[forcePrefix.length + 1 .. $];
70        
71         manifest ~= prefix ~ std.path.sep ~ file;
72     }
73    
74     // now install the requested things
75     foreach (build; buildSources) {
76         char[][char[]] settings = conf.settings[build];
77        
78         // basic info
79         char[] type = settings["type"];
80         char[] target = settings["target"];
81
82         // maybe we shouldn't install it
83         if ("noinstall" in settings)
84             continue;
85        
86         // say what we're doing
87         writefln("Installing %s", target);
88        
89         // do preinstall
90         if ("preinstall" in settings) {
91             manifest ~= dsssScriptedStep(conf, settings["preinstall"]);
92         }
93        
94         // figure out what it is
95         if (type == "library" && libsSafe()) {
96             // far more complicated
97             char[][] srcFiles = targetToFiles(build, conf, true);
98             if (srcFiles.length == 0) {
99                 // warning is in sss.build
100                 continue;
101             }
102            
103             // 1) copy in library files
104             if (targetGNUOrPosix()) {
105                 // copy in the .a and .so/.dll files
106                
107                 // 1) .a
108                 copyAndManifest("lib" ~ target ~ ".a", libPrefix);
109
110                 // and perhaps the debug version as well
111                 if (buildDebug)
112                     copyAndManifest("libdebug-" ~ target ~ ".a", libPrefix);
113                
114                 char[] shlibname = getShLibName(settings);
115                
116                 if (shLibSupport() &&
117                     ("shared" in settings)) {
118                     if (targetVersion("Posix")) {
119                         // 2) .so
120                         char[][] shortshlibnames = getShortShLibNames(settings);
121                
122                         // copy in
123                         copyAndManifest(shlibname, libPrefix);
124                
125                         // make softlinks
126                         foreach (ssln; shortshlibnames) {
127                             // make it
128                             vSaySystemDie("ln -sf " ~ shlibname ~ " " ~
129                                          libPrefix ~ std.path.sep ~ ssln);
130                             manifest ~= libPrefix ~ std.path.sep ~ ssln;
131                         }
132                     } else if (targetVersion("Windows")) {
133                         // 2) .dll
134                         copyAndManifest(shlibname, libPrefix);
135                     } else {
136                         assert(0);
137                     }
138                 }
139             } else if (targetVersion("Windows")) {
140                 // copy in the .lib and .dll files
141                
142                 // 1) .lib
143                 copyAndManifest(target ~ ".lib", libPrefix);
144                
145                 char[] shlibname = getShLibName(settings);
146                
147                 if (shLibSupport() &&
148                     ("shared" in settings)) {
149                     // 2) .dll
150                     copyAndManifest(shlibname, libPrefix);
151                 }
152             } else {
153                 assert(0);
154             }
155            
156             // 2) install generated .di files
157             foreach (file; srcFiles) {
158                 // if it's already a .di file, this is simpler
159                 if (std.string.tolower(getExt(file)) == "di") {
160                     copyAndManifest(getBaseName(file),
161                                     includePrefix ~ std.path.sep ~ getDirName(file),
162                                     getDirName(file) ~ std.path.sep);
163
164                 } else {
165                     // install the generated .di file
166                     copyAndManifest(getBaseName(file ~ "i"),
167                                     includePrefix ~ std.path.sep ~ getDirName(file),
168                                     "dsss_imports" ~ std.path.sep ~ getDirName(file) ~ std.path.sep);
169                 }
170             }
171            
172         } else if (type == "binary") {
173             // fairly easy
174             if (targetVersion("Posix")) {
175                 copyAndManifest(target, binPrefix);
176             } else if (targetVersion("Windows")) {
177                 copyAndManifest(target ~ ".exe", binPrefix);
178             } else {
179                 assert(0);
180             }
181            
182         } else if (type == "sourcelibrary" ||
183                    (type == "library" && !libsSafe())) {
184             // also fairly easy
185             char[][] srcFiles = targetToFiles(build, conf, true);
186             foreach (file; srcFiles) {
187                 char[] fdir = getDirName(file);
188                 char[] pdir = fdir.dup;
189                 if (fdir != "") fdir ~= std.path.sep;
190                 if (pdir != "") pdir = std.path.sep ~ pdir;
191                
192                 copyAndManifest(getBaseName(file),
193                                 includePrefix ~ pdir,
194                                 fdir);
195             }
196            
197         } else if (type == "subdir") {
198             // recurse
199             char[] origcwd = getcwd();
200             chdir(build);
201             int installret = install(null, null, pname, &manifest);
202             if (installret) return installret;
203             chdir(origcwd);
204         }
205        
206         // do postinstall
207         if ("postinstall" in settings) {
208             manifest ~= dsssScriptedStep(conf, settings["postinstall"]);
209         }
210        
211         // install the manifest itself
212         if (subManifest) {
213             (*subManifest) ~= manifest;
214         } else {
215             mkdirP(manifestPrefix);
216             std.file.write(manifestFile, std.string.join(manifest, "\n") ~ "\n");
217         }
218        
219         // extra line for clarity
220         writefln("");
221     }
222    
223     // then install documentation
224     if (doDocs && exists("dsss_docs")) {
225         writefln("Installing documentation...");
226        
227         char[] docs = docPrefix ~ std.path.sep ~ pname;
228         mkdirP(docs);
229        
230         chdir("dsss_docs");
231        
232         // copy in everything
233         void copyDir(char[] cdir)
234         {
235             char[] subdocs = docs ~ std.path.sep ~ cdir;
236             mkdirP(subdocs);
237            
238             foreach (file; listdir(cdir)) {
239                 char[] full = cdir ~ std.path.sep ~ file;
240                 if (isdir(full)) {
241                     copyDir(full);
242                 } else {
243                     copyInFile(file, subdocs, cdir ~ std.path.sep);
244                 }
245             }
246         }
247        
248         foreach (file; listdir(".")) {
249             if (isdir(file)) {
250                 copyDir(file);
251             } else {
252                 copyInFile(file, docs);
253             }
254         }
255        
256         chdir("..");
257     }
258    
259     return 0;
260 }
Note: See TracBrowser for help on using the browser.