gcc not linking symbols from .o into application - g++

I'm trying to link a c++ .o file into an application (also c++). Here is the build line:
g++ -o ../objs/armv5sfLinux3.2gcc4.6.2.EV3/Touch_publisher ../objs/armv5sfLinux3.2gcc4.6.2.EV3/Touch_publisher.o ../objs/armv5sfLinux3.2gcc4.6.2.EV3/EV3_Touch.o ../objs/armv5sfLinux3.2gcc4.6.2.EV3/EV3_TouchPlugin.o ../objs/armv5sfLinux3.2gcc4.6.2.EV3/EV3_TouchSupport.o ../ev3/ev3dev.o -L/host-rootfs/home/rip/nfs/ev3dev/ndds.5.1.0/lib/armv5sfLinux3.2gcc4.6.2.EV3 -lnddscppz -lnddscz -lnddscorez -ldl -lnsl -lm -lpthread -lrt -lstdc++
The problematic .o is the ../ev3/ev3dev.o file. After build, I get the Touch_publisher application, but nm reports:
root#arundel:~/rti_510/Touch# nm ../objs/armv5sfLinux3.2gcc4.6.2.EV3/Touch_publisher | grep ev3 | grep " U "
U _ZN6ev3dev12touch_sensorC1ESs
U _ZNK6ev3dev12touch_sensor7pressedEv
U _ZNK6ev3dev6sensor9type_nameEv
If I do an nm on ev3dev.o, for the missing symbols, I get e.g.,
root#arundel:~/rti_510/Touch# nm ../ev3/ev3dev.o | grep _ZN6ev3dev12touch_sensorC1ESs
0000ee5c T _ZN6ev3dev12touch_sensorC1ESs
root#arundel:~/rti_510/Touch#
So a symbol is there. What from the above is the detail I'm unware of? The " T " means it is an external symbol...
Am I missing some esoteric flag on the command line? The ev3dev.o file is built using:
BUILD:
gcc -std=c++11 -shared -fpic -march=armv5t -mfloat-abi=soft -mlong-calls -o ev3dev.o ev3dev.cpp
Or maybe is there another step? I've tried '-Wl,-whole-archive,../ev3/ev3dev.o,-no-whole-archive' but still get those pesky U symbols.
I have no -O# optimizations enabled.
I have read 20 or so similar questions ("missing symbols from linked object")
Thank you
addendum: result of objdump rather than nm:
root#arundel:/host-rootfs/home/rip/nfs/ev3dev/rti_510/Touch# objdump -T Touch_publisher | grep \*UND\* | grep ev3dev
00000000 DF *UND* 00000000 _ZNK6ev3dev12touch_sensor7pressedEv
00000000 DF *UND* 00000000 _ZNK6ev3dev6sensor9type_nameEv
00000000 DF *UND* 00000000 _ZN6ev3dev12touch_sensorC1ESs
root#arundel:/host-rootfs/home/rip/nfs/ev3dev/rti_510/Touch# objdump -t ../ev3/ev3dev.o | grep ev3dev | grep _ZNK6ev3dev12touch
0000f040 g F .text 00000058 _ZNK6ev3dev12touch_sensor7pressedEv
root#arundel:/host-rootfs/home/rip/nfs/ev3dev/rti_510/Touch# objdump -t ../ev3/ev3dev.o | grep ev3dev | grep _ZNK6ev3dev6sensor9type
0000dd10 g F .text 00000690 _ZNK6ev3dev6sensor9type_nameEv
root#arundel:/host-rootfs/home/rip/nfs/ev3dev/rti_510/Touch# objdump -t ../ev3/ev3dev.o | grep ev3dev | grep _ZN6ev3dev12touch
0000ee5c g F .text 000001e4 _ZN6ev3dev12touch_sensorC1ESs
0000ee5c g F .text 000001e4 _ZN6ev3dev12touch_sensorC2ESs
root#arundel:/host-rootfs/home/rip/nfs/ev3dev/rti_510/Touch#

The ev3dev.o file is built using:
BUILD:
gcc -std=c++11 -shared ... -o ev3dev.o ev3dev.cpp
That's your problem, right there: you've built a shared library and mis-named it ev3dev.o.
The rules for linking shared libraries is that they are not included into the main executable when you link against them, so no wonder ev3dev.o is not included into the Touch_publisher.
Solution: replace -shared with -c if you want ev3dev.o to be a normal (relocatable) object file, suitable for linking into the main executable.

Related

How to create a makefile for a Fortran program using modules

The challenge is to create a makefile which takes a list of modules and does not require me to sort out precendence. For example, the modules are
mod allocations.f08 mod precision definitions.f08 mod unit values.f08
mod blocks.f08 mod shared.f08 mod parameters.f08
mod timers.f08
The main program is characterize.f08. The error message is
Fatal Error: Can't open module file ‘mprecisiondefinitions.mod’ for reading at (1): No such file or directory
The first statement in the main program is use mPrecisionDefinitions, the module defined in mod precision definitions.f08.
The following makefile, based upon Creating a FORTRAN makefile, is:
# compiler
FC := /usr/local/bin/gfortran
# compile flags
FCFLAGS = -g -c -Wall -Wextra -Wconversion -Og -pedantic -fcheck=bounds -fmax-errors=5
# link flags
FLFLAGS =
# source files and objects
SRCS = $(patsubst %.f08, %.o, $(wildcard *.f08))
# program name
PROGRAM = a.out
all: $(PROGRAM)
$(PROGRAM): $(SRCS)
$(FC) $(FLFLAGS) -o $# $^
%.mod: %.f08
$(FC) $(FCFLAGS) -o $# $<
%.o: %.f08
$(FC) $(FCFLAGS) -o $# $<
clean:
rm -f *.o *.mod
For starters, I recommend to replace all spaces in your file names with underscores or something similar.
Spaces are almost universally used as separators, and any program that is started with something like
gfortran -c -o mod precision definitions.o mod precision definitions.f08
would interpret this line as 'create an object file called mod from the source files precision, definitions.o, mod, precision, and definitions.f08. And while there are ways to do it, with increasing automation, you have to jump more and more hoops.
In contrast, this works well:
gfortran -c -o mod_precision_definitions.o mod_precision_definitions.f08
I would use this command to change all the spaces into underscores:
rename 's/ /_/g' *.f08
If that doesn't work, use this command:
for f in *.f08; do mv "$f" ${f// /_}; done
Next, I wouldn't worry about .mod files. They get generated together with the object files when you compile a module. So while technically some routine that uses a module requires the .mod file for that module, you might as well claim in your Makefile that it depends on the object file itself.
So with that said, here's the Makefile I would use (with some assumed inter-module dependencies added):
# Find all source files, create a list of corresponding object files
SRCS=$(wildcard *.f08)
OBJS=$(patsubst %.f08,%.o,$(SRCS))
# Ditto for mods (They will be in both lists)
MODS=$(wildcard mod*.f08)
MOD_OBJS=$(patsubst %.f08,%.o,$(MODS))
# Compiler/Linker settings
FC = gfortran
FLFLAGS = -g
FCFLAGS = -g -c -Wall -Wextra -Wconversion -Og -pedantic -fcheck=bounds -fmax-errors=5
PROGRAM = characterize
PRG_OBJ = $(PROGRAM).o
# make without parameters will make first target found.
default : $(PROGRAM)
# Compiler steps for all objects
$(OBJS) : %.o : %.f08
$(FC) $(FCFLAGS) -o $# $<
# Linker
$(PROGRAM) : $(OBJS)
$(FC) $(FLFLAGS) -o $# $^
# If something doesn't work right, have a 'make debug' to
# show what each variable contains.
debug:
#echo "SRCS = $(SRCS)"
#echo "OBJS = $(OBJS)"
#echo "MODS = $(MODS)"
#echo "MOD_OBJS = $(MOD_OBJS)"
#echo "PROGRAM = $(PROGRAM)"
#echo "PRG_OBJ = $(PRG_OBJ)"
clean:
rm -rf $(OBJS) $(PROGRAM) $(patsubst %.o,%.mod,$(MOD_OBJS))
.PHONY: debug default clean
# Dependencies
# Main program depends on all modules
$(PRG_OBJ) : $(MOD_OBJS)
# Blocks and allocations depends on shared
mod_blocks.o mod_allocations.o : mod_shared.o

How to exclude a system library from dynamic linking

I have a local DLL which I want to shadow the system one.
How do i do that?
Specifically (on linux):
/usr/bin/clang++ -o vw main.o -L. -l vw -l allreduce -L /usr/lib -L /usr/lib/x86_64-linux-gnu -l boost_program_options -l pthread -l z
but then
$ ldd vowpalwabbit/vw
libvw.so => /usr/lib64/libvw.so (0x00007ffa22789000)
and I want it to point to ./libvw.so instead
Afaik the parameter is -nostdlib, but I only used it with plain C.
See also Clang produces crashing code with -nostdlib

Using g++ with libc++

It's quite easy to get clang++ to use GCC's libstdc++ (-stdlib=stdc++), but how can I do the converse? On OS X Mavericks, the c++ system library is libc++, which means that basically libstdc++ cannot be used (if you mix with other c++ libraries such as boost that have been compiled with libc++). So, roughly, that means G++ is not usable... Unless I can ask it to use libc++ rather than libstdc++.
Thanks.
The script I use (EDIT)
I'm using the following script, g++-libc++, to run g++ on top of libc++, on Mac OS X with MacPorts (hence the -mp names.
#! /bin/sh
clangxx=clang++-mp-3.5
gxx=g++-mp-4.9
libcxx_includes=$($clangxx -print-search-dirs |
perl -ne 's{^libraries: =(.*)}{$1/../../../} && print')
exec $gxx -std=c++11 \
-isystem ${libcxx_includes}/include/c++/v1 \
-nostdinc++ -nodefaultlibs \
-lc -lc++ -lc++abi -lgcc_s.10.5 \
-Wl,-no_compact_unwind \
"$#"
Something like:
g++ -std=c++0x -nostdinc++ -nodefaultlibs -lc -isystem <path_to>/include/c++/v1 -lc++ -lc++abi -lgcc_s.10.5

GCC multiple optimization flags

I have some legacy code that compiles with both -02 and -03 set. From the GCC man file I get the guarantee that:
-O3 turns on all optimizations specified by -O2 and also turns on the -finline-functions, -funswitch-loops, -fpredictive-commoning, -fgcse-after-reload and -ftree-vectorize
options.
So, at first glance it would seem likely that turning both of these flags on would be the same as just -O3. However, that got me thinking is that the right thing to do in that case as -O2 is probably the "safer" option. Obviously, it is a simple matter compile some code with all of the permutations and see what happens in each case, but I was wondering if anyone knows if there is a specific policy that GCC has in regard to specifying multiple optimizations levels and if so what is the reasoning behind it?
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.
For over-concerned users like my self, here is a code begging for optimization:
$ cat dominant_flag.c
#include <stdio.h>
int foo(int i)
{
return 3*i+122;
}
int main(int argc, char **argv)
{
return foo(0xface); // meant to be optimized out
}
And Here are four compilation scenarios:
$ gcc -g -O0 dominant_flag.c -o flag0
$ gcc -g -O3 dominant_flag.c -o flag3
$ gcc -g -O0 -O3 dominant_flag.c -o flag03
$ gcc -g -O3 -O0 dominant_flag.c -o flag30
Once I look for the constant 0xface, I see it exists in the non optimized versions:
$ objdump -S -D flag0 | grep -w "\$0xface" # 61e: bf ce fa 00 00 mov $0xface,%edi
$ objdump -S -D flag30 | grep -w "\$0xface" # 61e: bf ce fa 00 00 mov $0xface,%edi
and optimized out in the optimized versions:
$ objdump -S -D flag3 | grep -w "\$0xface"
$ objdump -S -D flag03 | grep -w "\$0xface"
The whole foo call is gone:
$ objdump -S -D flag03 | sed -n "297,298p;299q"
4f0: b8 e4 f0 02 00 mov $0x2f0e4,%eax # <--- hex(3*0xface+122)=0x2f0e4
4f5: c3 retq

When is the symbol table for this program built

When I run make on the following Makefile, when is the symbol table built, if it even is?
LEX = flex
YACC = yacc
CC = gcc
calcu: y.tab.o lex.yy.o
$(CC) -o calcu y.tab.o lex.yy.o -ly -lfl
y.tab.c y.tab.h: parser.y
$(YACC) -d parser.y
y.tab.o: y.tab.c parser.h
$(CC) -c y.tab.c
lex.yy.o: y.tab.h lex.yy.c
$(CC) -c lex.yy.c
lex.yy.c: calclexer.l parser.h
$(LEX) calclexer.l
clean:
rm *.o
rm *.c
rm calcu
make doesn't build symbol tables (obviously the compilers and linkers it invokes will have to do that!). I'll assume you're referring to whatever the resulting calcu binary does wrt its input, instead.
If any such thing as a "symbol table" is ever built by calcu, it will be by code you inserted into parser.y that gets moved over into yacc.tab.c; as to when, it will be during the course of a calcu run over whatever its input is -- incrementally, as each syntax production including "symbol-table building code" matches.