~oif-team/ubuntu/natty/qt4-x11/xi2.1

« back to all changes in this revision

Viewing changes to qmake/generators/unix/unixmake.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Adam Conrad
  • Date: 2005-08-24 04:09:09 UTC
  • Revision ID: james.westby@ubuntu.com-20050824040909-xmxe9jfr4a0w5671
Tags: upstream-4.0.0
ImportĀ upstreamĀ versionĀ 4.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/****************************************************************************
 
2
**
 
3
** Copyright (C) 1992-2005 Trolltech AS. All rights reserved.
 
4
**
 
5
** This file is part of the qmake application of the Qt Toolkit.
 
6
**
 
7
** This file may be distributed under the terms of the Q Public License
 
8
** as defined by Trolltech AS of Norway and appearing in the file
 
9
** LICENSE.QPL included in the packaging of this file.
 
10
**
 
11
** This file may be distributed and/or modified under the terms of the
 
12
** GNU General Public License version 2 as published by the Free Software
 
13
** Foundation and appearing in the file LICENSE.GPL included in the
 
14
** packaging of this file.
 
15
**
 
16
** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
 
17
**   information about Qt Commercial License Agreements.
 
18
** See http://www.trolltech.com/qpl/ for QPL licensing information.
 
19
** See http://www.trolltech.com/gpl/ for GPL licensing information.
 
20
**
 
21
** Contact info@trolltech.com if any conditions of this licensing are
 
22
** not clear to you.
 
23
**
 
24
** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
25
** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
26
**
 
27
****************************************************************************/
 
28
 
 
29
#include "unixmake.h"
 
30
#include "option.h"
 
31
#include <qregexp.h>
 
32
#include <qfile.h>
 
33
#include <qhash.h>
 
34
#include <qdir.h>
 
35
#include <time.h>
 
36
 
 
37
 
 
38
void
 
39
UnixMakefileGenerator::init()
 
40
{
 
41
    if(init_flag)
 
42
        return;
 
43
    init_flag = true;
 
44
 
 
45
    if(!project->isEmpty("QMAKE_FAILED_REQUIREMENTS")) /* no point */
 
46
        return;
 
47
 
 
48
    QStringList &configs = project->variables()["CONFIG"];
 
49
 
 
50
    //defaults
 
51
    if(project->isEmpty("ICON") && !project->isEmpty("RC_FILE"))
 
52
        project->variables()["ICON"] = project->variables()["RC_FILE"];
 
53
    if(project->isEmpty("QMAKE_EXTENSION_SHLIB")) {
 
54
        if(project->isEmpty("QMAKE_CYGWIN_SHLIB")) {
 
55
            project->variables()["QMAKE_EXTENSION_SHLIB"].append("so");
 
56
        } else {
 
57
            project->variables()["QMAKE_EXTENSION_SHLIB"].append("dll");
 
58
        }
 
59
    }
 
60
    if(project->isEmpty("QMAKE_CFLAGS_PRECOMPILE"))
 
61
        project->variables()["QMAKE_CFLAGS_PRECOMPILE"].append("-x c-header -c");
 
62
    if(project->isEmpty("QMAKE_CXXFLAGS_PRECOMPILE"))
 
63
        project->variables()["QMAKE_CXXFLAGS_PRECOMPILE"].append("-x c++-header -c");
 
64
    if(project->isEmpty("QMAKE_CFLAGS_USE_PRECOMPILE"))
 
65
        project->variables()["QMAKE_CFLAGS_USE_PRECOMPILE"].append("-include");
 
66
    if(project->isEmpty("QMAKE_EXTENSION_PLUGIN"))
 
67
        project->variables()["QMAKE_EXTENSION_PLUGIN"].append(project->first("QMAKE_EXTENSION_SHLIB"));
 
68
    if(project->isEmpty("QMAKE_COPY_FILE"))
 
69
        project->variables()["QMAKE_COPY_FILE"].append("$(COPY)");
 
70
    if(project->isEmpty("QMAKE_COPY_DIR"))
 
71
        project->variables()["QMAKE_COPY_DIR"].append("$(COPY) -R");
 
72
    if(project->isEmpty("QMAKE_INSTALL_FILE"))
 
73
        project->variables()["QMAKE_INSTALL_FILE"].append("$(COPY_FILE)");
 
74
    if(project->isEmpty("QMAKE_INSTALL_DIR"))
 
75
        project->variables()["QMAKE_INSTALL_DIR"].append("$(COPY_DIR)");
 
76
    if(project->isEmpty("QMAKE_LIBTOOL"))
 
77
        project->variables()["QMAKE_LIBTOOL"].append("libtool --silent");
 
78
    if(project->isEmpty("QMAKE_SYMBOLIC_LINK"))
 
79
        project->variables()["QMAKE_SYMBOLIC_LINK"].append("ln -sf");
 
80
 
 
81
    /* this should probably not be here, but I'm using it to wrap the .t files */
 
82
    if(project->first("TEMPLATE") == "app")
 
83
        project->variables()["QMAKE_APP_FLAG"].append("1");
 
84
    else if(project->first("TEMPLATE") == "lib")
 
85
        project->variables()["QMAKE_LIB_FLAG"].append("1");
 
86
    else if(project->first("TEMPLATE") == "subdirs") {
 
87
        MakefileGenerator::init();
 
88
        if(project->isEmpty("MAKEFILE"))
 
89
            project->variables()["MAKEFILE"].append("Makefile");
 
90
        if(project->isEmpty("QMAKE_QMAKE"))
 
91
            project->variables()["QMAKE_QMAKE"].append("qmake");
 
92
        if(project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].indexOf("qmake_all") == -1)
 
93
            project->variables()["QMAKE_INTERNAL_QMAKE_DEPS"].append("qmake_all");
 
94
        return; /* subdirs is done */
 
95
    }
 
96
 
 
97
    //If the TARGET looks like a path split it into DESTDIR and the resulting TARGET
 
98
    if(!project->isEmpty("TARGET")) {
 
99
        QString targ = project->first("TARGET");
 
100
        int slsh = qMax(targ.lastIndexOf('/'), targ.lastIndexOf(Option::dir_sep));
 
101
        if(slsh != -1) {
 
102
            if(project->isEmpty("DESTDIR"))
 
103
                project->values("DESTDIR").append("");
 
104
            else if(project->first("DESTDIR").right(1) != Option::dir_sep)
 
105
                project->variables()["DESTDIR"] = QStringList(project->first("DESTDIR") + Option::dir_sep);
 
106
            project->variables()["DESTDIR"] = QStringList(project->first("DESTDIR") + targ.left(slsh+1));
 
107
            project->variables()["TARGET"] = QStringList(targ.mid(slsh+1));
 
108
        }
 
109
    }
 
110
 
 
111
    project->variables()["QMAKE_ORIG_TARGET"] = project->variables()["TARGET"];
 
112
    project->variables()["QMAKE_ORIG_DESTDIR"] = project->variables()["DESTDIR"];
 
113
    project->variables()["QMAKE_LIBS"] += project->variables()["LIBS"];
 
114
    if((!project->isEmpty("QMAKE_LIB_FLAG") && !project->isActiveConfig("staticlib")) ||
 
115
         (project->isActiveConfig("qt") &&  project->isActiveConfig("plugin"))) {
 
116
        if(configs.indexOf("dll") == -1) configs.append("dll");
 
117
    } else if(!project->isEmpty("QMAKE_APP_FLAG") || project->isActiveConfig("dll")) {
 
118
        configs.removeAll("staticlib");
 
119
    }
 
120
    if(!project->isEmpty("QMAKE_INCREMENTAL"))
 
121
        project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_INCREMENTAL"];
 
122
    else if(!project->isEmpty("QMAKE_LFLAGS_PREBIND") &&
 
123
            !project->variables()["QMAKE_LIB_FLAG"].isEmpty() &&
 
124
            project->isActiveConfig("dll"))
 
125
        project->variables()["QMAKE_LFLAGS"] += project->variables()["QMAKE_LFLAGS_PREBIND"];
 
126
    if(!project->isEmpty("QMAKE_INCDIR"))
 
127
        project->variables()["INCLUDEPATH"] += project->variables()["QMAKE_INCDIR"];
 
128
    if(!project->isEmpty("QMAKE_LIBDIR")) {
 
129
        const QStringList &libdirs = project->values("QMAKE_LIBDIR");
 
130
        for(QStringList::ConstIterator it = libdirs.begin(); it != libdirs.end(); ++it) {
 
131
            if(!project->isEmpty("QMAKE_LFLAGS_RPATH") && project->isActiveConfig("rpath_libdirs"))
 
132
                project->variables()["QMAKE_LFLAGS"] += var("QMAKE_LFLAGS_RPATH") + (*it);
 
133
            project->variables()["QMAKE_LIBDIR_FLAGS"] += "-L" + (*it);
 
134
        }
 
135
    }
 
136
    if(!project->isEmpty("QMAKE_RPATHDIR")) {
 
137
        const QStringList &rpathdirs = project->values("QMAKE_RPATHDIR");
 
138
        for(QStringList::ConstIterator it = rpathdirs.begin(); it != rpathdirs.end(); ++it) {
 
139
            if(!project->isEmpty("QMAKE_LFLAGS_RPATH"))
 
140
                project->variables()["QMAKE_LFLAGS"] += var("QMAKE_LFLAGS_RPATH") + QFileInfo((*it)).absoluteFilePath();
 
141
        }
 
142
    }
 
143
    QString compile_flag = var("QMAKE_COMPILE_FLAG");
 
144
    if(compile_flag.isEmpty())
 
145
        compile_flag = "-c";
 
146
    if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")) {
 
147
        QString prefix_flags = project->first("QMAKE_CFLAGS_PREFIX_INCLUDE");
 
148
        if(prefix_flags.isEmpty())
 
149
            prefix_flags = "-include";
 
150
        compile_flag += " " + prefix_flags + " " + project->first("QMAKE_ORIG_TARGET");
 
151
    }
 
152
    if(project->isEmpty("QMAKE_RUN_CC"))
 
153
        project->variables()["QMAKE_RUN_CC"].append("$(CC) " + compile_flag + " $(CFLAGS) $(INCPATH) -o $obj $src");
 
154
    if(project->isEmpty("QMAKE_RUN_CC_IMP"))
 
155
        project->variables()["QMAKE_RUN_CC_IMP"].append("$(CC) " + compile_flag + " $(CFLAGS) $(INCPATH) -o $@ $<");
 
156
    if(project->isEmpty("QMAKE_RUN_CXX"))
 
157
        project->variables()["QMAKE_RUN_CXX"].append("$(CXX) " + compile_flag + " $(CXXFLAGS) $(INCPATH) -o $obj $src");
 
158
    if(project->isEmpty("QMAKE_RUN_CXX_IMP"))
 
159
        project->variables()["QMAKE_RUN_CXX_IMP"].append("$(CXX) " + compile_flag + " $(CXXFLAGS) $(INCPATH) -o $@ $<");
 
160
 
 
161
    project->variables()["QMAKE_FILETAGS"] << "SOURCES" << "GENERATED_SOURCES" << "TARGET" << "DESTDIR";
 
162
    if(!project->isEmpty("QMAKE_EXTRA_COMPILERS")) {
 
163
        const QStringList &quc = project->variables()["QMAKE_EXTRA_COMPILERS"];
 
164
        for(QStringList::ConstIterator it = quc.begin(); it != quc.end(); ++it)
 
165
            project->variables()["QMAKE_FILETAGS"] += project->variables()[(*it)+".input"];
 
166
    }
 
167
 
 
168
    if(project->isActiveConfig("GNUmake") && !project->isEmpty("QMAKE_CFLAGS_DEPS"))
 
169
        include_deps = true; //do not generate deps
 
170
    if(project->isActiveConfig("compile_libtool"))
 
171
        Option::obj_ext = ".lo"; //override the .o
 
172
 
 
173
    MakefileGenerator::init();
 
174
 
 
175
    if(project->isActiveConfig("macx") &&
 
176
       !project->isEmpty("TARGET") && !project->isActiveConfig("compile_libtool") &&
 
177
       ((project->first("TEMPLATE") == "app" && project->isActiveConfig("app_bundle")) ||
 
178
        (project->first("TEMPLATE") == "lib" && project->isActiveConfig("lib_bundle") &&
 
179
         !project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin")))) {
 
180
        if(project->first("TEMPLATE") == "app") {
 
181
            QString bundle = project->first("TARGET");
 
182
            if(!project->isEmpty("QMAKE_APPLICATION_BUNDLE_NAME"))
 
183
                bundle = project->first("QMAKE_APPLICATION_BUNDLE_NAME");
 
184
            if(!bundle.endsWith(".app"))
 
185
                bundle += ".app";
 
186
            project->variables()["QMAKE_BUNDLE_NAME"] = QStringList(bundle);
 
187
            project->variables()["QMAKE_PKGINFO"].append(project->first("DESTDIR") + bundle + "/PkgInfo");
 
188
            project->variables()["ALL_DEPS"] += project->first("QMAKE_PKGINFO");
 
189
        } else if(project->first("TEMPLATE") == "lib") {
 
190
            QString bundle = project->first("TARGET");
 
191
            if(!project->isEmpty("QMAKE_FRAMEWORK_BUNDLE_NAME"))
 
192
                bundle = project->first("QMAKE_FRAMEWORK_BUNDLE_NAME");
 
193
            if(!bundle.endsWith(".framework"))
 
194
                bundle += ".framework";
 
195
            project->variables()["QMAKE_BUNDLE_NAME"] = QStringList(bundle);
 
196
        }
 
197
    } else { //no bundling here
 
198
        project->variables()["QMAKE_BUNDLE_NAME"].clear();
 
199
    }
 
200
 
 
201
    if(!project->isEmpty("QMAKE_INTERNAL_INCLUDED_FILES"))
 
202
        project->variables()["DISTFILES"] += project->variables()["QMAKE_INTERNAL_INCLUDED_FILES"];
 
203
    project->variables()["DISTFILES"] += project->projectFile();
 
204
 
 
205
    init2();
 
206
    project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "QMAKE_LIBDIR_FLAGS" << "QMAKE_LIBS";
 
207
    if(!project->isEmpty("QMAKE_MAX_FILES_PER_AR")) {
 
208
        bool ok;
 
209
        int max_files = project->first("QMAKE_MAX_FILES_PER_AR").toInt(&ok);
 
210
        QStringList ar_sublibs, objs = project->variables()["OBJECTS"];
 
211
        if(ok && max_files > 5 && max_files < (int)objs.count()) {
 
212
            int obj_cnt = 0, lib_cnt = 0;
 
213
            QString lib;
 
214
            for(QStringList::Iterator objit = objs.begin(); objit != objs.end(); ++objit) {
 
215
                if((++obj_cnt) >= max_files) {
 
216
                    if(lib_cnt) {
 
217
                        lib.sprintf("lib%s-tmp%d.a",
 
218
                                    project->first("QMAKE_ORIG_TARGET").toLatin1().constData(), lib_cnt);
 
219
                        ar_sublibs << lib;
 
220
                        obj_cnt = 0;
 
221
                    }
 
222
                    lib_cnt++;
 
223
                }
 
224
            }
 
225
        }
 
226
        if(!ar_sublibs.isEmpty()) {
 
227
            project->variables()["QMAKE_AR_SUBLIBS"] = ar_sublibs;
 
228
            project->variables()["QMAKE_INTERNAL_PRL_LIBS"] << "QMAKE_AR_SUBLIBS";
 
229
        }
 
230
    }
 
231
 
 
232
    if(project->isActiveConfig("compile_libtool")) {
 
233
        const QString libtoolify[] = { "QMAKE_RUN_CC", "QMAKE_RUN_CC_IMP",
 
234
                                       "QMAKE_RUN_CXX", "QMAKE_RUN_CXX_IMP",
 
235
                                       "QMAKE_LINK_THREAD", "QMAKE_LINK", "QMAKE_AR_CMD", "QMAKE_LINK_SHLIB_CMD",
 
236
                                       QString() };
 
237
        for(int i = 0; !libtoolify[i].isNull(); i++) {
 
238
            QStringList &l = project->variables()[libtoolify[i]];
 
239
            if(!l.isEmpty()) {
 
240
                QString libtool_flags, comp_flags;
 
241
                if(libtoolify[i].startsWith("QMAKE_LINK") || libtoolify[i] == "QMAKE_AR_CMD") {
 
242
                    libtool_flags += " --mode=link";
 
243
                    if(project->isActiveConfig("staticlib")) {
 
244
                        libtool_flags += " -static";
 
245
                    } else {
 
246
                        if(!project->isEmpty("QMAKE_LIB_FLAG")) {
 
247
                            int maj = project->first("VER_MAJ").toInt();
 
248
                            int min = project->first("VER_MIN").toInt();
 
249
                            int pat = project->first("VER_PAT").toInt();
 
250
                            comp_flags += " -version-info " + QString::number(10*maj + min) +
 
251
                                          ":" + QString::number(pat) + ":0";
 
252
                            if(libtoolify[i] != "QMAKE_AR_CMD") {
 
253
                                QString rpath = Option::output_dir;
 
254
                                if(!project->isEmpty("DESTDIR")) {
 
255
                                    rpath = project->first("DESTDIR");
 
256
                                    if(QDir::isRelativePath(rpath))
 
257
                                        rpath.prepend(Option::output_dir + Option::dir_sep);
 
258
                                }
 
259
                                comp_flags += " -rpath " + Option::fixPathToTargetOS(rpath, false);
 
260
                            }
 
261
                        }
 
262
                    }
 
263
                    if(project->isActiveConfig("plugin"))
 
264
                        libtool_flags += " -module";
 
265
                } else {
 
266
                    libtool_flags += " --mode=compile";
 
267
                }
 
268
                l.first().prepend("$(LIBTOOL)" + libtool_flags + " ");
 
269
                if(!comp_flags.isEmpty())
 
270
                    l.first() += comp_flags;
 
271
            }
 
272
        }
 
273
    }
 
274
}
 
275
 
 
276
void
 
277
UnixMakefileGenerator::processPrlVariable(const QString &var, const QStringList &l)
 
278
{
 
279
    if(var == "QMAKE_PRL_LIBS") {
 
280
        project->variables()["QMAKE_CURRENT_PRL_LIBS"] += l;
 
281
    } else
 
282
        MakefileGenerator::processPrlVariable(var, l);
 
283
}
 
284
 
 
285
QStringList
 
286
&UnixMakefileGenerator::findDependencies(const QString &file)
 
287
{
 
288
    QStringList &ret = MakefileGenerator::findDependencies(file);
 
289
    // Note: The QMAKE_IMAGE_COLLECTION file have all images
 
290
    // as dependency, so don't add precompiled header then
 
291
    if(doPrecompiledHeaders() && !project->isEmpty("PRECOMPILED_HEADER")
 
292
       && file != project->first("QMAKE_IMAGE_COLLECTION")) {
 
293
        QString header_prefix = project->first("QMAKE_ORIG_TARGET") + ".gch" + Option::dir_sep;
 
294
        header_prefix += project->first("QMAKE_PRECOMP_PREFIX");
 
295
        if(file.endsWith(".c")) {
 
296
            QString precomp_h = header_prefix + "c";
 
297
            if(!ret.contains(precomp_h))
 
298
                ret += precomp_h;
 
299
        } else {
 
300
            for(QStringList::Iterator it = Option::cpp_ext.begin(); it != Option::cpp_ext.end(); ++it) {
 
301
                if(file.endsWith(*it)) {
 
302
                    QString precomp_h = header_prefix + "c++";
 
303
                    if(!ret.contains(precomp_h))
 
304
                        ret += precomp_h;
 
305
                    break;
 
306
                }
 
307
            }
 
308
        }
 
309
    }
 
310
    return ret;
 
311
}
 
312
 
 
313
bool
 
314
UnixMakefileGenerator::findLibraries()
 
315
{
 
316
    QList<QMakeLocalFileName> libdirs, frameworkdirs;
 
317
    frameworkdirs.append(QMakeLocalFileName("/System/Library/Frameworks"));
 
318
    frameworkdirs.append(QMakeLocalFileName("/Library/Frameworks"));
 
319
    const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString() };
 
320
    for(int i = 0; !lflags[i].isNull(); i++) {
 
321
        QStringList &l = project->variables()[lflags[i]];
 
322
        for(QStringList::Iterator it = l.begin(); it != l.end(); ++it) {
 
323
            bool do_suffix = true;
 
324
            QString stub, dir, extn, opt = (*it).trimmed();
 
325
            if(opt.startsWith("-")) {
 
326
                if(opt.startsWith("-L")) {
 
327
                    libdirs.append(QMakeLocalFileName(opt.right(opt.length()-2)));
 
328
                } else if(opt.startsWith("-l")) {
 
329
                    stub = opt.mid(2);
 
330
                } else if(Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-F")) {
 
331
                    frameworkdirs.append(QMakeLocalFileName(opt.right(opt.length()-2)));
 
332
                } else if(Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-framework")) {
 
333
                    if(opt.length() > 11) {
 
334
                        opt = opt.mid(11);
 
335
                    } else {
 
336
                        ++it;
 
337
                        opt = (*it);
 
338
                    }
 
339
                    do_suffix = false;
 
340
                    extn = "";
 
341
                    dir = "/System/Library/Frameworks/" + opt + ".framework/";
 
342
                    stub = opt;
 
343
                }
 
344
            } else {
 
345
                extn = dir = "";
 
346
                stub = opt;
 
347
                int slsh = opt.lastIndexOf(Option::dir_sep);
 
348
                if(slsh != -1) {
 
349
                    dir = opt.left(slsh);
 
350
                    stub = opt.mid(slsh+1);
 
351
                }
 
352
                QRegExp stub_reg("^.*lib(" + stub + "[^./=]*)\\.(.*)$");
 
353
                if(stub_reg.exactMatch(stub)) {
 
354
                    stub = stub_reg.cap(1);
 
355
                    extn = stub_reg.cap(2);
 
356
                }
 
357
            }
 
358
            if(!stub.isEmpty()) {
 
359
                if(do_suffix && !project->isEmpty("QMAKE_" + stub.toUpper() + "_SUFFIX"))
 
360
                    stub += project->first("QMAKE_" + stub.toUpper() + "_SUFFIX");
 
361
                bool found = false;
 
362
                QStringList extens;
 
363
                if(!extn.isNull())
 
364
                    extens << extn;
 
365
                else
 
366
                    extens << project->variables()["QMAKE_EXTENSION_SHLIB"].first() << "a";
 
367
                for(QStringList::Iterator extit = extens.begin(); extit != extens.end(); ++extit) {
 
368
                    if(dir.isNull()) {
 
369
                        QString lib_stub;
 
370
                        for(QList<QMakeLocalFileName>::Iterator dep_it = libdirs.begin(); dep_it != libdirs.end(); ++dep_it) {
 
371
                            if(exists((*dep_it).local() + Option::dir_sep + "lib" + stub +
 
372
                                             "." + (*extit))) {
 
373
                                lib_stub = stub;
 
374
                                break;
 
375
                            }
 
376
                        }
 
377
                        if(!lib_stub.isNull()) {
 
378
                            (*it) = "-l" + lib_stub;
 
379
                            found = true;
 
380
                            break;
 
381
                        }
 
382
                    } else {
 
383
                        if(exists("lib" + stub + "." + (*extit))) {
 
384
                            (*it) = "lib" + stub + "." + (*extit);
 
385
                            found = true;
 
386
                            break;
 
387
                        }
 
388
                    }
 
389
                }
 
390
                if(!found && project->isActiveConfig("compile_libtool")) {
 
391
                    for(QList<QMakeLocalFileName>::Iterator dep_it = libdirs.begin(); dep_it != libdirs.end(); ++dep_it) {
 
392
                        if(exists((*dep_it).local() + Option::dir_sep + "lib" + stub + Option::libtool_ext)) {
 
393
                            (*it) = (*dep_it).real() + Option::dir_sep + "lib" + stub + Option::libtool_ext;
 
394
                            found = true;
 
395
                            break;
 
396
                        }
 
397
                    }
 
398
                }
 
399
            }
 
400
        }
 
401
    }
 
402
    return false;
 
403
}
 
404
 
 
405
QString linkLib(const QString &file, const QString &libName) {
 
406
  QString ret;
 
407
  QRegExp reg("^.*lib(" + QRegExp::escape(libName) + "[^./=]*).*$");
 
408
  if(reg.exactMatch(file))
 
409
    ret = "-l" + reg.cap(1);
 
410
  return ret;
 
411
}
 
412
 
 
413
void
 
414
UnixMakefileGenerator::processPrlFiles()
 
415
{
 
416
    QList<QMakeLocalFileName> libdirs, frameworkdirs;
 
417
    frameworkdirs.append(QMakeLocalFileName("/System/Library/Frameworks"));
 
418
    frameworkdirs.append(QMakeLocalFileName("/Library/Frameworks"));
 
419
    const QString lflags[] = { "QMAKE_LIBDIR_FLAGS", "QMAKE_LIBS", QString() };
 
420
    for(int i = 0; !lflags[i].isNull(); i++) {
 
421
            QStringList &l = project->variables()[lflags[i]];
 
422
        for(int lit = 0; lit < l.size(); ++lit) {
 
423
            QString opt = l.at(lit).trimmed();
 
424
                if(opt.startsWith("-")) {
 
425
                    if(opt.startsWith("-L")) {
 
426
                        libdirs.append(QMakeLocalFileName(opt.right(opt.length()-2)));
 
427
                } else if(opt.startsWith("-l")) {
 
428
                        QString lib = opt.right(opt.length() - 2);
 
429
                        for(QList<QMakeLocalFileName>::Iterator dep_it = libdirs.begin(); dep_it != libdirs.end(); ++dep_it) {
 
430
                            if(!project->isActiveConfig("compile_libtool")) { //give them the .libs..
 
431
                                QString la = (*dep_it).local() + Option::dir_sep + "lib" + lib + Option::libtool_ext;
 
432
                                if(exists(la) && QFile::exists((*dep_it).local() + Option::dir_sep + ".libs")) {
 
433
                                    QString dot_libs = (*dep_it).real() + Option::dir_sep + ".libs";
 
434
                                l.append("-L" + dot_libs);
 
435
                                    libdirs.append(QMakeLocalFileName(dot_libs));
 
436
                                }
 
437
                            }
 
438
 
 
439
                            QString prl = (*dep_it).local() + Option::dir_sep + "lib" + lib;
 
440
                            if(!project->isEmpty("QMAKE_" + lib.toUpper() + "_SUFFIX"))
 
441
                                prl += project->first("QMAKE_" + lib.toUpper() + "_SUFFIX");
 
442
                            if(processPrlFile(prl)) {
 
443
                                if(prl.startsWith((*dep_it).local()))
 
444
                                    prl.replace(0, (*dep_it).local().length(), (*dep_it).real());
 
445
                                opt = linkLib(prl, lib);
 
446
                                break;
 
447
                            }
 
448
                        }
 
449
                    } else if(Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-F")) {
 
450
                        frameworkdirs.append(QMakeLocalFileName(opt.right(opt.length()-2)));
 
451
                    } else if(Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-framework")) {
 
452
                    if(opt.length() > 11)
 
453
                            opt = opt.mid(11);
 
454
                    else
 
455
                        opt = l.at(++lit);
 
456
                    opt = opt.trimmed();
 
457
                        for(QList<QMakeLocalFileName>::Iterator dep_it = frameworkdirs.begin();
 
458
                            dep_it != frameworkdirs.end(); ++dep_it) {
 
459
                            QString prl = (*dep_it).local() + "/" + opt + ".framework/" + opt + Option::prl_ext;
 
460
                        if(processPrlFile(prl))
 
461
                                break;
 
462
                            }
 
463
                    }
 
464
                } else if(!opt.isNull()) {
 
465
                    QString lib = opt;
 
466
                processPrlFile(lib);
 
467
#if 0
 
468
                    if(ret)
 
469
                      opt = linkLib(lib, "");
 
470
#endif
 
471
                    if(!opt.isEmpty())
 
472
                    l.replaceInStrings(lib, opt);
 
473
            }
 
474
 
 
475
            QStringList &prl_libs = project->variables()["QMAKE_CURRENT_PRL_LIBS"];
 
476
            if(!prl_libs.isEmpty()) {
 
477
                for(int prl = 0; prl < prl_libs.size(); ++prl)
 
478
                    l.insert(lit+prl+1, prl_libs.at(prl));
 
479
                prl_libs.clear();
 
480
                }
 
481
            }
 
482
 
 
483
        //merge them into a logical order
 
484
        if(!project->isActiveConfig("no_smart_library_merge") && !project->isActiveConfig("no_lflags_merge")) {
 
485
            QStringList lflags;
 
486
            for(int lit = 0; lit < l.size(); ++lit) {
 
487
                QString opt = l.at(lit).trimmed();
 
488
                if(opt.startsWith("-")) {
 
489
                    if(opt.startsWith("-L") ||
 
490
                       (Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-F"))) {
 
491
                        if(lit == 0 || l.lastIndexOf(opt, lit-1) == -1)
 
492
                            lflags.append(opt);
 
493
                    } else if(opt.startsWith("-l")) {
 
494
                        if(lit == l.size()-1 || l.indexOf(opt, lit+1) == -1)
 
495
                            lflags.append(opt);
 
496
                    } else if(Option::target_mode == Option::TARG_MACX_MODE && opt.startsWith("-framework")) {
 
497
                        if(opt.length() > 11)
 
498
                            opt = opt.mid(11);
 
499
                        else
 
500
                            opt = l.at(++lit);
 
501
                        bool found = false;
 
502
                        for(int x = lit+1; x < l.size(); ++x) {
 
503
                            QString xf = l.at(x);
 
504
                            if(xf.startsWith("-framework")) {
 
505
                                QString framework;
 
506
                                if(xf.length() > 11)
 
507
                                    framework = xf.mid(11);
 
508
            else
 
509
                                    framework = l.at(++x);
 
510
                                if(framework == opt) {
 
511
                                    found = true;
 
512
                break;
 
513
        }
 
514
    }
 
515
                        }
 
516
                        if(!found) {
 
517
                            lflags.append("-framework");
 
518
                            lflags.append(opt);
 
519
                        }
 
520
                    } else {
 
521
                        lflags.append(opt);
 
522
                    }
 
523
                } else if(!opt.isNull()) {
 
524
                    if(lit == 0 || l.lastIndexOf(opt, lit-1) == -1)
 
525
                        lflags.append(opt);
 
526
                }
 
527
            }
 
528
            l = lflags;
 
529
        }
 
530
    }
 
531
}
 
532
 
 
533
QString
 
534
UnixMakefileGenerator::defaultInstall(const QString &t)
 
535
{
 
536
    if(t != "target" || project->first("TEMPLATE") == "subdirs")
 
537
        return QString();
 
538
 
 
539
    bool bundle = false;
 
540
    const QString root = "$(INSTALL_ROOT)";
 
541
    QStringList &uninst = project->variables()[t + ".uninstall"];
 
542
    QString ret, destdir=project->first("DESTDIR");
 
543
    QString targetdir = Option::fixPathToTargetOS(project->first("target.path"), false);
 
544
    if(!destdir.isEmpty() && destdir.right(1) != Option::dir_sep)
 
545
        destdir += Option::dir_sep;
 
546
    targetdir = fileFixify(targetdir, FileFixifyAbsolute);
 
547
    if(targetdir.right(1) != Option::dir_sep)
 
548
        targetdir += Option::dir_sep;
 
549
 
 
550
    QStringList links;
 
551
    QString target="$(TARGET)";
 
552
    if(!project->isEmpty("QMAKE_BUNDLE_NAME")) {
 
553
        target = project->first("QMAKE_BUNDLE_NAME");
 
554
        bundle = true;
 
555
    } else if(project->first("TEMPLATE") == "app") {
 
556
        target = "$(QMAKE_TARGET)";
 
557
    } else if(project->first("TEMPLATE") == "lib") {
 
558
        if(project->isActiveConfig("create_prl") && !project->isActiveConfig("no_install_prl") &&
 
559
           !project->isEmpty("QMAKE_INTERNAL_PRL_FILE")) {
 
560
            QString dst_prl = project->first("QMAKE_INTERNAL_PRL_FILE");
 
561
            int slsh = dst_prl.lastIndexOf('/');
 
562
            if(slsh != -1)
 
563
                dst_prl = dst_prl.right(dst_prl.length() - slsh - 1);
 
564
            dst_prl = filePrefixRoot(root, targetdir + dst_prl);
 
565
            ret += "-$(INSTALL_FILE) \"" + project->first("QMAKE_INTERNAL_PRL_FILE") + "\" \"" + dst_prl + "\"";
 
566
            if(!uninst.isEmpty())
 
567
                uninst.append("\n\t");
 
568
            uninst.append("-$(DEL_FILE) \"" + dst_prl + "\"");
 
569
        }
 
570
        if(project->isActiveConfig("create_libtool") && !project->isActiveConfig("compile_libtool")) {
 
571
            QString src_lt = var("QMAKE_ORIG_TARGET");
 
572
            int slsh = src_lt.lastIndexOf(Option::dir_sep);
 
573
            if(slsh != -1)
 
574
                src_lt = src_lt.right(src_lt.length() - slsh);
 
575
            int dot = src_lt.indexOf('.');
 
576
            if(dot != -1)
 
577
                src_lt = src_lt.left(dot);
 
578
            src_lt += Option::libtool_ext;
 
579
            src_lt.prepend("lib");
 
580
            QString dst_lt = filePrefixRoot(root, targetdir + src_lt);
 
581
            if(!project->isEmpty("DESTDIR")) {
 
582
                src_lt.prepend(var("DESTDIR"));
 
583
                src_lt = Option::fixPathToLocalOS(fileFixify(src_lt,
 
584
                                                             qmake_getpwd(), Option::output_dir, FileFixifyAbsolute));
 
585
            }
 
586
            if(!ret.isEmpty())
 
587
                ret += "\n\t";
 
588
            ret += "-$(INSTALL_FILE) \"" + src_lt + "\" \"" + dst_lt + "\"";
 
589
            if(!uninst.isEmpty())
 
590
                uninst.append("\n\t");
 
591
            uninst.append("-$(DEL_FILE) \"" + dst_lt + "\"");
 
592
        }
 
593
        if(project->isActiveConfig("create_pc")) {
 
594
            QString src_pc = var("QMAKE_ORIG_TARGET");
 
595
            int slsh = src_pc.lastIndexOf(Option::dir_sep);
 
596
            if(slsh != -1)
 
597
                src_pc = src_pc.right(src_pc.length() - slsh);
 
598
            int dot = src_pc.indexOf('.');
 
599
            if(dot != -1)
 
600
                src_pc = src_pc.left(dot);
 
601
            src_pc += ".pc";
 
602
            QString d = filePrefixRoot(root, targetdir + "pkgconfig" + Option::dir_sep);
 
603
            QString dst_pc = d + src_pc;
 
604
            if(!project->isEmpty("DESTDIR")) {
 
605
                src_pc.prepend(var("DESTDIR"));
 
606
                src_pc = Option::fixPathToLocalOS(fileFixify(src_pc,
 
607
                                                             qmake_getpwd(), Option::output_dir, FileFixifyAbsolute));
 
608
            }
 
609
            if(!ret.isEmpty())
 
610
                ret += "\n\t";
 
611
            ret += mkdir_p_asstring(d) + "\n\t";
 
612
            ret += "-$(INSTALL_FILE) \"" + src_pc + "\" \"" + dst_pc + "\"";
 
613
            if(!uninst.isEmpty())
 
614
                uninst.append("\n\t");
 
615
            uninst.append("-$(DEL_FILE) \"" + dst_pc + "\"");
 
616
        }
 
617
        if(project->isEmpty("QMAKE_CYGWIN_SHLIB")) {
 
618
            if(!project->isActiveConfig("staticlib") && !project->isActiveConfig("plugin")) {
 
619
                if(project->isEmpty("QMAKE_HPUX_SHLIB")) {
 
620
                    links << "$(TARGET0)" << "$(TARGET1)" << "$(TARGET2)";
 
621
                } else {
 
622
                    links << "$(TARGET0)";
 
623
                }
 
624
            }
 
625
        }
 
626
    }
 
627
 
 
628
    if(!bundle && project->isActiveConfig("compile_libtool")) {
 
629
        QString src_targ = target;
 
630
        if(src_targ == "$(TARGET)")
 
631
            src_targ = "$(TARGETL)";
 
632
        QString dst_dir = fileFixify(targetdir, FileFixifyAbsolute);
 
633
        if(QDir::isRelativePath(dst_dir))
 
634
            dst_dir = Option::fixPathToTargetOS(Option::output_dir + Option::dir_sep + dst_dir);
 
635
        ret = "-$(LIBTOOL) --mode=install cp \"" + src_targ + "\" \"" + filePrefixRoot(root, dst_dir) + "\"";
 
636
        uninst.append("-$(LIBTOOL) --mode=uninstall \"" + src_targ + "\"");
 
637
    } else {
 
638
        QString src_targ = target;
 
639
        if(!destdir.isEmpty())
 
640
            src_targ = Option::fixPathToTargetOS(destdir + target, false);
 
641
        QString dst_targ = filePrefixRoot(root, fileFixify(targetdir + target, FileFixifyAbsolute));
 
642
        if(bundle) {
 
643
            if(!ret.isEmpty())
 
644
                ret += "\n\t";
 
645
            ret += "$(DEL_FILE) -r \"" + dst_targ + "\"\n\t";
 
646
        }
 
647
        if(!ret.isEmpty())
 
648
            ret += "\n\t";
 
649
 
 
650
        const QString copy_cmd = QString(bundle ? "-$(INSTALL_DIR)" : "-$(INSTALL_FILE)") + " \"" +
 
651
                                 src_targ + "\" \"" + dst_targ + "\"";
 
652
        if(project->first("TEMPLATE") == "lib" && !project->isActiveConfig("staticlib")
 
653
           && project->values(t + ".CONFIG").indexOf("fix_rpath") != -1) {
 
654
            if(!project->isEmpty("QMAKE_FIX_RPATH")) {
 
655
                ret += copy_cmd;
 
656
                ret += "\n\t-" + var("QMAKE_FIX_RPATH") + " \"" +
 
657
                       dst_targ + "\" \"" + dst_targ + "\"";
 
658
            } else if(!project->isEmpty("QMAKE_LFLAGS_RPATH")) {
 
659
                ret += "-$(LINK) $(LFLAGS) " + var("QMAKE_LFLAGS_RPATH") + targetdir + " -o \"" +
 
660
                       dst_targ + "\" $(OBJECTS) $(LIBS) $(OBJCOMP)";
 
661
            } else {
 
662
                ret += copy_cmd;
 
663
            }
 
664
        } else {
 
665
            ret += copy_cmd;
 
666
        }
 
667
 
 
668
        if(!project->isActiveConfig("debug") && !project->isEmpty("QMAKE_STRIP") &&
 
669
           (project->first("TEMPLATE") != "lib" || !project->isActiveConfig("staticlib"))) {
 
670
            ret += "\n\t-" + var("QMAKE_STRIP");
 
671
            if(project->first("TEMPLATE") == "lib" && !project->isEmpty("QMAKE_STRIPFLAGS_LIB"))
 
672
                ret += " " + var("QMAKE_STRIPFLAGS_LIB");
 
673
            else if(project->first("TEMPLATE") == "app" && !project->isEmpty("QMAKE_STRIPFLAGS_APP"))
 
674
                ret += " " + var("QMAKE_STRIPFLAGS_APP");
 
675
            if(bundle)
 
676
                ret = " \"" + dst_targ + "/Contents/MacOS/$(QMAKE_TARGET)\"";
 
677
            else
 
678
                ret += " \"" + dst_targ + "\"";
 
679
        }
 
680
        if(!uninst.isEmpty())
 
681
            uninst.append("\n\t");
 
682
        if(bundle)
 
683
            uninst.append("-$(DEL_FILE) -r \"" + dst_targ + "\"");
 
684
        else
 
685
            uninst.append("-$(DEL_FILE) \"" + dst_targ + "\"");
 
686
        if(!links.isEmpty()) {
 
687
            for(QStringList::Iterator it = links.begin(); it != links.end(); it++) {
 
688
                if(Option::target_mode == Option::TARG_WIN_MODE ||
 
689
                   Option::target_mode == Option::TARG_MAC9_MODE) {
 
690
                } else if(Option::target_mode == Option::TARG_UNIX_MODE ||
 
691
                          Option::target_mode == Option::TARG_MACX_MODE) {
 
692
                    QString link = Option::fixPathToTargetOS(destdir + (*it), false);
 
693
                    int lslash = link.lastIndexOf(Option::dir_sep);
 
694
                    if(lslash != -1)
 
695
                        link = link.right(link.length() - (lslash + 1));
 
696
                    QString dst_link = filePrefixRoot(root, fileFixify(targetdir + link, FileFixifyAbsolute));
 
697
                    ret += "\n\t-$(SYMLINK) \"$(TARGET)\" \"" + dst_link + "\"";
 
698
                    if(!uninst.isEmpty())
 
699
                        uninst.append("\n\t");
 
700
                    uninst.append("-$(DEL_FILE) \"" + dst_link + "\"");
 
701
                }
 
702
            }
 
703
        }
 
704
    }
 
705
    return ret;
 
706
}