bd7abbeb777123c40fd2f1bacba089631bc5556d
[scilab.git] / scilab / modules / dynamic_link / macros / ilib_gen_Make_unix.sci
1 // Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
2 // Copyright (C) ENPC
3 // Copyright (C) 2007-2008 - INRIA - Sylvestre LEDRU (rewrite to use autotools)
4 // Copyright (C) 2009-2010 - DIGITEO - Sylvestre LEDRU
5 //
6 // Copyright (C) 2012 - 2016 - Scilab Enterprises
7 //
8 // This file is hereby licensed under the terms of the GNU GPL v2.0,
9 // pursuant to article 5.3.4 of the CeCILL v.2.1.
10 // This file was originally licensed under the terms of the CeCILL v2.1,
11 // and continues to be available under such terms.
12 // For more information, see the COPYING file which you should have received
13 // along with this program.
14
15 //=============================================================================
16 // Generate a Makefile which can be used by ilib_*
17 //=============================================================================
18
19 function ilib_gen_Make_unix(names,   ..
20     files,   ..
21     libs,    ..
22     libname, ..
23     ldflags, ..
24     cflags,  ..
25     fflags,  ..
26     cc,      ..
27     tables   ..
28     )
29
30     if getos() == "Windows" then
31         return
32     end
33
34     if libname == "" then libname = names(1);end
35
36     if ( strncpy(libname,3) == "lib") then
37         l       = strsplit(libname,3);
38         libname = l(2);
39         clear l;
40     end
41
42     if isdef("tables") then
43
44         /// Check tables ... the second element should be the file name
45         if typeof(tables)<>"list" then
46             tables=list(tables)
47         end
48         L=length(tables);
49
50         // for each element in tables
51         for it=1:L
52             table = tables(it)
53             [mt,nt]=size(table);
54             for i=1:mt ;
55                 // mex files to be added to the build process
56                 if table(i,3)=="cmex" | table(i,3)=="fmex" | table(i,3)=="Fmex" then
57                     if isempty(find(basename(files)==table(i,2))) then // If not already in the array
58                         files=[files, table(i,2)] // add it to the file list
59                     end
60                 end
61             end
62         end
63
64     end // isdef('tables')
65
66
67     originPath  = pwd();
68     linkBuildDir    = TMPDIR+"/"+libname;
69     mkdir(linkBuildDir);
70     commandpath = SCI+"/modules/dynamic_link/src/scripts";
71     usercommandpath = SCIHOME+"/modules/dynamic_link/src/scripts";
72
73     // generate the stuff into the user directory in order to avoid the configure each time.
74      if isdir(usercommandpath) == %F then
75         mkdir(usercommandpath);
76         copyMandatoryFiles(commandpath,usercommandpath);
77         generateConfigure(usercommandpath);
78     end
79
80     // Copy files => linkBuildDir
81     chdir(linkBuildDir);
82
83     if ( ilib_verbose() <> 0 ) then
84         mprintf(gettext("   %s: Copy compilation files (Makefile*, libtool...) to TMPDIR\n"),"ilib_gen_Make");
85     end
86
87     copyMandatoryFiles(usercommandpath,linkBuildDir);
88
89     filelist = "";
90
91     for x = files(:)' ;
92         // Pre added file in the list ... don't really know why
93
94         if (x <> "csci") then
95             // Old way: to compile a fun.c file, the user had to provide fun.o
96             filename = strsubst(x,".o","");
97
98             chdir(originPath); // Switch back to the source dir in order to have only the filename
99             filesMatching = ls(filename+".*");
100
101             // Two cases here:
102             // * The user provided the real filename. Then, take if straight
103             // * The user provided a file ending by .o (example: myfile.o)
104             // We stripped the ending .o and looked for all files
105             if filesMatching == [] | fileinfo(x) <> [] then
106
107                 [pathFrom, file_name, file_extension]=fileparts(x); // Retrieve the path of the file
108                 if length(pathFrom) == 0 then // Empty => it should be PWD
109                     pathFrom=pwd();
110                 end
111
112                 if pathFrom <> linkBuildDir then
113                     if ( ilib_verbose() <> 0 ) then
114                         mprintf(gettext("   %s: Copy %s to TMPDIR\n"),"ilib_gen_Make",x);
115                     end
116                     copyfile(x, linkBuildDir);
117                 else
118                     if ( ilib_verbose() <> 0 ) then
119                         mprintf(gettext("   %s: Did not copy %s: Source and target directories are the same (%s).\n"),"ilib_gen_Make",x,pathFrom);
120                     end
121                 end
122
123                 if ~isfile(pathFrom + "/" + file_name + file_extension) then
124                     error(msprintf(_("%s: Wrong value for input argument #%d: existing file(s) expected. Provided: %s\n"), "ilib_gen_Make_unix", 2, pathFrom + "/" + file_name + file_extension));
125                 end
126
127                 filelist = filelist + " " + file_name + file_extension;
128
129             else
130
131                 // Or copy the file matching to what we were looking for
132                 // (this stuff could lead to bug if you have fun.c fun.f
133                 // or fun.cxx but it was already the case before ...
134
135                 // Not that we don't want to copy working files
136                 ignoredFileExtension=[".lo",".la",".lai"]
137                 for f=filesMatching(:)'
138
139                     if ~isfile(f) then
140                         error(msprintf(_("%s: Wrong value for input argument #%d: existing file(s) expected.\n"), "ilib_gen_Make_unix", 2));
141                     end
142
143                     if strindex(f,ignoredFileExtension) == [] then
144                         if ( ilib_verbose() <> 0 ) then
145                             mprintf(gettext("   %s: Copy %s to TMPDIR\n"),"ilib_gen_Make",f);
146                         end
147
148                         copyfile(f, linkBuildDir);
149                         filelist = filelist + " " + f;
150                     else
151                         if ( ilib_verbose() <> 0 ) then
152                             mprintf(gettext("   %s: File %s ignored.\n"),"ilib_gen_Make",f);
153                         end
154                     end
155                 end
156             end
157             chdir(linkBuildDir);
158         end
159     end
160
161     if ldflags <> "" | cflags <> "" | fflags <> "" | cc <> "" | fileinfo(usercommandpath+"/Makefile.orig") == [] | fileinfo(usercommandpath+"/libtool") == [] then
162         // Makefile.orig doesn't exists or may be invalid regarding the flags
163         // run the ./configure with the flags
164
165         if ( ilib_verbose() == 2 ) then
166             mprintf(gettext("   %s: Need to run the compiler detection (configure).\n"),"ilib_gen_Make");
167         end
168
169         mdelete(linkBuildDir+"/Makefile.orig");
170         generateConfigure(linkBuildDir, ldflags, cflags, fflags, cc)
171     else
172         // Reuse existing Makefile.orig because compilation flags are all empty
173         [status,msg]=copyfile(usercommandpath+"/Makefile.orig",linkBuildDir);
174
175         if ( ilib_verbose() == 2 ) then
176             mprintf(gettext("   %s: Use the previous detection of compiler.\n"),"ilib_gen_Make");
177         end
178
179         if (status <> 1)
180             error(msprintf(gettext("%s: An error occurred: %s\n"), "ilib_gen_Make",msg));
181         end
182
183         // We just copied the configure script, so its modification time is "now".
184         // But Makefile timestamp is also "now", since we just created it. Since
185         // Makefile depends on configure, "make" re-run the configure script, and
186         // hence rebuild Makefile from Makefile.in, overwriting the result of
187         // scicompile.sh. We want to avoid this, so we have to force Makefile's
188         // timestamp to one second later.
189         // (just try "touch configure Makefile; make" on any autoconf project)
190         sleep(1000);
191         unix_g("touch Makefile");
192     end
193
194     // Alter the Makefile in order to compile the right files
195     if ( ilib_verbose() <> 0 ) then
196         mprintf(gettext("   %s: Modification of the Makefile in TMPDIR.\n"),"ilib_gen_Make");
197     end
198
199     cmd=commandpath + "/scicompile.sh " + libname + " " + filelist
200
201     [msg,ierr, stderr] = unix_g(cmd);
202
203     if ( ilib_verbose() == 2 ) then
204         mprintf(gettext("   %s: Substitute the reference by the actual file.\n"),"ilib_gen_Make");
205         mprintf(gettext("   Command: %s\n"),cmd);
206         if (length(msg)) then
207             mprintf(gettext("Output: %s\n"),msg);
208         end
209         mprintf(gettext("stderr: %s\n"),stderr);
210     end
211
212     if ierr <> 0 then
213         if ( ilib_verbose() <> 0 ) then
214             mprintf(gettext("%s: Error while modifying the reference Makefile:\n"),"ilib_gen_Make")
215             mprintf(msg + " " + stderr);
216         end
217         return;
218     end
219
220     chdir(originPath);
221
222 endfunction
223
224
225 function generateConfigure(workingPath, ..
226     ldflags, ..
227     cflags, ..
228     fflags, ..
229     cc)
230
231     // We launch ./configure in order to produce a "generic" Makefile
232     // for this computer
233
234     if ( ilib_verbose() <> 0 ) then
235         mprintf(gettext("   %s: configure : Generate Makefile.\n"),"ilib_gen_Make");
236     end
237     cmd = gencompilationflags_unix(ldflags, cflags, fflags, cc, "configure")
238     cmd = workingPath+"/compilerDetection.sh "+cmd
239
240     [msg,ierr,stderr] = unix_g(cmd);
241
242     if ( ilib_verbose() == 2 ) then
243         mprintf(gettext("   %s: Command: %s\n"),"ilib_gen_Make",cmd);
244         mprintf(gettext("   Output: %s\n"),msg);
245         mprintf(gettext("   stderr: %s\n"),stderr);
246     end
247
248     if ierr <> 0 then
249         if ( ilib_verbose() <> 0 ) then
250             mprintf("%s\n", msg + " " + stderr);
251         end
252         error(msprintf(gettext("%s: An error occurred during the detection of the compiler(s). Set ilib_verbose(2) for more information.\n"), "ilib_gen_Make"));
253         return;
254     end
255
256 endfunction
257
258 function copyMandatoryFiles(commandpath,workingPath)
259     // List of the files mandatory to generate a lib with the detection of the env
260     mandatoryFiles = ["compilerDetection.sh", ..
261     "configure.ac", ..
262     "configure", ..
263     "Makefile.am", ..
264     "Makefile.in", ..
265     "config.sub", ..
266     "libtool", ..
267     "config.guess", ..
268     "config.status", ..
269     "depcomp", ..
270     "install-sh", ..
271     "ltmain.sh", ..
272     "missing", ..
273     "aclocal.m4"];
274
275     // Copy files to the working path
276     for x = mandatoryFiles(:)' ;
277         fullPath=commandpath+"/"+x;
278         if (isfile(fullPath)) then
279             [status,msg]=copyfile(fullPath,workingPath);
280             if (status <> 1)
281                 error(msprintf(gettext("%s: An error occurred: %s\n"), "ilib_gen_Make",msg));
282             end
283         end
284     end
285
286 endfunction
287 //=============================================================================