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