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

时间:2019-06-21 10:40:08

标签: c++ qmake

我正在尝试建立一个简单的类,该类既可以用作标题,也可以与qmake一起使用。我正在使用.pro文件中定义的宏“ STATIC_BUILD”来控制构建是否是静态的。

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

#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

#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

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

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

注释foo.pro中的“ CONFIG + = STATIC_BUILD”行并将类用作标头只能按预期工作。 如果我将该项目编译为静态(上面的行未注释),则将获得“ Foo”成员的“未定义引用”。

我注意到,未注释“ CONFIG + = STATIC_BUILD”,而是注释了该行

#include "foo.cpp"

在foo.h中,一切正常(当然,仅适用于静态构建)。 这对我来说没有任何意义,因为“ ifndef”的确切目的是不“编译”静态构建中的#include。

我在做什么错了?

我在Linux环境中使用带有gcc的Qt 5.11。

2 个答案:

答案 0 :(得分:3)

这是一个已知的QMake错误,报告了几次:

(警告:第三次错误报告中的不必要的冒犯性语言)

简而言之,跳过在#include指令中提到的“源文件”构建的机制还不够聪明,无法考虑实际上是否将执行#include指令(即,它不知道预处理器的条件。)

答案 1 :(得分:2)

这是已知的qmake“功能”。看到的时候:

#include "foo.cpp"
头文件中的

(无论是否进行“评估”),它只是不会为foo.cpp生成构建规则,因此不会被构建。不幸的是,似乎Qt开发人员并没有将其视为错误,而是功能。

解决方法是创建第三个文件(如foo_incsrc.h),其中只有一行:

#include "foo.cpp"

并相应地更改您的foo.h

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