Cross compiling C++ project, Relocations in generic ELF (EM: 3) - c++

I've been working on a c++ project for a while now, but would like to port it over to my arm processor. I already have all of my cross-compile tools (I'm using CodeSourcery) and thought I could just change my makefile to point to that compiler. It compiles fine using the default g++, but When try a make pointing to the cross-compiler I get relocation errors:
/home/oryan/CodeSourcery/bin/../lib/gcc/arm-none-linux-gnueabi/4.5.2/../../../../arm-none-linux-gnueabi/bin/ld: ServerSocket.o: Relocations in generic ELF (EM: 3)
ServerSocket.o: could not read symbols: File in wrong format
collect2: ld returned 1 exit status
make: *** [simple_server] Error 1
It seems like I don't have a proper link set up or it's pointing to a wrong location. I'm not that familiar with makefiles and am probably missing something obvious. The makefile I've been using is from http://tldp.org/LDP/LG/issue74/tougher.html with the client side removed:
# Makefile for the socket programming example
#
simple_server_objects = ServerSocket.o Socket.o simple_server_main.o
all : simple_server
simple_server: $(simple_server_objects)
/home/matt/CodeSourcery/bin/arm-none-linux-gnueabi-g++ -o simple_server $(simple_server_objects)
Socket: Socket.cpp
ServerSocket: ServerSocket.cpp
simple_server_main: simple_server_main.cpp
clean:
rm -f *.o simple_server
Right now I am manually compiling each file and it works great, but I'd like to further my understanding here.
Thanks!

The problem is you've set your makefile up to link with the new g++ but you haven't changed the compiler you're using to build the objects in the first place.
The easiest way to fix this is to set environment CXX to the next compiler, i.e.
export CXX=/home/matt/CodeSourcery/bin/arm-none-linux-gnueabi-g++
or just set it for a given make by adding CXX=... to the command line.
You'll need to make clean first but you'll then use the correct compiler for both the compile and link.
You could also specify a new how-to-compile-C++ files rule in your makefile to specify the new compiler but the environment variable is easier:
.cc.o:
/home/.../g++ $(CPPFLAGS) $(CXXFLAGS) -c

The problem is because of these three rules:
Socket: Socket.cpp
ServerSocket: ServerSocket.cpp
simple_server_main: simple_server_main.cpp
First of all, the left-hand side of the rule should be the object file I guess, so should have the .o suffix.
The second problem, and most likely the root of your problem, is that there is no command to compile the source files, which means that make will use the default compiler and not your cross-compiler.

Related

I need some Makefile wizardry explained

So I was following one of the Makefile by example tutorials (cause I'm fairly fresh) and thats how I ended up here.
files = src/main.cpp src/compiler.cpp
all: $(files)
%.cpp:
echo $#
And this for some reason produces this
echo src/compiler.cpp
src/compiler.cpp
echo all.cpp
all.cpp
g++ -c -o all.o all.cpp
cc1plus: fatal error: all.cpp: No such file or directory
compilation terminated.
make: *** [<builtin>: all.o] Error 1
I don't see any refrences to g++ at all and for some reason it's getting called. The idea here was to use it to compile all my stuff from /src to .o files in /obj then produce a binary. Any ideas on how to do that or explanations on how to not call g++ without even referencing it in the makefile is highly appreciated.
It's being called because you have created a target all, and you haven't given make any recipe to build that target. So, make looks through its built-in rules and it sees that it knows how to build a program x given a prerequisite x.cpp. Well, make knows how to build a all.cpp, because you provided a rule that tells it how to build any .cpp file.
So first it runs the rule to build all.cpp, then it runs its built-in rule to build a target all from that all.cpp (which doesn't exist because your rule that told make how to build %.cpp doesn't actually create that target).
If you don't actually want to build a target all, then you should declare it to be a phony target:
.PHONY: all

Trying to compile simple project that uses TRI DDS using cygwin gcc

I am trying to take the TRI DDS example code. It is all setup to build with MSVS2012 and comes with MSVS2012 proj/solution files.
However I want to try to build this using Cygwin and g++/gcc. I have got so far and then hit issues.
My cpp/h files are taken from their example - the user code is basic c++ but the generated files / RTI DDS files I think are causing an issue.
The basic source files are:
Hello.cpp
HelloPublisher.cpp/h
HelloSubscriber.cpp/h
HelloWorld.idl
RTI-DDS generator uses HelloWorld.idl to generate further files (.cxx/h files). I am not expecting to change any of the RTI-DDS files and the code within the 4 source files are fairly vanilla, so I can compile them if I hack out all the calls to RTI-DDS.
The area I want to focus on is the makefile / environment. Here are the pertinent parts of my makefile (note the linker parts are not complete because I have not got that far yet - the compile still fails):
note NDDSHOME = c:\Program Files\rti_connext_dds-5.3.0 as an env var.
# Setup minimal "un-polluted" paths to try to avoid any conflicts
makePaths=/usr/local/bin:/usr/bin:$(NDDSHOME)/bin
export PATH := $(makePaths)
#Include Paths
INCLUDES = -I. -I"$(NDDSHOME)/include" -I"$(NDDSHOME)/include/ndds" -I"$(NDDSHOME)/include/ndds/hpp"
#Compiler / options:
DEFINES = -DRTI_WIN32 -DRTI_STATIC -DWIN32 -D_WIN32_WINNT=_WIN32_WINNT_WIN7
CC = g++
CC_FLAGS = -std=c++11 -Wall -Wextra -lWS2_32
EXEC = run
# C++ files
SOURCES = $(wildcard *.cpp)
OBJECTS = $(SOURCES.cpp=.o)
# Main Target
$(EXEC): $(OBJECTS)
# Don't do linking yet - compile not working!
%.o: %.cpp
$(CC) $< -o $# -c $(DEFINES) $(CC_FLAGS) $(INCLUDES)
I know the INCLUDES paths are working because I get different errors when they are not (can't find...)
But the error I get at the moment is:
/usr/include/w32api/winsock2.h:1004:68: error: conflicting declaration of c function 'int gethostname(char*, int)'
:
:
/usr/include/sys/unistd.h:268:6 note: previous declration 'int gethostname(char *, size_t)'
note I have to copy this by hand from my other PC... so I have abbreviated the complete message.
I thought I was close to solving this by looking at other questions with similar errors, but I can't quite make the connection to fix this. I have tried adding other defines to specify the windows version, but that did not fix it. I know there is a linker option that we need to use for things like mingw that is what the -lws2_32 flag is set for - but I have not got to the linker stage yet :(
I guess either the unistd.h or the winsock2.h should not really both be included, but I can't quite figure out what define (or other) I need to add...
Any ideas?

Compile Pro*C in AIX 7 (64bit)

I try to migrate the old Pro*C program from HP to AIX, after changed some setting, I can make the binary file but fail to execute. Seems I now facing wrong library used (lib32/libclntsh.a).
Here is the error
0509-036 Cannot load program PROGNAME because of the following errors:
0509-150 Dependent module SOMEPATH/lib32/libclntsh.a(shr.o) could not be loaded.
0509-103 The module has an invalid magic number.
I build the program by setting object mode to 64
export OBJECT_MODE=64
Here is the full image when I make the binary
/PATHA/bin/oraxlc -O3 -q64 -DSS_64BIT_SERVER -I. -c MYPROG.c "MYPROG.c", line 2051.25: 1506-342 (W) "/*" detected in comment.
/PATHA/bin/oraxlc -o GLMJLUSB GLMJLUSB.o -L/PATHA/lib/ -lclntsh -lld -lm `cat /PATHA/lib/sysliblist` -lm -lc_r -lpthreads +DD64
/PATHB/bin/.orig/xlc: 1501-228 (W) input file +DD64 not found
Is there any way I can specify not to use the problem library, and use the 64bit version instead?
I don't know much about Pro*C and AIX, so any help is welcome. Thanks.
(Not really an answer yet, expect many edits).
Do you have a Makefile? If not, create one:
.SUFFIXES: .pc
PROC = ${ORACLE_HOME}/bin/proc
PROCFLAGS = code=ansi lines=yes
.pc.c:
${PROC} ${PROCFLAGS} $<
Keep improving it, until you can successfully precompile your *.pc files into *.c files.
Note: it is way easier, if you have GNU!make instead of prehistoric!make

can you create a c++ file from an .o object file with makefile?

What I'm trying to do is create a c++ file from an object file but I cannot figure out a way to do so.
INCLUDEDIR = ../headers
CXXFLAGS = -std=c++11 -I $(INCLUDEDIR) -Wall -Wfatal-errors -O2
all:primeFactors.o
primeFactors.o: primeFactors.cpp $(INCLUDEDIR)/primeFactors.h
g++ $(CXXFLAGS) -c $< -o $#
When I try to build this I get
make: *** No rule to make target 'primeFactors.cpp', needed by
'primeFactors.o'. Stop.
which I understand but when I take out the primeFactor.cpp argument I then get told there is nothing to be done with the make file. So is there a way to do this?
In general; no, you cannot do that. An object file (.o file) is the result of the code passing through the compiler front-end (to parse the language) the optimizer (to make it run fast) and the compiler back-end (to produce code that will run on your CPU).
This process is not reversible. You cannot go from compiled code back to source.
can you create a c++ file from an .o object file with makefile?
A makefile will allow you to do that only if you have an underlying tool to do it. make, which uses makefiles to do its job, does not have any built-in mechanisms to pull that off.
Your makefile has a rule for building primeFactors.o.
primeFactors.o: primeFactors.cpp $(INCLUDEDIR)/primeFactors.h
It says that primeFactors.cpp and $(INCLUDEDIR)/primeFactors.h are needed to build primeFactors.o. If you don't have those files, or no rules to build them, there is no way for make to build primeFactors.o.

make not executing correct Makefile

I should preface this by saying I am very new to Makefiles.
I created the following Makefile:
all: tiling_graph.o
g++ -o tiling_graph tiling_graph.o -L/usr/local/lib -ligraph
I am trying to make sure that -ligraph is included. However, when I type "make", I get the following output: "c++ -c -o tiling_graph.o tiling_graph.cpp"
Why is it not using the Makefile that I created in the current directory? I have tried using "make -f Makefile" and "make --file=Makefile" but none of these are working.
Also, right after I first made the Makefile, it worked correctly. The output after typing make was
"g++ -o tiling_graph tiling_graph.o -L/usr/local/lib -ligraph"
I executed ./tiling_graph and it was successful.
Then I edited tiling_graph.cpp, ran make again, and the output was "c++ -c -o tiling_graph.o tiling_graph.cpp" and has been ever since.
I would really appreciate any help. Thanks!
A simple way to think about a make rule:
target: dependency list
commands to make the target
is that it is a recipe for making the file called target from the list of files in the dependency list. Since make can see the file system, it can tell whether any file in the dependency list is newer than the file named target, which is its signal for recreating target. After all, if none of the dependencies have changed, the target must be up-to-date.
Note that make knows quite a lot about how to build files. In particular, it has a lot of built-in "pattern" rules, so it knows, for example, how to make an object file (prog.o) from a C++ source file (prog.cpp) or from a C source file (prog.c) or many other things. So you only need to actually write a makefile when you have other requirements, like a library (and even then you could just add that to an environment variable, but the makefile is better).
Now, you don't actually want to build a file called all. You want to build a file called tiling_graph. So the correct make rule would be:
tiling_graph: tiling_graph.o
g++ -o tiling_graph tiling_graph.o -L/usr/local/lib -ligraph
Since make already knows how to create tiling_graph.o, it can actually figure out how to make tiling_graph from tiling_graph.cpp.
So where does this all come from? The usual way to use all is:
all: program1 program2 program3
which tells make that the all target requires program1, program2 and program3. So if you need to build all three of those programs, the all rule would let you just do one make command. Since there is no file named all, that's a "phony" target and (with gnu make, at least) it should be declared as a phony target:
all: tiling_graph
.PHONY: all
But you really don't need that if you just want to build one program.
When you just type make (as opposed to make target), make chooses the first target in the makefile. So if you put the thing you usually want to build first, you'll save some typing.