简体   繁体   English

使用QMake的仅标头和静态构建

[英]Header-only and static build with QMake

I am trying to set up a simple class that can be used both as a header only and static with qmake. 我试图建立一个简单的类,该类既可以用作标题,也可以与qmake一起使用。 I am contolling if the build is static using a macro "STATIC_BUILD" defined in the .pro file. 我正在使用.pro文件中定义的宏“ STATIC_BUILD”来控制构建是否是静态的。

foo.pro: foo.pro:

TEMPLATE = app
CONFIG += c++11

CONFIG += STATIC_BUILD

STATIC_BUILD {
    DEFINES += STATIC_BUILD
}

SOURCES += \
    main.cpp

HEADERS += \
    foo.h

STATIC_BUILD {
    SOURCES += \
        foo.cpp
}

foo.h foo.h

#ifndef FOO_H
#define FOO_H

#ifndef STATIC_BUILD
#define MY_INLINE inline
#else
#define MY_INLINE
#endif

class Foo {
public:
    Foo();

    int getI() const;
    void setI(int value);

private:
    int i;
};

#ifndef STATIC_BUILD
#include "foo.cpp"
#endif

#endif // FOO_H

foo.cpp foo.cpp

#include "foo.h"

MY_INLINE Foo::Foo(){}

MY_INLINE int Foo::getI() const {
    return i;
}

MY_INLINE void Foo::setI(int value) {
    i = value;
}

main.cpp main.cpp

#include <iostream>
#include "foo.h"

int main() {
    Foo f;
    f.setI(3);
    std::cout << f.getI() << "\n";
    return 0;
}

Commenting the line "CONFIG += STATIC_BUILD" in foo.pro and using the class as header only works as expected. 注释foo.pro中的“ CONFIG + = STATIC_BUILD”行并将类用作标头只能按预期工作。 If I compile this project as static (with the line above not commented) I get "undefined reference" for members of "Foo". 如果我将该项目编译为静态(上面的行未注释),则将获得“ Foo”成员的“未定义引用”。

I noticed that, with "CONFIG += STATIC_BUILD" not commented and commenting instead the line 我注意到,未注释“ CONFIG + = STATIC_BUILD”,而是注释了该行

#include "foo.cpp"

in foo.h, everything works correctly (only for the static build, of course). 在foo.h中,一切正常(当然,仅适用于静态构建)。 This does not make any sense to me because the "ifndef" has excactly the purpose to do not "compile" the #include in the static build. 这对我来说没有任何意义,因为“ ifndef”的确切目的是不“编译”静态构建中的#include。

What am I doing wrong? 我究竟做错了什么?

I am using Qt 5.11 with gcc in a linux environment. 我在Linux环境中使用带有gcc的Qt 5.11。

This is a known QMake bug, reported a few times: 这是一个已知的QMake错误,报告了几次:

(warning: unnecessary offensive language in the third bug report) (警告:第三次错误报告中的不必要的冒犯性语言)

In short, the mechanism that skips build for a "source file" found to be mentioned in an #include directive is not smart enough to consider whether the #include directive will actually be executed (that is, it doesn't know about preprocessor conditionals). 简而言之,跳过在#include指令中提到的“源文件”构建的机制不够聪明,无法考虑是否将实际执行#include指令(也就是说,它不了解预处理器条件)。

This is a known qmake "feature." 这是已知的qmake“功能”。 When it sees: 当看到:

#include "foo.cpp"

in the header (regardless of whether it would be "evaluated" or not), it simply doesn't generate build rules for foo.cpp , so it's not getting built. 在标头中(无论是否进行“评估”),它只是不会为foo.cpp生成生成规则,因此不会生成。 Unfortunately, it seems the Qt developers don't view this as a bug, but as a feature. 不幸的是,似乎Qt开发人员并不将其视为错误,而是功能。

The workaround is to create a third file (like foo_incsrc.h ) that only has a single line in it: 解决方法是创建第三个文件(如foo_incsrc.h ),其中只有一行:

#include "foo.cpp"

and change your foo.h accordingly: 并相应地更改您的foo.h

#ifndef STATIC_BUILD
#include "foo_incsrc.h"
#endif

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM