I see that VC++ includes an option called /show include to list you the hierarchy of include files in each translation unit. This seems to be a very helpful option - to optimise/improve the compilation time in a large scale project.
Question
Is there any equivalent option in GNU g++ compiler to get these (similar output)?
gcc -H
will print the names of header files as they are used.
There's a variety of options for controlling this.
-MD will list files, -MMD will list non-system files as side effects of compilation
-M, -MM will generate lists instead of compiling.
-MQ, -MG, -MP and -MT generate makefile target fragments. -MF allows you to specify an output filename.
Related
I have several c++ objects that I'd like to compile using a single target. If possible I'll make a variable in the makefile that list all the object files and then have a single target that compiles them all.
Following this question I have the following "Makefile" so far:
#### Directories and flags
ifndef $(DIR_MAIN)
DIR_MAIN=../..
endif
DIR_EXE=$(DIR_MAIN)
DIR_SRC=$(DIR_MAIN)/src/Analyse_MC
DIR_MISC_SRC=$(DIR_MAIN)/src/Misc
DIR_BLD=$(DIR_MAIN)/build/Analyse_MC
DIR_MISC_BLD=$(DIR_MAIN)/build/Misc
COMP=g++
COMPILE_FLAGS= -std=c++11 -O3 -lstdc++ `pkg-config --cflags eigen3` -msse2 -I${DIR_MISC_SRC}
LINK_FLAGS= -O3 -fopenmp -lgsl -lgslcblas -lm -lhdf5_cpp -lhdf5
OBSERVABLE_OBJECTS=g_decomp_IP_orthog_sphere.o g_decomp_LS_orthog_sphere.o g_decomp_IP_disk.o g_decomp_LS_disk.o find_rank.o eigenvectors.o GramSchmidt.o diagonal_Hamiltonian.o mean_log_WF.o energy.o JK_EP_overlap.o overlap.o geo_mean_eigstate_overlap.o eigstate_overlap.o pair_corr_bins.o
#### Compile all
all: setup observables $(DIR_EXE)/Analyse_MC
setup:
#mkdir -p $(DIR_BLD)
#### Compile observable objects
observables: $(addsuffix -stamp,$(OBSERVABLE_OBJECTS))
%.-stamp : %.o
${COMP} -c -o $# $<
However when running make I get the following:
make: *** No rule to make target `g_decomp_IP_orthog_sphere.o-stamp', needed by `observables'. Stop.
So I've misunderstood something.
If possible I'd also like each of the objects to be updated with changes in .h-files with the name of the object in addition to some common .h-files for all of the objects. Is this possible?
Or do I have to / is it recommended to write a separate target for each object?
EDIT:
Some info about the variables:
DIR_MAIN is defined the way it is because usually this makefile will be called from another makefile which defines DIR_MAIN from its directory using pwd; but ut can also be called on its own from its own directory.
DIR_MISC_SRC points to some header files necessary for the files in DIR_SRC.
DIR_BLD and DIR_MISC_BLD will contain the corresponding resulting object files.
The error message does show you what you've done wrong, but a bit obliquely:
make: *** No rule to make target g_decomp_IP_orthog_sphere.o-stamp, needed by observables. Stop.
Your rule to make stamp files is:
%.-stamp: %.o
You probably wanted that to be
%.o-stamp: %.o
Compiling %.o to %.o-stamp looks very strange to begin with - probably you just want
observables: $(OBSERVABLE_OBJECTS)
.PHONY: observables
Stamp files are sometimes useful for actions you want to perform once but have no output file. For compilation, the object file is the output file, and that's all that make requires.
If possible I'd also like each of the objects to be updated with changes in .h-files with the name of the object in addition to some common .h-files for all of the objects. Is this possible?
That's a whole nother question in itself - you want to search for "makefile auto-dependency generation" for starting points.
Does anyone know how to use gcc to generate all possible binary files from object files ? I know you can use : "gcc -MM" to generate all the .o files for some given source files.
But how would you use gcc to generate all possible binary files from object files
in a project ?
Example: I use "gcc -MM" to generate: a.o, b.o, c.o, d.o
If one were trying to generate a list of binaries files built from each of the .o files like this:
a: b.o c.o d.o
b: a.o c.o d.o
c: a.o b.o d.o
d: a.o b.o b.o
I can do this with a Perl script, but I was just curious if there was some way to do it with gcc
Thanks
Short answer, "no, but..."
gcc -MM can give you foo.o: bar.h because foo.cc contains the directive:
#include "bar.h"
That's easy. But foo.cc can also contain the declaration:
int bar_f1(int);
How can gcc know which object file contains the binary code for this function? Or if there are two object files containing functions with this signature, which it should use? It can't.
...Unless...
Long answer, "yes, if..."
If you refrain from giving source files forward declarations of things in other source files, and also refrain from giving a header file declarations of anything not contained in the corresponding source file, and also give the source file containing int main(...) a fixed name like, say, main.cc, then you can take the output of gcc -MM:
bar.o: bar.h baz.h
foo.o: bar.h
main.o: foo.h zot.h
pan.o: pan.h
zot.o: zot.h
and transform it without too much trouble (using e.g Perl or sed) into:
main: bar.o foo.o zot.o
In theory you could get by without these restrictions(*) by scanning the object files and constructing the dependency tree; this might be equivalent to scanning for the presence of int main(...), segregating those files and linking each of them against all the others, or just listing them, if all you want is a list of possible executables without dependencies (I'm still not sure exactly what you want). These things still require some scripting on your part, I know of no way to do them with gcc alone.
(*)You must still refrain from having two definitions of the same thing.
I am trying to compile a opensource component from source code. I am compiling all C files in that component using gcc command.
When I pass options in order -O2 -Os, binary is in few KB's. But when I pass options in order -Os -O2 binary size is large.
I do know that order matter in case of including sub-directories or Linking libraries in gcc command.
Why order matters for optimization arguments of gcc command ?
I am using gcc version 4.9.1.
Because it's just using the last1 option it sees.
1. From the man page: If you use multiple -O options, with or without level numbers, the last such option is the one that is effective.
From the GCC man page:
If you use multiple -O options, with or without level numbers, the last such option is the one that is effective.
You can't combine -O2 and -Os on the command line.
But here's the description of -Os:
Optimize for size. -Os enables all -O2 optimizations that do not typically increase code size. It also performs further optimizations designed to reduce code size.
Looks like -Os is already doing what you want.
I compiled an .cc file with the following command, which is in Makefile code:
bin/bash ../libtool --silent --tag=CXX --mode=compile g++ -DHAVE_CONFIG_H -I.
-I.. -I../include/ -I.. -g -O2 -MT rtpsession_inet.lo -MD -MP -MF
.deps/rtpsession_inet.Tpo -c -o rtpsession_inet.lo rtpsession_inet.cc
There is a function named rtp_session_rtp_recv in the .cc file. However, it is said that the reference of this function cannot be found when I use the library generated by the Makefile.
So I checked the .o file generated by rtpsession_inet.cc and find that there is not a function named rtp_session_rtp_recv while the function name is changed to _Z20rtp_session_rtp_recvP11_RtpSessionj.
Meanwhile, there are several other functions changes their name, e.g. rtp_session_rtp_send -> _Z20rtp_session_rtp_sendP11_RtpSessionP4msgb.
But functions such as rtp_session_set_remote_addr_full are not changed at all.
What is the additional characters' meaning? How can I deal with this problem?
I compile the file in Linux and use command
nm rtpsession_inet.o
to read the .o file. (All the functions including the one with incorrect name are with T tag, which means the reference exists)
Thanks!
This is called name mangling.
It's for the benefit of the linker. A C++ compiler is able to resolve multiple functions of the same name, based on their argument types. For example, you might have a function called print that takes an int argument, and another that takes a char* argument. The compiler knows which one to generate a call to based on what type of argument you pass to it.
Calls across translation units, though, have to be resolved by the linker, which typically is not aware of C++ overloading rules and has to resolve calls based only on the name. So the C++ compiler decorates the name with enough information to resolve the overload.
The C++ standard doesn't specify how this is done, but if you look at the name you can probably work out how the mangled name is generated.
How can I deal with this problem?
The compiler and linker should resolve calls correctly. What problem are you referring to?
The additional characters are symbol "decorations" added by the compiler and are used to identify the function/method signature, i.e. the return type and the parameters. It helps the runtime determine which one of many functions of the same name (overloading) to invoke in any given invocation.
In Arch Linux PKGBUILD for surf browser, there is:
sed -i 's/CPPFLAGS =/CPPFLAGS +=/g' config.mk
sed -i 's/CFLAGS =/CFLAGS +=/g' config.mk
sed -i 's/LDFLAGS =/LDFLAGS +=/g' config.mk
Why must the flags be changed from
CPPFLAGS = -DVERSION=\"${VERSION}\"
to
CPPFLAGS += -DVERSION=\"${VERSION}\"
I've looked into google, but don't see anything there about this. Can someone please explain and tell me where to read more about these flags?
I did quite a lot of googling and found that this pattern (Surf's is here) seems fairly common in Arch Linux PKGBUILD files. Another example was in DWM's PKGBUILD.
Obviously it is patching the config.mk file so that when make is called, the values are appended to the flags instead of overriding the flags (which must already be set elsewhere). So there must be existing settings that need to be retained. This seems to just be done by default by the package builders so it was hard to find the reason.
Looking further I found this bug report relating to DWM's config.mk file, where the author notes that a version of that file was overriding flags set in makepkg.conf which is the main configuration file for makepkg, which allows tuning compilation settings per machine. This seems like a reasonable explanation for what you found. From that page, a default value for CFLAGS would be something like this:
CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe"
So the patched config.mk file would result in the following when building the package:
CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -std=c99 -pedantic -Wall -Os -I. ....."