Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compiler.pri: improve modern C++ detection #2630

Merged
merged 2 commits into from
Nov 13, 2016

Conversation

mkrautz
Copy link
Contributor

@mkrautz mkrautz commented Nov 8, 2016

This PR adds a cplusplus.pri file (which gets included by compiler.pri).

Its purpose is to handle selection of C++ standards at build time via qmake's CONFIG variable.

Builders can now specify, say, qmake -recursive -Wall main.pro CONFIG+="release c++11" to select C++ mode.

Besides the ability to explicitly select a C++ standard, cplusplus.pri will auto-detect an appropriate C++ standard for the current system.

Supercedes PRs #2608 and #2628

@mkrautz
Copy link
Contributor Author

mkrautz commented Nov 8, 2016

Can't properly document this for now (other than the code comments).
Feel free to take a look. Will add more docs (commit subjects, commit body, PR description) later.

@mkrautz mkrautz mentioned this pull request Nov 8, 2016
# But Qt 4 won't, so we add it manually.
lessThan(QT_MAJOR_VERSION, 5) {
QMAKE_CXXFLAGS *= -std=c++11
# First, auto-populate CONFIG with the latest C++ standard
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These checks should probably go outside the unix{} block.

Copy link
Contributor

@EmperorArthur EmperorArthur left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's the best I've seen so far for dealing with all C++ variants, but it has a few failure modes, that should probably be addressed.

}
CONFIG(c++1z) {
QMAKE_CXXFLAGS += -std=c++1z
QMAKE_LFLAGS += -std=c++1z
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This section won't work if more than one CONFIG option is set. g++ doesn't like having multiple -std=... lines passed to it.

If QT is compiled with support for more than one of these, then more than one CONFIG option is set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in latest revision.

contains(QT_CONFIG, c++11): CONFIG *= c++11
contains(QT_CONFIG, c++14): CONFIG *= c++14
contains(QT_CONFIG, c++1z): CONFIG *= c++1z
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If QT is compiled with support for more than one of these, then more than one CONFIG option is set.

This causes compile errors in the lessThan(QT_MAJOR_VERSION, 5) { block.

If qmake has a break statement, I would suggest putting breaks in between each of these lines. If not, you are going to have to separate this out into three blocks.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in latest revision.

# populate QMAKE_CXXFLAGS and QMAKE_LFLAGS with the
# appproiate -std=c++XX flags. So, for Qt 4, we'll
# have to set them up manually.
lessThan(QT_MAJOR_VERSION, 5) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This comment and check are, unfortunately, incorrect.

Qt 5 does not populate QMAKE_CXXFLAGS with any -std=c++XX.

You can see for yourself by adding this right before/after the check:

message("QMAKE_CXXFLAGS=$${QMAKE_CXXFLAGS}")

If we want mumble to build on GCC 6.0 and older with Qt 5.7 or later, we're going to have to manually set QMAKE_CXXFLAGS.

I'd recommend removing the check altogether.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm pretty sure I checked that this was the case.
They should be populated via the default_post.prf qmake feature file.
See: https://github.com/qt/qtbase/blob/1e97037ed97aade9eb107bbc595785c2de76f7dc/mkspecs/features/default_post.prf#L98

But I'll double-check.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And, the reason you can't print them via message is because they're populated after processing the application's .pro file.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I finally had a chance to test this on a Linux box.

Qt 5.6.1 on my Debian stretch install does in fact pass -std=gnu++1z.

@mkrautz
Copy link
Contributor Author

mkrautz commented Nov 11, 2016

@EmperorArthur PTAL

# The expectation is that this is a general convention,
# so add it to our library search path in C++11, C++14
# and C++1z mode.
CONFIG(c++11):CONFIG(c++14):CONFIG(c++1z) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be ORs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed.

unix {
# Qt 4, as opposed to Qt 5, doesn't automatically
# populate QMAKE_CXXFLAGS and QMAKE_LFLAGS with the
# appproiate -std=c++XX flags. So, for Qt 4, we'll
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

typo appproiate -> appropriate

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

Copy link
Member

@Kissaki Kissaki left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typo in commit message: "Wile" -> "While"

@mkrautz
Copy link
Contributor Author

mkrautz commented Nov 11, 2016

Typo in commit message: "Wile" -> "While"

Done.

@mkrautz
Copy link
Contributor Author

mkrautz commented Nov 11, 2016

Hmmm, seems like the QT_CONFIG checks aren't working on my Debian stretch system. (Qt 5.6) They work on Arch, though. (Qt 5.7) Testing...

@mkrautz
Copy link
Contributor Author

mkrautz commented Nov 11, 2016

OK, the problem is that mkspecs/features/qt_module_headers.prf will add -std=c++98 if CONFIG(c++11) isn't set... So it seems we'll have to add c++11 for all standards above c++11... Hmmm...

@mkrautz
Copy link
Contributor Author

mkrautz commented Nov 11, 2016

Hmmm, seems like the QT_CONFIG checks aren't working on my Debian stretch system. (Qt 5.6) They work on Arch, though. (Qt 5.7) Testing...

[...]

OK, the problem is that mkspecs/features/qt_module_headers.prf will add -std=c++98 if CONFIG(c++11) isn't set... So it seems we'll have to add c++11 for all standards above c++11... Hmmm...

Fixed in latest upload.

@mkrautz
Copy link
Contributor Author

mkrautz commented Nov 11, 2016

PTAL

# First, auto-populate CONFIG with the latest C++ standard
# that Qt has detected support for.
!CONFIG(c++03):!CONFIG(c++11):!CONFIG(c++14):!CONFIG(c++1z) {
# For the c++1z and c++14 below, we also add
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"For the c++1z and c++14 cases below"

maybe?

#
# For example, Qt 5.6's
# mkspecs/features/qt_module_headers.prf
# will automatically add -std=c++98 to CXXFLAGS
Copy link
Contributor Author

@mkrautz mkrautz Nov 11, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

file will

maybe?

# The result is that if we ONLY put c++1z in
# CONFIG, that check will cause us to have
# *both* -std=c++98 *and* -std=gnu++1z in
# CXXFLAGS, which is bad.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CXXFLAGS when building on Qt 5.6, which is bad.

#
# In order to be compatible with such checks,
# ensure that we have all prior "modern"
# standards in CONFIG, to please Qt.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

standards -> # C++ standards

@EmperorArthur
Copy link
Contributor

Looks good to me.

This commit adds a cplusplus.pri file that allows users
to pass 'c++03', 'c++11', 'c++14' or 'c++1z' in CONFIG
when building Mumble via qmake.

For example, to explicitly build Mumble in c++1z mode,
one would use:

    $ qmake -recursive -Wall main.pro CONFIG+="release c++1z"

While it is possible to explicitly specify a target C++ standard
when building Mumble, the cplusplus.pri will auto-detect an
appropriate C++ standard to target for the system it is building
on.
In the past, Debian stretch put C+11 ZeroC Ice
libraries in a special C++11-specific library
search path.

Since it doesn't hurt to look there, keep this
around, even though it's probably not needed
anymore.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants