0

I have a big autotools project, and one part of codes in the subdirectory use g++-4.9 to compile, others use g++8.2.

My question is how to compile the whole project with different version of g++.

I've see some related question is to change a different g++ compiler, and general answers are to set environment variables or make options.

However, my issue is to compile with both g++8.2 and g++4.9 in same time.

I expect there are some solutions to set Makefile.am like :

noinst_PROGRAMS=foo bar
foo_CXX_COMPILER=/usr/bin/g++-4.9

bar_CXX_COMPILER=/usr/bin/g++-8.2

EDIT:

More Details that I've tried :

  1. The third-party library in the sub-project will show a lot of warnings "auto_ptr is deprecated" when compiling with g++-4.9 -std=c++11, but without any error and executing well.
  2. It compiled well with no error and warning with g++-4.9 -std=c++98.
  3. It yells many errors "undefined reference to ..." when I compile with g++-8.2, even if I add the flag -std=c++98.

I guess this is because g++-8.2 compiler cannot recognize auto_ptr usage!

I prefer to use only one compiler which makes the problem simply! But, if the case cannot be allowed to use only one, I would want to know how to set up Makefile.am with different two compilers, or any best way to solve this compilation problem !

hsuchengmao
  • 524
  • 1
  • 6
  • 14
  • You'll need two different build targets: one for your program (library?) and files it depends on (object files, libraries, etc) built with g++8.2 and one for it built with g++4.9. If you require a build with each compiler, set up another built target that depends on the two compiler-specific builds. – Peter Dec 25 '18 at 09:37
  • 2
    Are you sure you can't build everything with g++8.2? Perhaps by adding some extra options for the targets you think you need v4.9 for? This would be a far more forward-looking solution. – John Bollinger Dec 26 '18 at 02:15
  • @JohnBollinger : My subproject used third-party library ([Hazelcast Client c++](https://github.com/hazelcast/hazelcast-cpp-client#table-of-contents)) should use g++-4.9 or less version according to this [answer](https://groups.google.com/forum/#!searchin/hazelcast/undefined%7Csort:date/hazelcast/6kYc_mQGQwA/SL8TmR1RaD0J). I've tried to compile with g++-8.2, it shows a lot of errors like "undefined reference to ...". While using g++-4.9, it works well. That *Hazelcast Client C++ Library* seems to be an old library ! – hsuchengmao Dec 26 '18 at 02:33
  • 3
    The Google thread you linked to is about Hazelcast not working with a C++ standard library that is too *old*, not too new, and I don't see anything in it about g++4.9 being the limit. It might be worth your while to pose a (separate) question about building Hazelcast with g++ 8.2 if you can't figure it out on your own. Just because you see a lot of errors does not necessarily mean that the solution is complicated. And trying to use different versions of the C++ standard library in the same project is bad news. – John Bollinger Dec 26 '18 at 02:52
  • @eric_hsu: avoid commenting your own question. **Please [edit](https://stackoverflow.com/posts/53920978/edit) your question to improve it.** Mention all the libraries in the question, and explicitly tell us what dialect of C++ they are coded in (C++98, C++14, C++17, ...) – Basile Starynkevitch Dec 27 '18 at 09:09

2 Answers2

4

My question is how to compile the whole project with different version of g++.

It is possible, but I wouldn't recommend it. The GNU Build System doesn't have any support for that, but you might have a look at how AX_CC_FOR_BUILD accomplishes a similar idea (enabling a compiler for build as well as for host).

Idea #2 is what @JohnBollinger suggested -- pick a compiler and build with it. End users of your build will appreciate this more than having to setup two compilers. This is the solution I would go with, since the GNU Build System works this way. g++-8.2 can be told to compile code from previous versions of C++ if the old code can't be modernized for some reason.

Idea #3 is basically to split your project into two autotools projects -- one compiling with the old compiler and one with the new compiler. Not really a fan of this idea either.

ldav1s
  • 15,885
  • 2
  • 53
  • 56
2

I have a big autotools project, and one part of codes in the subdirectory use g++-4.9 to compile, others use g++8.2.

My question is how to compile the whole project with different version of g++.

I don't recommend doing that. The ABI conventions might have changed (so compiling with two different GCCs of different ABIs is IMHO not recommended).

Actually, I recommend building all the project with the same (newest) GCC, that is with g++ 8.2

If some parts of the project are using an different dialect of C++, you could explicitly pass some -std=c++11 or -std=c++17 options to them.

So just configure your project to use the same (and latest) GCC. If some C++ dialects are different, pass a specific flag to it. See options controlling the C++ dialect and -std= option.

At last, you could consider patching the source code of the old library to make it C++14 compliant (in particular, remove every occurrence of auto_ptr and replace them wisely with unique_ptr etc...). In most cases, it is worthwhile to do that (and perhaps a newer version of that old library already exists, which is C++14 or C++17)

Mixing two different versions of the C++ standard library is certainly painful and should be avoided. If you insist trying that, you need to understand painfully all the gory details (so I really recommend not trying this). Then read Drepper's How to write shared libraries paper.

Another approach could be to have your software use two different processes (one for the old C++98 source code, another for the new C++14 code) and use inter-process communication facilities. This is perhaps the most robust solution.

For practical purposes, consider old C++98 and new C++14 as two different, and incompatible, programming languages (C++11 was really different of its predecessors).

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Thanks! I'm sure it should use flag -std=c++11. So if I want to use `g++-8.2` to compile my whole big project, it should add some flags of *Options Controlling C++ Dialect* as you posted. I've simply look it over, and the possible flags I should pass is **-fabi-version=n**, **-fabi-compat-version=n**, and **-Wabi=n**. However, it didn't work on my test, when I set the value of `n` to 2 and 8. Is it a correct way to set it? – hsuchengmao Dec 27 '18 at 04:00
  • I don't know if you need to set that. But probably not. – Basile Starynkevitch Dec 27 '18 at 07:37
  • The third-party library in subproject which compiles well in g++4.9 use the deprecated `auto_ptr`. When I compile with g++8.2 by modifying `-std=option` or *options controlling dialect*, it still shows a lot of error "undefined reference to ...". I guess this is because the deprecated type cannot be compiled in g++-8.2 ! Am I right? If so, I'll take @Idav1s 's first and third suggestions to survey solutions. – hsuchengmao Dec 27 '18 at 08:44
  • You probably need to link wisely (perhaps two different C++ standard libraries) – Basile Starynkevitch Dec 27 '18 at 08:51
  • Thanks for your advice of wisely way to build a c++ project! It's really painful to encounter two compilers in one project. I finally cloned the source code of third-party library to manually build it myself with my default `g++` (8.2). This make my project successfully build in one compiler ! Also, update the library version from 3.10 to 3.11. I'm not sure why this way solved this issue. I guess the original share library that I link may build in `g++4.9`, which cause compilation error in `g++8.2` when linking it. Is that correct ? Anyway, it solved ! – hsuchengmao Dec 28 '18 at 05:36