Merge remote-tracking branch 'origin/6.1'
[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     stringToHash =  strcat([libname,ldflags,cflags,fflags,cc])
162
163     hash = getmd5(stringToHash,"string");
164     md5file = fullfile(usercommandpath,libname+".md5");
165     if stringToHash == libname || (isfile(md5file) && ...
166         mgetl(md5file) == hash && ...
167         isfile(usercommandpath+"/Makefile.orig") && ...
168         isfile(usercommandpath+"/libtool"))
169         // Reuse existing Makefile.orig because compilation flags are all empty or unchanged since last call
170         [status,msg]=copyfile(usercommandpath+"/Makefile.orig",linkBuildDir);
171
172         if ( ilib_verbose() == 2 ) then
173             mprintf(gettext("   %s: Use the previous detection of compiler.\n"),"ilib_gen_Make");
174         end
175
176         if (status <> 1)
177             error(msprintf(gettext("%s: An error occurred: %s\n"), "ilib_gen_Make",msg));
178         end
179
180         // We just copied the configure script, so its modification time is "now".
181         // But Makefile timestamp is also "now", since we just created it. Since
182         // Makefile depends on configure, "make" re-run the configure script, and
183         // hence rebuild Makefile from Makefile.in, overwriting the result of
184         // scicompile.sh. We want to avoid this, so we have to force Makefile's
185         // timestamp to one second later.
186         // (just try "touch configure Makefile; make" on any autoconf project)
187         sleep(1000);
188         unix_g("touch Makefile");
189     else
190         // Makefile.orig doesn't exists or may be invalid regarding the flags
191         // run the ./configure with the flags
192
193         mputl(hash,md5file)
194
195         if ( ilib_verbose() == 2 ) then
196             mprintf(gettext("   %s: Need to run the compiler detection (configure).\n"),"ilib_gen_Make");
197         end
198
199         mdelete(linkBuildDir+"/Makefile.orig");
200         generateConfigure(linkBuildDir, ldflags, cflags, fflags, cc)
201     end
202
203     // Alter the Makefile in order to compile the right files
204     if ( ilib_verbose() <> 0 ) then
205         mprintf(gettext("   %s: Modification of the Makefile in TMPDIR.\n"),"ilib_gen_Make");
206     end
207
208     cmd=commandpath + "/scicompile.sh " + libname + " " + filelist
209
210     [msg,ierr, stderr] = unix_g(cmd);
211
212     if ( ilib_verbose() == 2 ) then
213         mprintf(gettext("   %s: Substitute the reference by the actual file.\n"),"ilib_gen_Make");
214         mprintf(gettext("   Command: %s\n"),cmd);
215         if (length(msg)) then
216             mprintf(gettext("Output: %s\n"),msg);
217         end
218         mprintf(gettext("stderr: %s\n"),stderr);
219     end
220
221     if ierr <> 0 then
222         if ( ilib_verbose() <> 0 ) then
223             mprintf(gettext("%s: Error while modifying the reference Makefile:\n"),"ilib_gen_Make")
224             mprintf(msg + " " + stderr);
225         end
226         return;
227     end
228
229     chdir(originPath);
230
231 endfunction
232
233
234 function generateConfigure(workingPath, ..
235     ldflags, ..
236     cflags, ..
237     fflags, ..
238     cc)
239
240     // We launch ./configure in order to produce a "generic" Makefile
241     // for this computer
242
243     if ( ilib_verbose() <> 0 ) then
244         mprintf(gettext("   %s: configure : Generate Makefile.\n"),"ilib_gen_Make");
245     end
246     cmd = gencompilationflags_unix(ldflags, cflags, fflags, cc, "configure")
247     cmd = workingPath+"/compilerDetection.sh "+cmd
248
249     [msg,ierr,stderr] = unix_g(cmd);
250
251     if ( ilib_verbose() == 2 ) then
252         mprintf(gettext("   %s: Command: %s\n"),"ilib_gen_Make",cmd);
253         mprintf(gettext("   Output: %s\n"),msg);
254         mprintf(gettext("   stderr: %s\n"),stderr);
255     end
256
257     if ierr <> 0 then
258         if ( ilib_verbose() <> 0 ) then
259             mprintf("%s\n", msg + " " + stderr);
260         end
261         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"));
262         return;
263     end
264
265 endfunction
266
267 function copyMandatoryFiles(commandpath,workingPath)
268     // List of the files mandatory to generate a lib with the detection of the env
269     mandatoryFiles = ["compilerDetection.sh", ..
270     "configure.ac", ..
271     "configure", ..
272     "compile", ..
273     "Makefile.am", ..
274     "Makefile.in", ..
275     "config.sub", ..
276     "libtool", ..
277     "config.guess", ..
278     "config.status", ..
279     "depcomp", ..
280     "install-sh", ..
281     "ltmain.sh", ..
282     "missing", ..
283     "aclocal.m4"];
284
285     // Copy files to the working path
286     for x = mandatoryFiles(:)' ;
287         fullPath=commandpath+"/"+x;
288         if (isfile(fullPath)) then
289             [status,msg]=copyfile(fullPath,workingPath);
290             if (status <> 1)
291                 error(msprintf(gettext("%s: An error occurred: %s\n"), "ilib_gen_Make",msg));
292             end
293         end
294     end
295
296 endfunction
297 //=============================================================================