11

Is there any way to get the version and vendor of the compiler used by the user through qmake? What I need is to disable building some targets of my project when g++ 3.x is used and enable them when g++ 4.x is used.

Update: Most answers targeted the preprocessor. This is something that I want to avoid. I don't want a target to be build for a specific compiler version and I want this decision to be made by the build system.

tshepang
  • 12,111
  • 21
  • 91
  • 136
Yorgos Pagles
  • 1,836
  • 3
  • 18
  • 29

8 Answers8

15

In addition to ashcatch's answer, qmake allows you to query the command line and get the response back as a variable. So you could to something like this:

linux-g++ {
    system( g++ --version | grep -e "\<4.[0-9]" ) {
        message( "g++ version 4.x found" )
        CONFIG += g++4
    }
    else system( g++ --version | grep -e "\<3.[0-9]" ) {
        message( "g++ version 3.x found" )
        CONFIG += g++3
    }
    else {
        error( "Unknown system/compiler configuration" )
    }
}

Then later, when you want to use it to specify targets, you can use the config scoping rules:

SOURCES += blah blah2 blah3
g++4: SOURCES += blah4 blah5
Community
  • 1
  • 1
Caleb Huitt - cjhuitt
  • 14,785
  • 3
  • 42
  • 49
  • Perfect thanks. I was thinking on doing something like that but thought I 'd ask if there is something that is already supported out of the box. Since there apparently isn't your solution is ready to use :-) – Yorgos Pagles May 03 '09 at 10:49
  • @Caleb: there is a possible simplification if you would use the `gcc -dumpversion` command, which could make grep redundant. May I edit your answer or shall I write another one? – user23573 May 01 '15 at 10:57
  • @BogdanWilli Feel free. – Caleb Huitt - cjhuitt May 01 '15 at 21:12
7

My answer based on Caleb Huitt - cjhuitt's. But his approach does not work for me.

*-g++ {
    GCC_VERSION = $$system("g++ -dumpversion")
    contains(GCC_VERSION, 6.[0-9]) {
        message( "g++ version 6.x found" )
        CONFIG += g++6
    } else {
        contains(GCC_VERSION, 5.[0-9]) {
            message( "g++ version 5.x found" )
            CONFIG += g++5
        } else {
            contains(GCC_VERSION, 4.[0-9]) {
                message( "g++ version 4.x found" )
                CONFIG += g++4
            } else {
                message( "Unknown GCC configuration" )
            }
        }
    }
}

As you see you can get version from GCC and then compare it with regex expression.

The way how to use is the same:

SOURCES += blah blah2 blah3
g++4: SOURCES += blah4 blah5
Community
  • 1
  • 1
dismine
  • 575
  • 13
  • 17
  • 1
    +1 for showing how to check the version once and store the result. Also note that `$$QMAKE_CXX` (for example) will return the full name of current compiler, eg. if cross-compiling. `GCC_VERSION = $$system("$${QMAKE_CXX} -dumpversion")` – Maxim Paperno Jan 18 '19 at 09:04
2

My answer is based on dismine's answer
We can simply extract the major version number using $$str_member

gcc | clang {
    COMPILER_VERSION = $$system($$QMAKE_CXX " -dumpversion")
    COMPILER_MAJOR_VERSION = $$str_member($$COMPILER_VERSION)
    greaterThan(COMPILER_MAJOR_VERSION, 3): message("gcc 4 or later")
    greaterThan(COMPILER_MAJOR_VERSION, 4): message("gcc 5 or later")
    greaterThan(COMPILER_MAJOR_VERSION, 5): message("gcc 6 or later")
    greaterThan(COMPILER_MAJOR_VERSION, 6): message("gcc 7 or later")
}
Eric Lemanissier
  • 357
  • 2
  • 15
  • for older Qt version str_member ist not available, but following worked for me COMPILER_VERSION = $$system($$QMAKE_CXX " -dumpversion") COMPILER_MAJOR_VERSION1 = $$split(COMPILER_VERSION, ".") COMPILER_MAJOR_VERSION = $$first(COMPILER_MAJOR_VERSION1) – Nightingale7 Jul 09 '18 at 19:30
  • fails with gcc10. See Nightingale7's solution using split. – Matthew Eshleman Jun 16 '23 at 15:36
2

As a start, I would look at the scoping feature that qmake supports:

Scopes and Conditions

But while I read about it, it seems that by default you can use general platform conditions like win32 or unix or you can use the name of the qmake spec like linux-g++. You could test the Visual Studio version like this (since the different Visual Studio versions use different qmake specs), but I don't think that you can test the gcc version like this (at least I don't know how).

Community
  • 1
  • 1
ashcatch
  • 2,327
  • 1
  • 18
  • 29
1

I do

isEmpty(MGWVER) {
    MGW_MAJ = $$system(echo | gcc -dM -E - | fgrep __GNUC__ | cut -d\" \" -f 3)
    MGW_MIN = $$system(echo | gcc -dM -E - | fgrep __GNUC_MINOR__ | cut -d\" \" -f 3)
    MGWVER =$$MGW_MAJ$$MGW_MIN
    message(MGWVER $$MGWVER)
}

It returns "48". I use it for linking proper boost libraries:

USER_BOOST_CFG=mgw$${MGWVER}-mt-s-$$(BOOST_VER)
message($$USER_BOOST_CFG)
LIBS *= -L$$(BOOST_ROOT)/lib
LIBS *= -L$$(BOOST_ROOT)/stage/lib

LIBS *= -lboost_system-$$USER_BOOST_CFG
LIBS *= -lboost_filesystem-$$USER_BOOST_CFG
LIBS *= -lboost_date_time-$$USER_BOOST_CFG

effectively giving: -lboost_system-mgw48-mt-s-1_54

I am on mingw.

Another idea is to look at QMAKESPEC vaariable and parse from it, hint:

message(QMAKESPEC $$QMAKESPEC)
SPLITED=$$section(QMAKESPEC, "/", 0, -3)
message(SPLITED $$SPLITED)
Fantastory
  • 1,891
  • 21
  • 25
  • this does not work on Qt 5.4 (selected Kit: Desktop Qt 5.4.1 MinGW 32bit) `fgrep` is not available. – user23573 Apr 30 '15 at 07:02
  • fgrep is not a part of qt. You need http://gnuwin32.sourceforge.net/ . I recomend installing https://chocolatey.org/ and than 'choco install gnuwin' . Everything from command line or script – Fantastory May 01 '15 at 09:52
0

There is an elegant but not so well documented feature as described on topic on QT forum QMAKE_GCC_MAJOR_VERSION and QMAKE_CLANG_MAJOR_VERSION. So in your .pro file you can just write something like:

linux-g++:greaterThan(QMAKE_GCC_MAJOR_VERSION, 8):message( "g++ version 9+ found" )
else:linux-clang:greaterThan(QMAKE_CLANG_MAJOR_VERSION, 13):message( "clang version 14+ found" )

or add some QMAKE_CXXFLAGS, e.g.

linux-g++:greaterThan(QMAKE_GCC_MAJOR_VERSION, 7):QMAKE_CXXFLAGS += -Wno-deprecated-copy

as Robert Hairgrove and Kromignon suggest.

artaxerx
  • 244
  • 1
  • 3
  • 11
0

Each compiler vendor use to define some specific symbols that identify the compiler and version. You could make the check using those symbols.

I know, for example, that _MSC_VER gives the version of Microsoft C++ Compiler.

What I also know is that Boost Libraries use this kind of feature selection and adaptation.

You can take a look to Boost Config headers, found in include folder, at path: boost/config/* , specially at select_compiler_config.hpp.

By using those compiler specific symbols, you can make feature selection at preprocessing phase of building the code.

Cătălin Pitiș
  • 14,123
  • 2
  • 39
  • 62
0

The following macros are defined in my version of gcc and g++

#define __GNUC__ 4 
#define __GNUC_MINOR__ 0
#define __GNUC_PATCHLEVEL__ 1

Additionaly the g++ defines:

#define __GNUG__ 4
Martin York
  • 257,169
  • 86
  • 333
  • 562