Specifying go build's version of C++ - c++

I'm trying to build a go project that uses a third party library (GDAL) that's written in C and C++. I've run into this error:
In file included from contour.cpp:31:0:
cpl_port.h:187:6: error: #error Must have C++11 or newer.
# error Must have C++11 or newer.
^
In file included from C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/type_traits:35:0,
from cpl_conv.h:372,
from contour.cpp:39:
C:/TDM-GCC-64/lib/gcc/x86_64-w64-mingw32/5.1.0/include/c++/bits/c++0x_warning.h:32:2: error: #error This file requires compiler and library support for the ISO C++ 2011 standard. This support is currently experimental, and must be enabled with the -std=c++11 or -std=gnu++11 compiler options.
#error This file requires compiler and library support for the \
^
Some searching tells me this is expected, and the fix is to simply set a flag on the compiler (not go related, but still pertinent).
I've read through go's documentation on building, and while it suggests it's possible to specify options to individual compilers, it doesn't explicitly spell out how, nor does it provide any examples.
I've tried the following just guessing, and while the go build command accepts them, they produce the same error, so they don't work.
go build -gcflags -std=gnu++11 -ldflags -std=gnu++11
go build -gcflags -std=c++11 -ldflags -std=c++11
go build -gcflags -std=c++11
go build -gcflags -std=all=gnu++11 -ldflags -std=all=gnu++11
How can I tell go to tell gcc to compile with C++11 or newer?
Edit: As requested by PeterSO:
H:\>go version
go version go1.10.2 windows/amd64
H:\>go env
set GOARCH=amd64
set GOBIN=
set GOCACHE=C:\Users\ksexton\AppData\Local\go-build
set GOEXE=.exe
set GOHOSTARCH=amd64
set GOHOSTOS=windows
set GOOS=windows
set GOPATH=H:\ksexton\Go;
set GORACE=
set GOROOT=C:\Go
set GOTMPDIR=
set GOTOOLDIR=C:\Go\pkg\tool\windows_amd64
set GCCGO=gccgo
set CC=gcc
set CXX=g++
set CGO_ENABLED=1
set CGO_CFLAGS=-g -O2
set CGO_CPPFLAGS=
set CGO_CXXFLAGS=-g -O2
set CGO_FFLAGS=-g -O2
set CGO_LDFLAGS=-g -O2
set PKG_CONFIG=pkg-config
set GOGCCFLAGS=-m64 -mthreads -fmessage-length=0 -fdebug-prefix-map=C:\Users\ksexton\AppData\Local\Temp\go-build937852322=/tmp/go-build -gno-record-gcc-switches
H:\>gcc --version
gcc (tdm64-1) 5.1.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
H:\>g++ --version
g++ (tdm64-1) 5.1.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Command cgo
Using cgo with the go command
All the cgo CPPFLAGS and CFLAGS directives in a package are
concatenated and used to compile C files in that package. All the
CPPFLAGS and CXXFLAGS directives in a package are concatenated and
used to compile C++ files in that package. All the CPPFLAGS and FFLAGS
directives in a package are concatenated and used to compile Fortran
files in that package. All the LDFLAGS directives in any package in
the program are concatenated and used at link time. All the pkg-config
directives are concatenated and sent to pkg-config simultaneously to
add to each appropriate set of command-line flags.
On Windows:
set CGO_CXXFLAGS=-std=c++11

Related

Can't cross-compile gdb with MinGW

I'm trying to cross-compile gdb so I could debug my Windows version of program.
My host system is Arch Linux(5.13.4-arch1-1 to be exact).
I'm using MinGW from the official repositories.
$ i686-w64-mingw32-gcc --version
i686-w64-mingw32-gcc (GCC) 11.2.0
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
I downloaded the source for gdb from https://ftp.gnu.org/gnu/gdb/ (gdb-10.2.tar.gz).
I unpacked it, cd into dir and ran:
$ ./configure --host=i686-w64-mingw32
$ make
For long it compiled without any errors and then:
CXX source-cache.o
source-cache.c:37:10: fatal error: srchilite/sourcehighlight.h: No such file or directory
37 | #include <srchilite/sourcehighlight.h>
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
And also although compiler already compiled gdbserver and other different programs, I can't run them.
Launching gdbserver.exe with wine gives:
$ wine gdbserver.exe
0024:err:module:import_dll Library libgcc_s_dw2-1.dll (which is needed by L"Z:\\home\\udalny\\.local\\build\\gdb\\gdb-10.2\\gdbserver\\gdbserver.exe") not found
0024:err:module:import_dll Library libstdc++-6.dll (which is needed by L"Z:\\home\\udalny\\.local\\build\\gdb\\gdb-10.2\\gdbserver\\gdbserver.exe") not found
0024:err:module:LdrInitializeThunk Importing dlls for L"Z:\\home\\udalny\\.local\\build\\gdb\\gdb-10.2\\gdbserver\\gdbserver.exe" failed, status c0000135
Is it not statically linked?
Does anybody know how to fix it?
You can avoid the problem with the configure flag --disable-source-highlight if you can do without sourxe highlighting.

Cannot cross-compile for arm with c++17

I am trying to cross-compile c++14/c++17 code for my raspberry pi. I am sure it worked on my old PC. However, when I try to compile it on my new pc, it returns me the following error.
$ arm-linux-gnueabihf-g++ main.cpp -std=c++17
arm-linux-gnueabihf-g++: error: unrecognized command line option ‘-std=c++17’
I thought it is the compiler issue, the version of the compiler I am using is:
$ arm-linux-gnueabihf-g++ --version
arm-linux-gnueabihf-g++ (crosstool-NG linaro-1.13.1+bzr2650 - Linaro GCC 2014.03) 4.8.3 20140303 (prerelease)
Copyright (C) 2013 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
I try to get the newest compiler with
sudo apt-get install libc6-armel-cross libc6-dev-armel-cross binutils-arm-linux-gnueabi libncurses5-dev build-essential bison flex libssl-dev bc
Yet, the version is still the same, which can only compile c++11.
How can I update the arm-linux-gnueabi-g++ compiler?? I am pretty sure there is a compiler that works since I used it before, but not sure how I get it.
I found the easiest way to solve this issue is to directly install the newest cross-compiler
sudo apt-get install g++-9-arm-linux-gnueabihf
and use the compiler as (just an example of using c++17)
arm-linux-gnueabihf-g++-9 main.cpp -std=c++17

How to meet the C++ standards version in my g++ compiler?

I know C++ has standards and not versions, therefore, their releases are managed by specifications (like C99, C++11, between others)
The C++ compilers have versions, and a each version can support multiple c++ standards ... Is this right?
In relation to above, I found my g++ version compiler, which is 7.2.0
λ bgarcial [~] → g++ --version
g++ (Ubuntu 7.2.0-8ubuntu3) 7.2.0
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
λ bgarcial [~] →
I have the following directory of my g++ compiler, I am using native makefiles to build in C++ language
λ bgarcial [include/c++/7] → pwd
/usr/include/c++/7
λ bgarcial [include/c++/7] →
How to can I determine which C++ standards that are supported my g++ compiler?
The g++ documentation includes the following information:
GCC supports the original ISO C++ standard published in 1998, and the 2011 and 2014 revisions. The default, if no C++ language dialect options are given, is -std=gnu++14.
It also contains this interesting bit:
By default, GCC also provides some additional extensions to the C++ language that on rare occasions conflict with the C++ standard. See Options Controlling C++ Dialect. Use of the -std options listed above disables these extensions where they they conflict with the C++ standard version selected.
You may also select an extended version of the C++ language explicitly with -std=gnu++98 (for C++98 with GNU extensions), or -std=gnu++11 (for C++11 with GNU extensions), or -std=gnu++14 (for C++14 with GNU extensions), or -std=gnu++1z (for C++1z with GNU extensions).
In a given C++ project, how can I specify what C++ standard/specification type to use?
In the CMakeLists.txt may be? or ...
As a flag building some basic file? such as the following:
g++ client.cpp main.cpp -o client.out -lzmq -std=gnu++11
What is the recommended C++ standard/specification.
I ask this because in first instance I assume that I am using C++14 with GNU extensions in relation to g++ compiler documentation previously referenced above.
In some cases, I am not using some functions or libraries but I don't know if this is due to the standard used or something else.
What is the recommended C++ standard to use and how can I configure my project to use it?
You can specify the standard with the -std switch
$g++ -std=c++11 your_file.cpp -o your_program

Automatically select a C++11-compatible g++ version in the Makefile

The problem:
2 version of g++ installed on a computer running Ubuntu 12.04. They are the versions 4.6 and 5.2.
I have to compile a C++11 program using a Makefile. If I use g++ as compiler it calls automatically the version 4.6, it does not support c++11 so the compilation fails. I've followed a tutorial online, so that now if I call g++ it calls automatically the version 5.2 and now it works.
I find this solution not so good, since it works only on my PC. Is there a way to recognize in the Makefile if the default g++ version support C++11 and, in case not, switch to a more recent version?
Thank you!
Is there a way to recognize in the Makefile if the default g++ version support C++11 and, in case not, switch to a more recent version?
You can certainly detect the version of the default compiler available in PATH in your makefile. However, where do you search for another version?
The standard approach is to let the user specify the C compiler through CC and C++ compiler through CXX make variables, e.g.: make CC=/path/to/my/gcc CXX=/path/to/my/g++.
You can always select which gcc to use while invoking make
make CXX=/gcc/path/of/your/choice
otherwise you can detect gcc version using
ifdef CXX
GCC_VERSION = $(shell $(CXX) -dumpversion)
else
GCC_VERSION = $(shell g++ -dumpversion)
endif
in Makefile and while using, you can test if your gcc is >=4.6
ifeq ($(shell expr $(GCC_VERSION) '>=' 4.6), 1)
UPDATE: newer gcc needs -dumpfullversion together (icx is the CC from Intel OneAPI)
$ icx -dumpversion
14.0.0
$ gcc -dumpversion
9
$ icx -dumpfullversion -dumpversion
14.0.0
$ gcc -dumpfullversion -dumpversion
9.3.1
One very simple way is to use conditional statements in your makefile, and go for versions which you know are compatible, and only use the default gcc as a fallback. Here's a basic example:
CXX=g++
ifeq (/usr/bin/g++-4.9,$(wildcard /usr/bin/g++-4.9*))
CXX=g++-4.9
# else if... (a list of known-to-be-ok versions)
endif
The other, more robust method, is to generate your makefile using a script that checks for capabilities using test compilations, kind of like what ./configure usually does. I really don't mean to recommend autotools, though.
The thing to do is build your Makefile to use as many implicit rules as possible. By default compilation uses various environment variables.
The variable $(CXX) is the C++ compiler command and defaults to g++ on Linux systems. So clanging CXX to a different compiler executable will change the compiler for all implicit compile commands.
When you write explicit rules use the same variable that the implicit rules use. So instead of this:
program: program.cpp
g++ -o program program.cpp
Do this:
program: program.cpp
$(CXX) -o program program.cpp
Other variables you should use are:
CPPFLAGS = -Iinclude
CXXFLAGS = -std=c++14 -g3 -O0
Those are for pre-processing flags CPPFLAGS and compiler flags CXXFLAGS and library linking flags LDLIBS.
Using the default environment variables allows the person compiling the project the freedom to control the compilation for their desired environment.
See the GNU make manual
This works for me:
cmake_minimum_required(VERSION 2.8.11)
project(test)
if (${CMAKE_CXX_COMPILER_VERSION} LESS 5.0)
message(FATAL_ERROR "You need a version of gcc > 5.0")
endif (${CMAKE_CXX_COMPILER_VERSION} LESS 5.0)
add_executable(test test.cpp)
You can check in your source code the gcc version and abort compilation if you don't like it. Here is how it works:
/* Test for GCC > 4.6 */
#if !(__GNUC__ > 3 && __GNUC_MINOR__ > 6)
#error gcc above version 4.6 required!
#endif

OS X Yosemite gcc unrecognized command line option 'mdll' after brew install gcc

I installed gcc using brew because I needed to install brew's Fortran package. It seems that the gcc package installed by brew install gcc does not support the mdll flag. How can I install the correct versions of Fortran and gcc?
$ which gcc
/usr/local/bin/gcc
$ gcc --version
gcc (GCC) 4.9.2 20141029 (prerelease)
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$ gcc -mdll
gcc: error: unrecognized command line option ‘-mdll’
gcc: fatal error: no input files
compilation terminated.
According to the gcc(1) manpage:
-mdll
This option is available for Cygwin and MinGW targets. It
specifies that a DLL---a dynamic link library---is to be generated,
enabling the selection of the required runtime startup object and
entry point.
Since OS X isn't either Cygwin or MinGW, it's safe to assume that no version of GCC will enable it on OS X.
If you're trying to build a dynamically linked object ("shared object" in UNIX terminology), check out the -dynamic/-dynamiclib flags. They seem to be the rough equivalent on OS X.