How to determine compilation flags at compile time on OS/X? - c++

If I compile with -fPIC on x86 Linux with gcc 4.1, then the definition __PIC__ is set to 1 and the preprocessor can act on that at compile time. However, on OS/X under gcc 4.01 that is not the case. Is there some other way to determine the setting of -fPIC at compile time on OS/X?
A general facility for querying compilation flags at the preprocessor level under OS/X would be even more helpful, but I wasn't able to find anything like that.

-fPIC is the default on OS X. gcc 4.0.1 on my crufty old OS X 10.4 machine does define __PIC__; or, when it is explicitly turned off with -fno-PIC, it does not.
The settings of compilation flags are not in general exported to the preprocessor, except for certain special cases, which may vary across different GCC targets.
But you can see the effects of changing flags on the predefined preprocessor definitions, on any platform, using the -dM option to gcc, which dumps the preprocessor definitions after preprocessing is complete.
e.g. from a terminal window:
$ gcc -xc++ -dM -E /dev/null | sort > /tmp/defaults.txt
$ gcc -fno-PIC -xc++ -dM -E /dev/null | sort > /tmp/nopic.txt
$ diff /tmp/defaults.txt /tmp/nopic.txt
65d64
< #define __PIC__ 1
$
(I've specified -xc++ there because I'm preprocessing /dev/null rather than a file with an extension that indicates the language variant. That could also be -xc, -xobjective-c or -xobjective-c++.)

Related

compiling string with GCC fives linker errors [duplicate]

What is the difference between g++ and gcc? Which one of them should be used for general c++ development?
gcc and g++ are compiler-drivers of the GNU Compiler Collection (which was once upon a time just the GNU C Compiler).
Even though they automatically determine which backends (cc1 cc1plus ...) to call depending on the file-type, unless overridden with -x language, they have some differences.
The probably most important difference in their defaults is which libraries they link against automatically.
According to GCC's online documentation link options and how g++ is invoked, g++ is equivalent to gcc -xc++ -lstdc++ -shared-libgcc (the 1st is a compiler option, the 2nd two are linker options). This can be checked by running both with the -v option (it displays the backend toolchain commands being run).
GCC: GNU Compiler Collection
Referrers to all the different languages that are supported by the GNU compiler.
gcc: GNU C      Compiler
g++: GNU C++ Compiler
The main differences:
gcc will compile: *.c\*.cpp files as C and C++ respectively.
g++ will compile: *.c\*.cpp files but they will all be treated as C++ files.
Also if you use g++ to link the object files it automatically links in the std C++ libraries (gcc does not do this).
gcc compiling C files has fewer predefined macros.
gcc compiling *.cpp and g++ compiling *.c\*.cpp files has a few extra macros.
Extra Macros when compiling *.cpp files:
#define __GXX_WEAK__ 1
#define __cplusplus 1
#define __DEPRECATED 1
#define __GNUG__ 4
#define __EXCEPTIONS 1
#define __private_extern__ extern
For c++ you should use g++.
It's the same compiler (e.g. the GNU compiler collection). GCC or G++ just choose a different front-end with different default options.
In a nutshell: if you use g++ the frontend will tell the linker that you may want to link with the C++ standard libraries. The gcc frontend won't do that (also it could link with them if you pass the right command line options).
What is the difference between g++ and gcc?
gcc has evolved from a single language "GNU C Compiler" to be a multi-language "GNU Compiler Collection". The term gcc may still sometimes refer to the "GNU C Compiler" in the context of C programming.
man gcc
# GCC(1) GNU
#
# NAME
# gcc - GNU project C and C++ compiler
However, g++ is the C++ compiler for the GNU Compiler Collection. Like gnat is the Ada compiler for gcc. see Using the GNU Compiler Collection (GCC)
For example, the Ubuntu 16.04 and 18.04 man g++ command returns the GCC(1) manual page.
The Ubuntu 16.04 and 18.04 man gcc states that ...
g++ accepts mostly the same options as gcc
and that the default ...
... use of gcc does not add the C++ library. g++ is a program
that calls GCC and automatically specifies linking against the C++
library. It treats .c, .h and .i files as C++ source files instead of
C source files unless -x is used. This program is also useful when
precompiling a C header file with a .h extension for use in C++
compilations.
Search the gcc man pages for more details on the option variances between gcc and g++.
Which one should be used for general c++ development?
Technically, either gcc or g++ can be used for general C++ development with applicable option settings. However, the g++ default behavior is naturally aligned to a C++ development.
The Ubuntu 18.04 'gcc' man page added, and Ubuntu 20.04 continues to have, the following paragraph:
The usual way to run GCC is to run the executable called gcc, or machine-gcc when cross-compiling, or machine-gcc-version to run a specific version of GCC. When you compile C++ programs, you should invoke GCC as g++ instead.
Side Note: In the case of the Xcode.app embedded toolchain, g++ simply links to gcc. Thus, g++ invocations may vary on a per-toolchain basis.
ls -l /Applications/Xcode.app/Contents/Developer/usr/bin
# …
# lrwxr-xr-x 1 root wheel 3 Apr 27 2021 g++ -> gcc
# -rwxr-xr-x 1 root wheel 167120 Nov 23 20:51 gcc
### -- versus --
which -a g++
# /usr/bin/g++
ls -l /usr/bin/g++
# -rwxr-xr-x 1 root wheel 137616 Jan 1 2020 /usr/bin/g++
One notable difference is that if you pass a .c file to gcc it will compile as C.
The default behavior of g++ is to treat .c files as C++ (unless -x c is specified).
Although the gcc and g++ commands do very similar things, g++ is designed to be the command you'd invoke to compile a C++ program; it's intended to automatically do the right thing.
Behind the scenes, they're really the same program. As I understand, both decide whether to compile a program as C or as C++ based on the filename extension. Both are capable of linking against the C++ standard library, but only g++ does this by default. So if you have a program written in C++ that doesn't happen to need to link against the standard library, gcc will happen to do the right thing; but then, so would g++. So there's really no reason not to use g++ for general C++ development.
I became interested in the issue and perform some experiments
I found that description here, but it is very short.
Then I tried to experiment with gcc.exe and g++.exe on my windows machine:
$ g++ --version | head -n1
g++.exe (gcc-4.6.3 release with patches [build 20121012 by perlmingw.sf.net]) 4.6.3
$ gcc --version | head -n1
gcc.exe (gcc-4.6.3 release with patches [build 20121012 by perlmingw.sf.net]) 4.6.3
I tried to compile c89, c99, and c++1998 simple test files and It's work well for me with correct extensions matching for language
gcc -std=c99 test_c99.c
gcc -std=c89 test_c89.c
g++ -std=c++98 test_cpp.cpp
gcc -std=c++98 test_cpp.cpp
But when I try to run "gnu compiler collection" tool in that fashion:
$ gcc -std=c++98 test_cpp.c
cc1.exe: warning: command line option '-std=c++98' is valid for C++/ObjC++ but not for C [enabled by default]
But this one still work with no errors
$ gcc -x c++ -std=c++98 test_cpp.c
And this also
$ g++ -std=c++0x test_cpp_11.cpp
p.s. Test files
$ cat test_c89.c test_c99.c test_cpp.cpp
// C89 compatible file
int main()
{
int x[] = {0, 2};
return sizeof(x);
}
// C99 compatible file
int main()
{
int x[] = {[1]=2};
return sizeof(x);
}
// C++1998,2003 compatible file
class X{};
int main()
{
X x;
return sizeof(x);
}
// C++11
#include <vector>
enum class Color : int{red,green,blue}; // scoped enum
int main()
{
std::vector<int> a {1,2,3}; // bracket initialization
return 0;
}
Findings:
If look at process tree then it seems that gcc, and g++ is backend to other tools, which in my environment are: cc1plus.exe, cc1.exe, collect2.exe, as.exe, ld.exe
gcc works fine as metatool for if you have correct extension or set correct
-std -x flags. See this
“GCC” is a common shorthand term for the GNU Compiler Collection. This is both the most general name for the compiler, and the name used when the emphasis is on compiling C programs (as the abbreviation formerly stood for “GNU C Compiler”).
When referring to C++ compilation, it is usual to call the compiler “G++”. Since there is only one compiler, it is also accurate to call it “GCC” no matter what the language context; however, the term “G++” is more useful when the emphasis is on compiling C++ programs.
You could read more here.
I was testing gcc and g++ in a linux system. By using MAKEFILE, I can define the compliler used by "GNU make". I tested with the so called "dynamic memory" locating feature of "C plus plus" by :
int main(){
int * myptr = new int;
* myptr = 1;
printf("myptr[0] is %i\n",*myptr);
return 0;
}
Only g++ can successfully compile on my computer while gcc will report error
undefined reference to `operator new(unsigned long)'
So my own conclusion is gcc does not fully support "C plus plus". It seems that choosing g++ for C++ source files is a better option.
gcc and g ++ are both GNU compiler. They both compile c and c++. The difference is for *.c files gcc treats it as a c program, and g++ sees it as a c ++ program. *.cpp files are considered to be c ++ programs. c++ is a super set of c and the syntax is more strict, so be careful about the suffix.

gcc-11 macOS doesn't compile [duplicate]

What is the difference between g++ and gcc? Which one of them should be used for general c++ development?
gcc and g++ are compiler-drivers of the GNU Compiler Collection (which was once upon a time just the GNU C Compiler).
Even though they automatically determine which backends (cc1 cc1plus ...) to call depending on the file-type, unless overridden with -x language, they have some differences.
The probably most important difference in their defaults is which libraries they link against automatically.
According to GCC's online documentation link options and how g++ is invoked, g++ is equivalent to gcc -xc++ -lstdc++ -shared-libgcc (the 1st is a compiler option, the 2nd two are linker options). This can be checked by running both with the -v option (it displays the backend toolchain commands being run).
GCC: GNU Compiler Collection
Referrers to all the different languages that are supported by the GNU compiler.
gcc: GNU C      Compiler
g++: GNU C++ Compiler
The main differences:
gcc will compile: *.c\*.cpp files as C and C++ respectively.
g++ will compile: *.c\*.cpp files but they will all be treated as C++ files.
Also if you use g++ to link the object files it automatically links in the std C++ libraries (gcc does not do this).
gcc compiling C files has fewer predefined macros.
gcc compiling *.cpp and g++ compiling *.c\*.cpp files has a few extra macros.
Extra Macros when compiling *.cpp files:
#define __GXX_WEAK__ 1
#define __cplusplus 1
#define __DEPRECATED 1
#define __GNUG__ 4
#define __EXCEPTIONS 1
#define __private_extern__ extern
For c++ you should use g++.
It's the same compiler (e.g. the GNU compiler collection). GCC or G++ just choose a different front-end with different default options.
In a nutshell: if you use g++ the frontend will tell the linker that you may want to link with the C++ standard libraries. The gcc frontend won't do that (also it could link with them if you pass the right command line options).
What is the difference between g++ and gcc?
gcc has evolved from a single language "GNU C Compiler" to be a multi-language "GNU Compiler Collection". The term gcc may still sometimes refer to the "GNU C Compiler" in the context of C programming.
man gcc
# GCC(1) GNU
#
# NAME
# gcc - GNU project C and C++ compiler
However, g++ is the C++ compiler for the GNU Compiler Collection. Like gnat is the Ada compiler for gcc. see Using the GNU Compiler Collection (GCC)
For example, the Ubuntu 16.04 and 18.04 man g++ command returns the GCC(1) manual page.
The Ubuntu 16.04 and 18.04 man gcc states that ...
g++ accepts mostly the same options as gcc
and that the default ...
... use of gcc does not add the C++ library. g++ is a program
that calls GCC and automatically specifies linking against the C++
library. It treats .c, .h and .i files as C++ source files instead of
C source files unless -x is used. This program is also useful when
precompiling a C header file with a .h extension for use in C++
compilations.
Search the gcc man pages for more details on the option variances between gcc and g++.
Which one should be used for general c++ development?
Technically, either gcc or g++ can be used for general C++ development with applicable option settings. However, the g++ default behavior is naturally aligned to a C++ development.
The Ubuntu 18.04 'gcc' man page added, and Ubuntu 20.04 continues to have, the following paragraph:
The usual way to run GCC is to run the executable called gcc, or machine-gcc when cross-compiling, or machine-gcc-version to run a specific version of GCC. When you compile C++ programs, you should invoke GCC as g++ instead.
Side Note: In the case of the Xcode.app embedded toolchain, g++ simply links to gcc. Thus, g++ invocations may vary on a per-toolchain basis.
ls -l /Applications/Xcode.app/Contents/Developer/usr/bin
# …
# lrwxr-xr-x 1 root wheel 3 Apr 27 2021 g++ -> gcc
# -rwxr-xr-x 1 root wheel 167120 Nov 23 20:51 gcc
### -- versus --
which -a g++
# /usr/bin/g++
ls -l /usr/bin/g++
# -rwxr-xr-x 1 root wheel 137616 Jan 1 2020 /usr/bin/g++
One notable difference is that if you pass a .c file to gcc it will compile as C.
The default behavior of g++ is to treat .c files as C++ (unless -x c is specified).
Although the gcc and g++ commands do very similar things, g++ is designed to be the command you'd invoke to compile a C++ program; it's intended to automatically do the right thing.
Behind the scenes, they're really the same program. As I understand, both decide whether to compile a program as C or as C++ based on the filename extension. Both are capable of linking against the C++ standard library, but only g++ does this by default. So if you have a program written in C++ that doesn't happen to need to link against the standard library, gcc will happen to do the right thing; but then, so would g++. So there's really no reason not to use g++ for general C++ development.
I became interested in the issue and perform some experiments
I found that description here, but it is very short.
Then I tried to experiment with gcc.exe and g++.exe on my windows machine:
$ g++ --version | head -n1
g++.exe (gcc-4.6.3 release with patches [build 20121012 by perlmingw.sf.net]) 4.6.3
$ gcc --version | head -n1
gcc.exe (gcc-4.6.3 release with patches [build 20121012 by perlmingw.sf.net]) 4.6.3
I tried to compile c89, c99, and c++1998 simple test files and It's work well for me with correct extensions matching for language
gcc -std=c99 test_c99.c
gcc -std=c89 test_c89.c
g++ -std=c++98 test_cpp.cpp
gcc -std=c++98 test_cpp.cpp
But when I try to run "gnu compiler collection" tool in that fashion:
$ gcc -std=c++98 test_cpp.c
cc1.exe: warning: command line option '-std=c++98' is valid for C++/ObjC++ but not for C [enabled by default]
But this one still work with no errors
$ gcc -x c++ -std=c++98 test_cpp.c
And this also
$ g++ -std=c++0x test_cpp_11.cpp
p.s. Test files
$ cat test_c89.c test_c99.c test_cpp.cpp
// C89 compatible file
int main()
{
int x[] = {0, 2};
return sizeof(x);
}
// C99 compatible file
int main()
{
int x[] = {[1]=2};
return sizeof(x);
}
// C++1998,2003 compatible file
class X{};
int main()
{
X x;
return sizeof(x);
}
// C++11
#include <vector>
enum class Color : int{red,green,blue}; // scoped enum
int main()
{
std::vector<int> a {1,2,3}; // bracket initialization
return 0;
}
Findings:
If look at process tree then it seems that gcc, and g++ is backend to other tools, which in my environment are: cc1plus.exe, cc1.exe, collect2.exe, as.exe, ld.exe
gcc works fine as metatool for if you have correct extension or set correct
-std -x flags. See this
“GCC” is a common shorthand term for the GNU Compiler Collection. This is both the most general name for the compiler, and the name used when the emphasis is on compiling C programs (as the abbreviation formerly stood for “GNU C Compiler”).
When referring to C++ compilation, it is usual to call the compiler “G++”. Since there is only one compiler, it is also accurate to call it “GCC” no matter what the language context; however, the term “G++” is more useful when the emphasis is on compiling C++ programs.
You could read more here.
I was testing gcc and g++ in a linux system. By using MAKEFILE, I can define the compliler used by "GNU make". I tested with the so called "dynamic memory" locating feature of "C plus plus" by :
int main(){
int * myptr = new int;
* myptr = 1;
printf("myptr[0] is %i\n",*myptr);
return 0;
}
Only g++ can successfully compile on my computer while gcc will report error
undefined reference to `operator new(unsigned long)'
So my own conclusion is gcc does not fully support "C plus plus". It seems that choosing g++ for C++ source files is a better option.
gcc and g ++ are both GNU compiler. They both compile c and c++. The difference is for *.c files gcc treats it as a c program, and g++ sees it as a c ++ program. *.cpp files are considered to be c ++ programs. c++ is a super set of c and the syntax is more strict, so be careful about the suffix.

Use CXX to query preprocessor defines?

I have a GNUmakefile that respects CXX and CXXFLAGS. It also performs some platform and architecture tests. Currently, the makefile assumes the host and target are the same:
IS_X86 = $(shell uname -m | $(EGREP) -c "i.86|x86|i86|amd64")
In an effort to improve robustness, I want to ask the tools what it is compiling for. I've come up with the following, but I'm not sure it is correct.
$ export CXX=clang++
$ export CXXFLAGS="-DNDEBUG -g2 -O3 -m32"
$ $CXX $CXXFLAGS -dM -E - < /dev/null | egrep "(i386|x86_64)"
#define __i386 1
#define __i386__ 1
#define i386 1
$ export CXX=clang++
$ export CXXFLAGS="-DNDEBUG -g2 -O3"
$ $CXX $CXXFLAGS -dM -E - < /dev/null | egrep "(i386|x86_64)"
#define __x86_64 1
#define __x86_64__ 1
My question is, will the above - with CXX and CXXFLAGS - work reliably to detect a target? Or do I need something else?
Here's the two reasons I ask. First, my experience with Autotools indicates something different. When Autotools performs a test like above, they test CPP, and sometimes CPP or CXX needs to include --isysroot (or other hacks) to get things configured properly.
Second, some toolchains, like Clang, integrate other components (like a preprocessor or assembler), so I can't use CPP directly under all circumstances.
In fact, doing something as simple as $CXX -Wa,-v - </dev/null (ask assembler for its version) results in an "unsupported option" error under Clang when using its integrated assembler. (Cf., With integrated assembler enabled, fail to fetch version string of assembler).
And just in case: this is not an Autools or Cmake project. It does not use Boost or any other libraries. Its a stand alone C++03 project.
My question is, will the above - with CXX and CXXFLAGS - work reliably to detect a target?
The answer is Yes, it will. The preprocessor or compielr driver (passing down to preprocessor) will mostly yield expected target defines with all else being equal. Notable exception is GCC and ARMv8/Aarch64, which is missing a slew of expected defines.
The thing to avoid is uname -m (and friends). Uname reports information on the host, and not the target.

What are some of the most commonly used gcc/g++ flags for information (not just optimization)

I have found -E very useful to see preprocessor output and debug macros, and I have seen -fdump-class-hierarchy to look at the v-tables of a class hierarchy...I know there are flags to dump asm output as well..what are some other widely (or perhaps a bit unknown but very handy) flags akin to these?
Few flags which I like:
-x language: used to compile file with extension other than .c or .cpp
-s - dump asm.
-g - debug build.
gcc -O3 -Q --help=optimizers | grep disabled - will give you all optimization flags which remain diabled even after -O3
Wonderful place for all wonderful options

Compiling previously preprocessed file changes output

I have a source file which I preprocess using the options -E and -P (using GCC 4.1.2 for a vxWorks-based embedded platform). All other options are the same as when I compile the file. These options are:
-Wall
-march=pentium
-nostdinc
-O0
-fno-builtin
-fno-defer-pop
-g
-c
-o
as well as all include-paths. Now when I compile this preprocessed file, the resulting object-file is much smaller (about 30%) than when I compile the original directly. And when I then link the program, the linker complains about missing symbols (all in user-code), which again does not happen when using the original source-file. Why is there a difference? Is there any way to make this work?
You're sure you're not missing any -D defines from your command line? Your result would be consistent with parts not being compiled due to conditionals.
Another possibility (since you don't name the compiler specifically) is that you're using a generic gcc -E rather than the arch-specific cross compiler for your vxWorks environment. The cross-gcc will predefine some variables that you'll need for gcc -E.
When compiling the preprocessed output, try passing the -fpreprocessed option to tell GCC not to preprocess again.
The only difference I can think of is macros that result in expanding to an identifier that's a macro name that has already been expanded - the preprocessor stops expansion at that point, but if you ran the preprocessor again, the identifier would be expanded again. I would have expected any instances of this to probably cause a compiler error, but who knows?