Running Cpp sample client out of the box.
I receive a segmentation fault.
0x00005555555efba6 in __bid64_to_string ()
Have sourced this function to client file to Decimal.h
extern "C" void __bid64_to_string(char*, Decimal, unsigned int*);
This may have something to do with the floating point library that the API documentation mentions: IntelĀ® Decimal Floating-Point Math Library
https://interactivebrokers.github.io/tws-api/introduction.html
I have checked if this is installed on my ubuntu version, using WSL Ubuntu 20.04.05
libintelrdfpmath-dev/now 2.0u2-4 amd64 [installed,local]
root#flare9x:~# dpkg -s libintelrdfpmath-dev
Package: libintelrdfpmath-dev
Status: install ok installed
Priority: optional
Section: libdevel
Installed-Size: 72286
Maintainer: Ubuntu Developers <ubuntu-devel-discuss#lists.ubuntu.com>
Architecture: amd64
Source: intelrdfpmath
Version: 2.0u2-4
Description: Intel Decimal Floating-Point Math Library
Software implementation of the IEEE 754-2008 Decimal Floating-Point
Arithmetic specification, aimed at financial applications, especially
in cases where legal requirements make it necessary to use decimal, and
not binary floating-point arithmetic (as computation performed with
binary floating-point operations may introduce small, but unacceptable
errors).
Original-Maintainer: Christian Stalp <chris#chrishell.de>
Homepage: https://software.intel.com/en-us/articles/intel-decimal-floating-point-math-library
Looking at the makefile:
CXXFLAGS=-pthread -Wall -Wno-switch -Wpedantic -Wno-unused-function -std=c++11
ROOT_DIR=../../../source/cppclient
BASE_SRC_DIR=${ROOT_DIR}/client
INCLUDES=-I${BASE_SRC_DIR} -I${ROOT_DIR}
SHARED_LIB_DIRS=${BASE_SRC_DIR}
SHARD_LIBS=libTwsSocketClient.so
TARGET=TestCppClient
$(TARGET)Static:
$(CXX) $(CXXFLAGS) $(INCLUDES) $(BASE_SRC_DIR)/*.cpp ./*.cpp $(BASE_SRC_DIR)/lib/libbid.a -o$(TARGET)Static
$(TARGET):
$(CXX) $(CXXFLAGS) $(INCLUDES) ./*.cpp $(BASE_SRC_DIR)/lib/libbid.so $(SHARED_LIB_DIRS)/$(SHARD_LIBS) -o$(TARGET)
clean:
rm -f $(TARGET) $(TARGET)Static *.o
The interesting part - I can compile the exact same code on Windows, VScode in win32.
I have tried to enforce 32bit with gcc. adding -m32.
When doing this compiler shows numerous complaints:
1974 | printf("Soft dollar tiers (%lu):", tiers.size());
| ~~^ ~~~~~~~~~~~~
| | |
| | std::vector<SoftDollarTier>::size_type {aka unsigned int}
| long unsigned int
| %u
I commented out these functions which include %lu as do not need them in main application.
Compile again, this time we have errors with the librarys that are packaged with the TWS API - the Intel decimal floating point math library, these libs come with the original TWS installation and locate:
/source/cppclient/client/lib/libbid.a
/usr/bin/ld: i386:x86-64 architecture of input file `../../../source/cppclient/client/lib/libbid.a(bid64_string.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../../source/cppclient/client/lib/libbid.a(bid128_2_str_tables.o)' is incompatible with i386 output
/usr/bin/ld: i386:x86-64 architecture of input file `../../../source/cppclient/client/lib/libbid.a(bid_decimal_data.o)' is incompatible with i386 output
win32 runs this just fine vscode.
running with ```gcc -m64``
Obtain seg fault again:
Thread 1 "TestCppClientSt" received signal SIGSEGV, Segmentation fault.
0x00005555555efba6 in __bid64_to_string ()
(gdb) bt
#0 0x00005555555efba6 in __bid64_to_string ()
#1 0x00007fffffffd940 in ?? ()
#2 0x00007fffffffd940 in ?? ()
#3 0x00007fffffffd940 in ?? ()
#4 0x00007fffffffd941 in ?? ()
#5 0x00007fffffffd940 in ?? ()
#6 0x00007fffffffd820 in ?? ()
#7 0x000055555555d5ff in std::iterator_traits<char*>::difference_type std::distance<char*>(char*, char*) ()
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
Not sure what it could be at this point - WSL and running ubuntu on windows - that process manages memory? is ubuntu clashing with windows.
At this point - what else can I check / troubleshoot?
Thanks
Ok finally got it working by locating where the intel floating point math library was located, named: libintelrdfpmath-dev, this was in contrast to using the library that comes with the TWS API as is, located at directory: ~/IBJts/source/cppclient/client/lib/libbid.a
:
root#Ubuntu-22:/bin# dpkg -L libintelrdfpmath-dev
/.
/usr
/usr/include
/usr/include/bid_conf.h
/usr/include/bid_functions.h
/usr/lib
/usr/lib/x86_64-linux-gnu
/usr/lib/x86_64-linux-gnu/libbidgcc000.a
/usr/lib/x86_64-linux-gnu/libbidgcc000b.a
/usr/lib/x86_64-linux-gnu/libbidgcc001.a
/usr/lib/x86_64-linux-gnu/libbidgcc001b.a
/usr/lib/x86_64-linux-gnu/libbidgcc010.a
/usr/lib/x86_64-linux-gnu/libbidgcc010b.a
/usr/lib/x86_64-linux-gnu/libbidgcc011.a
/usr/lib/x86_64-linux-gnu/libbidgcc011b.a
/usr/lib/x86_64-linux-gnu/libbidgcc100.a
/usr/lib/x86_64-linux-gnu/libbidgcc100b.a
/usr/lib/x86_64-linux-gnu/libbidgcc101.a
/usr/lib/x86_64-linux-gnu/libbidgcc101b.a
/usr/lib/x86_64-linux-gnu/libbidgcc110.a
/usr/lib/x86_64-linux-gnu/libbidgcc110b.a
/usr/lib/x86_64-linux-gnu/libbidgcc111.a
/usr/lib/x86_64-linux-gnu/libbidgcc111b.a
/usr/share
/usr/share/doc
/usr/share/doc/libintelrdfpmath-dev
/usr/share/doc/libintelrdfpmath-dev/README.gz
/usr/share/doc/libintelrdfpmath-dev/changelog.Debian.gz
/usr/share/doc/libintelrdfpmath-dev/copyright
I edited the makefile to include the path to this library, now which one?
I added
/usr/lib/x86_64-linux-gnu/libbidgcc000.a to my make file.
My makefile looks like:
CXX=g++
CXXFLAGS=-pthread -Wall -Wno-switch -Wpedantic -Wno-unused-function -std=c++11
ROOT_DIR=../../../source/cppclient
BASE_SRC_DIR=${ROOT_DIR}/client
INCLUDES=-I${BASE_SRC_DIR} -I${ROOT_DIR}
SHARED_LIB_DIRS=${BASE_SRC_DIR}
SHARD_LIBS=libTwsSocketClient.so
TARGET=TestCppClient
$(TARGET)Static:
$(CXX) $(CXXFLAGS) $(INCLUDES) $(BASE_SRC_DIR)/*.cpp ./*.cpp /usr/lib/x86_64-linux-gnu/libbidgcc000.a -o$(TARGET)Static
$(TARGET):
$(CXX) $(CXXFLAGS) $(INCLUDES) ./*.cpp $(BASE_SRC_DIR)/lib/libbid.so $(SHARED_LIB_DIRS)/$(SHARD_LIBS) -o$(TARGET)
clean:
rm -f $(TARGET) $(TARGET)Static *.o
requested real time bars, decimal places looks as intended and most of all no segmentation fault.
RealTimeBars. 3001 - Time: 1673241105, Open: 0.87948, High: 0.87951, Low: 0.87947, Close: 0.87951, Volume: -1, Count: -1, WAP: -1
hopefully this solves others issues with this.
Related
I encountered an odd difference between the binary produced by a 4.9.2 G++ and a 8.2.0 G++ on a Linux, when upgrading from the former to the latter. I was able to narrow it down to the below minimized snippet
//main.cpp
int main(){}
//emptylib.cpp
#!/bin/sh
#to build and verify output
rm -rf bin lib *.o
gcc_bin=/path/to/gcc_4.9.2/bin
#gcc_bin=/path/to/gcc_8.2.0/bin
${gcc_bin}/g++ -B${gcc_bin} -c main.cpp
${gcc_bin}/g++ -B${gcc_bin} -c emptylib.cpp
${gcc_bin}/g++ -B${gcc_bin} -shared emptylib.o -o libemptylib.so
${gcc_bin}/g++ -B${gcc_bin} main.o -o main -L. -lemptylib
mkdir bin
mkdir lib
mv libemptylib.so lib/
mv main bin/
ldd bin/main
The result is a bit strange, because I have provided no -rpath=../lib, but all the same, with the 4.9.2 compiler driver I end up with (in the output of ldd):
libemptylib.so => /path/to/bin/../lib/libemptylib.so
and with 8.2.0
libemptylib.so => not found
the lib does not resolve, as I would expect. I haven't been able to see any documentation that hints at a search for ../lib in any version, but I would not expect this to be a behavior by any version. Was this a bug in 4.9.2 or some earlier version or something that shouldn't have happened in the first place?
As a side note, the 8.2.0 and the 4.9.2 don't have an ld inside of their bin directory (despite me putting the -B in the code snippet), so both compiler drivers are using the /usr/bin/ld (I've verified as much) and producing different results based on the compiler driver alone.
Update:
On request, I ran readelf -d bin/main on both binaries and I did receive different output for rpath. GCC 4.9.2 gave me:
0x000000000000000f (RPATH) Library rpath: [$ORIGIN:$ORIGIN/../lib64:$ORIGIN/../lib:/path/to/gcc_libs/lib64:/path/to/gcc_libs/lib:/path/to/gcc_4.9.2/lib64:/path/to/gcc_4.9.2/lib]
where 8.2.0 did not have that
0x0000000000000001 (NEEDED) Shared Library: [libemptylib.so]
So I guess I have an answer to what happened. So how did this end up in my binary in 4.9.2, and why did it change between the two versions where now it doesn't in 8.2.0?
I did receive different output for rpath.
rpath: [$ORIGIN:$ORIGIN/../lib64:$ORIGIN/../lib:/path/to/gcc_libs/lib64:/path/to/gcc_libs/lib:/path/to/gcc_4.9.2/lib64:/path/to/gcc_4.9.2/lib]
So the difference is in how GCC 4.9.2 vs. 8.2.0 were configured.
I am guessing that 8.2 came from your distribution (or at least was configured with default installation paths), whereas 4.9 was configured to be installed into /path/to/gcc_4.9.2.
That explains why 4.9 adds -rpath with /path/to/gcc_4.9.2/lib64 for a 64-bit builds. It does not however explain where $ORIGIN of /path/to/gcc_4.9.2/lib (the latter shouldn't be part of a 64-bit build) come from.
Configuring GCC so that it puts exactly what's necessary, no more and no less, is a bit of a black magic. I wouldn't be surprised if 4.9 had some bugs in that area.
I am building a module in C++ to be used in Python. My flow is three steps: I compile the individual C++ sources into objects, create a library, and then run a setup.py script to compile the .pyx->.cpp->.so, while referring to the library I just created.
I know I can just do everything in one step with the Cython setup.py, and that is what I used to do. The reason for splitting it into multiple steps is I'd like the C++ code to evolve on its own, in which case I would just use the compiled library in Cython/python.
So this flow works fine, when there are no bugs. The issue is I am trying to find the source of a segfault, so I'd like to get the debugging symbols so that I can run with gdb (which I installed on OSX 10.14, it was a pain but it worked).
I have a makefile, which does the following.
Step 1: Compile individual C++ source files
All the files are compiled with the bare minimum flags, but -g is there:
gcc -mmacosx-version-min=10.7 -stdlib=libc++ -std=c++14 -c -g -O0 -I ./csrc -o /Users/colinww/system-model/build/data_buffer.o csrc/data_buffer.cpp
I think even here there is a problem: when I do nm -pa data_buffer.o, I see no debug symbols. Furthermore, I get:
(base) cmac-2:system-model colinww$ dsymutil build/data_buffer.o
warning: no debug symbols in executable (-arch x86_64)
Step 2: Compile cython sources
The makefile has the line
cd $(CSRC_DIR) && CC=$(CC) CXX=$(CXX) python3 setup_csrc.py build_ext --build-lib $(BUILD)
The relevant parts of setup.py are
....
....
....
compile_args = ['-stdlib=libc++', '-std=c++14', '-O0', '-g']
link_args = ['-stdlib=libc++', '-g']
....
....
....
Extension("circbuf",
["circbuf.pyx"],
language="c++",
libraries=["cpysim"],
include_dirs = ['../build'],
library_dirs=['../build'],
extra_compile_args=compile_args,
extra_link_args=link_args),
....
....
....
ext = cythonize(extensions,
gdb_debug=True,
compiler_directives={'language_level': '3'})
setup(ext_modules=ext,
cmdclass={'build_ext': build_ext},
include_dirs=[np.get_include()])
When this is run, it generates a bunch of compilation/linking commands like
gcc -Wno-unused-result -Wsign-compare -Wunreachable-code -DNDEBUG -g -fwrapv -O3 -Wall -Wstrict-prototypes -I/Users/colinww/anaconda3/include -arch x86_64 -I/Users/colinww/anaconda3/include -arch x86_64 -I. -I../build -I/Users/colinww/anaconda3/lib/python3.7/site-packages/numpy/core/include -I/Users/colinww/anaconda3/include/python3.7m -c circbuf.cpp -o build/temp.macosx-10.7-x86_64-3.7/circbuf.o -stdlib=libc++ -std=c++14 -O0 -g
and
g++ -bundle -undefined dynamic_lookup -L/Users/colinww/anaconda3/lib -arch x86_64 -L/Users/colinww/anaconda3/lib -arch x86_64 -arch x86_64 build/temp.macosx-10.7-x86_64-3.7/circbuf.o -L../build -lcpysim -o /Users/colinww/system-model/build/circbuf.cpython-37m-darwin.so -stdlib=libc++ -g
In both commands, the -g flag is present.
Step 3: Run debugger
Finally, I run my program with gdb
(base) cmac-2:sim colinww$ gdb python3
(gdb) run system_sim.py
It dumps out a ton of stuff related to system files (seems unrelated) and finally runs my program, and when it segfaults:
Thread 2 received signal SIGSEGV, Segmentation fault.
0x0000000a4585469e in cpysim::DataBuffer<double>::Write(long, long, double) () from /Users/colinww/system-model/build/circbuf.cpython-37m-darwin.so
(gdb) info local
No symbol table info available.
(gdb) where
#0 0x0000000a4585469e in cpysim::DataBuffer<double>::Write(long, long, double) () from /Users/colinww/system-model/build/circbuf.cpython-37m-darwin.so
#1 0x0000000a458d6276 in cpysim::ChannelFilter::Filter(long, long, long) () from /Users/colinww/system-model/build/chfilt.cpython-37m-darwin.so
#2 0x0000000a458b0d29 in __pyx_pf_6chfilt_6ChFilt_4filter(__pyx_obj_6chfilt_ChFilt*, long, long, long) () from /Users/colinww/system-model/build/chfilt.cpython-37m-darwin.so
#3 0x0000000a458b0144 in __pyx_pw_6chfilt_6ChFilt_5filter(_object*, _object*, _object*) () from /Users/colinww/system-model/build/chfilt.cpython-37m-darwin.so
#4 0x000000010002f1b8 in _PyMethodDef_RawFastCallKeywords ()
#5 0x000000010003be64 in _PyMethodDescr_FastCallKeywords ()
As I mentioned above, I think the problem starts in the initial compilation step. This has nothing to do with cython, I'm just calling gcc from the command line, passing the -g flag.
(base) cmac-2:system-model colinww$ gcc --version
Configured with: --prefix=/Applications/Xcode.app/Contents/Developer/usr --with-gxx-include-dir=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.4)
Target: x86_64-apple-darwin18.6.0
Thread model: posix
InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin
Any help is appreciated, thank you!
UPDATE
I removed the gcc tag and changed it to clang. So I guess now I'm confused, if Apple will alias gcc to clang, doesn't that imply that in "that mode" it should behave like gcc (and, implied, someone made sure it was so).
UPDATE 2
So, I never could get the debug symbols to appear in the debugger, and had to resort to lots of interesting if-printf statements, but the problem was due to an index variable becoming undefined. So thanks for all the suggestions, but the problem is more or less resolved (until next time). Thanks!
The macOS linker doesn't link debug information into the final binary the way linkers usually do on other Unixen. Rather it leaves the debug information in the .o files and writes a "debug map" into the binary that tells the debugger how to find and link up the debug info read from the .o files. The debug map is stripped when you strip your binary.
So you have to make sure that you don't move or delete your .o files after the final link, and that you don't strip the binary you are debugging before debugging it.
You can check for the presence of the debug map by doing:
$ nm -ap <PATH_TO_BINARY> | grep OSO
You should see output like:
000000005d152f51 - 03 0001 OSO /Path/To/Build/Folder/SomeFile.o
If you don't see that the executable probably got stripped. If the .o file is no around then somebody cleaned your build folder earlier than they should have.
I also don't know if gdb knows how to read the debug map on macOS. If the debug map entries and the .o files are present, you might try lldb and see if that can find the debug info. If it can, then this is likely a gdb-on-macOS problem. If the OSO's and the .o files are all present, then something I can't guess went wrong, and it might be worth filing a bug with http://bugreporter.apple.com.
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
Here's some sample test code I'm trying to run on an embedded Linux system:
#include <iostream>
int main(int argc, char *argv[])
{
char c = 'A';
int i = 7;
std::cout << "Hello World from C++" << std::endl;
std::cout << "c=" << c << std::endl;
std::cout << "i=" << i << std::endl;
}
The embedded system is a Microblaze, which is a 32-bit RISC softcore processor running on a Xilinx FPGA. Please don't be put off by that, as a lot of your standard Linux knowledge will still apply. The processor is configured as LSB with an MMU, and the Linux build I'm using (PetaLinux, supplied by Xilinx) is expecting the same. I'm using the supplied GNU compiler; Microblaze appears to be officially supported in GCC.
The problem I'm having is that when the stdlib needs to interact with the integer, it segfaults. Here's the output:
Hello World from C++
c=A
Segmentation fault
Note that the char is handled fine. The C equivalent of this code also works fine:
#include <stdio.h>
int main(int argc, char *argv[])
{
char c = 'A';
int i = 7;
printf("Hello World from C\n");
printf("c=%c\n", c);
printf("i=%i\n", i);
return 0;
}
...
Hello World from C
c=A
i=7
This leads me to suspect an issue with the shared library libstdc++.so.6.0.20. That library is supplied by Xilinx though, so it should be correct. The file output of that library is:
libstdc++.so.6.0.20: ELF 32-bit LSB shared object, Xilinx MicroBlaze 32-bit RISC, version 1 (SYSV), dynamically linked, not stripped
The file output of my binary is:
cpptest: ELF 32-bit LSB executable, Xilinx MicroBlaze 32-bit RISC, version 1 (SYSV), dynamically linked, interpreter /lib/ld.so.1, for GNU/Linux 2.6.32, stripped
I've also tried statically linking my binary using the -static flag, but the result was the same.
Here are the most relevant compiler and linker settings I'm using, but I've tried changing these with no avail.
CC=microblazeel-xilinx-linux-gnu-gcc
CXX=microblazeel-xilinx-linux-gnu-g++
CFLAGS= -O2 -fmessage-length=0 -fno-common -fno-builtin -Wall -feliminate-unused-debug-types
CPPFLAGS?=
CXXFLAGS= -O2 -fmessage-length=0 -fno-common -fno-builtin -Wall -feliminate-unused-debug-types
LDFLAGS=-Wl,-O1 -Wl,--hash-style=gnu -Wl,--as-needed
To compile:
#$(CCACHE) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o "$#"
To link:
#$(CXX) $(RELOBJECTS) $(LDFLAGS) $(EXT_LIBS) -o $(RELBINARY)
Note that microblazeel refers to the little endian version of the microblaze compiler.
I would very much like to debug this or at least look at a coredump, but no coredump seems to be produced when the segfault happens, and there's no gdb executable in the Microblaze Linux build. Maybe I'm missing something?
Thanks for taking your time to read this. Any thoughts?
From what I could see after a bit of research, vivado is the HW development IDE [because they offer a trial period--so it's the HW devel, which they always want to charge for].
If you're using the standard SDK board from Xilinx, everything should be preconfigured. Otherwise, a HW designer produces a HW design that has Microblaze in it.
From that, you may have to use petalinux to generate a new boot, kernel, etc. image that is compatible.
You may need to rebuild libstdc++ from source, but I'd do that as a last resort. For example, don't bother with it, until you've got gdb working and have test results.
Here are some petalinux PDF files:
http://www.xilinx.com/support/documentation/sw_manuals/petalinux2013_10/ug977-petalinux-getting-started.pdf
http://www.xilinx.com/support/documentation/sw_manuals/petalinux2013_10/ug981-petalinux-application-development-debug.pdf
The development guide shows how to invoke gdb (e.g.):
On the target system:
gdbserver host:1534 /bin/myapp
On the development system:
petalinux-utils --gdb myapp followed by target remote 192.168.0.10:1534
I've done some editing on your Makefile with annotations. I've commented out some of the non-essential options. Note that I'm using the += operator to build up CFLAGS/CXXFLAGS gradually
The basic idea here is to do a build with minimum deviations from "standard". Add only proven essential options. Build and test. Add back the options one-by-one [rebuild and test each time] until you find the option that is causing the problem.
I do, however, have a strong suspicion about -fno-common being a source of problems. Also, to a lesser extent, I'm a bit suspicious of -Wl,--as-needed
Should these options work? Sure, but xilinx/microblaze ain't no x86 ...
I've added two command line make variables:
DEBUG -- generate for debug with gdb
VERBOSE -- show everything about the build process
For example, try make <whatever> DEBUG=1 VERBOSE=1
CC = microblazeel-xilinx-linux-gnu-gcc
CXX = microblazeel-xilinx-linux-gnu-g++
CPPFLAGS ?=
CMFLAGS += -Wall -Werror
CMFLAGS += -fmessage-length=0
# compile for gdb session
# NOTES:
# (1) -gdwarf-2 may or may not be the the right option for microblaze
# (2) based on doc for -feliminate-unused-debug* petalinux/microblaze may want
# stabs format
ifdef DEBUG
CMFLAGS += -gdwarf-2
CMFLAGS += -O0
# compile for normal build
#else
CMFLAGS += -O2
CMFLAGS += -feliminate-unused-debug-types
endif
# NOTE: I used to use "#" on commands, but now I leave it off -- debug or not
# sure it's "ugly" but you can get used to it pretty quickly--YMMV
ifndef VERBOSE
Q :=
else
###Q := #
Q :=
endif
# let compiler/linker tell you _everything_:
# (1) configure options when tool was built
# (2) library search paths
# (3) linker scripts being used
ifdef VERBOSE
CMFLAGS += -v
LDFLAGS += -Wl,--verbose=2
endif
CMFLAGS += -fno-builtin
# NOTE: I'd _really_ leave this off as it may confuse c++ std as "<<" calls
# _M_insert (which is in the library, which is almost certainly _not_ using
# -fno-common)
###CMFLAGS += -fno-common
# NOTE: I'm also suspicious of this a little bit because the c++ lib may have
# some "weak" symbols that the c library doesn't
###LDFLAGS += -Wl,--as-needed
# NOTE: this seems harmless enough, but you can comment it out to see if it
# helps
LDFLAGS += -Wl,--hash-style=gnu
# NOTE: an optimization only
ifndef DEBUG
LDFLAGS += -Wl,-O1
endif
CFLAGS += $(CMFLAGS)
CXXFLAGS += $(CMFLAGS)
# NOTES:
# (1) leave this off for now -- doesn't save _that_ much and adds complexity
# to the build
# (2) IMO, I _never_ use it and I erase/uninstall it on any system I
# administrate (or just ensure the build doesn't use it by removing it
# from $PATH)--YMMV
###XCCACHE = $(CCACHE)
# to compile
$(Q)$(XCCACHE) $(CXX) $(CPPFLAGS) $(CXXFLAGS) $(CFLAGS) $< -o "$#"
# to link
$(Q)$(CXX) $(RELOBJECTS) $(LDFLAGS) $(EXT_LIBS) -o $(RELBINARY)
I'm near to frustration ;-). Since more than a week I try to crosscompile on my ubunutu 12.04 box i686 Linux machine for a ARMv6 machine (arm1176jzf-s - known as Raspberry Pi) an own developed program with LLVM 3.4.2.
After days I was able to compile and link successfully. But as I've tried to execute my code on the Raspberry Pi I only received a memory access error. It has turned out that a segmentation fault is raised. I have analyzed it with gdb. Please refer please to the enclosed picture.
.
Basically I have done the following:
I build the C and C++ files: #echo 'Compiling' $(1).$(2); cd $(BIN); $(4) -c $(COMPILE_FLAGS) ../$(3)/$(1).$(2) -o $(1).o $(LLVM_CONFIG_COMPILE); cd ..
I llvm-linked it: cd $(BIN); $(LINK) -o tl.bc $(1)
Then I called the system compiler: cd $(BIN); $(LLC) $(LINKER_FLAGS) -filetype=obj tl.thumb.opt.bc -o tl.thumb.opt.o
And I called the linker, i.e. the arm-linux-gnueabihf-g++: $(LD) -o bin/tl bin/tl.thumb.opt.o $(LINK_OPTION) $(THREAD_LIB_DIR) $(call INFLATE_config)
`test -f bin/tl` && echo 'Make was successful. Find Turbo Lisp in folder' $(BIN)
Take a look at my console output for my make file:
Building Turbo Lisp 0.01 for machine i686 with operating system GNU/Linux
COMPILE_FLAGS used:
-fno-strict-aliasing -emit-llvm -mfloat-abi=hard -mcpu=arm1176jzf-s -mfpu=vfpv3-d16 -mthumb -target arm-unknown-linux-gnueabihf -I/usr/include/arm-linux-gnueabihf/c++/4.6 -I/usr/include/arm-linux-gnueabihf/c++/4.6/arm-linux-gnueabihf -I/usr/lib/gcc/arm-linux-gnueabihf/4.6/include -I/usr/local/lib/LLVM_ARM/BOOST -ccc-gcc-name arm-linux-gnueabihf-gcc
Compiling precedence.cpp
Compiling util.cpp
Compiling ast.cpp
Compiling abstractParser.cpp
Compiling metaparser.cpp
Compiling parserLisp.cpp
Compiling parserToy.cpp
Compiling preconfiguredLanguages.cpp
Compiling handler.cpp
Compiling helper.cpp
Compiling lexer.cpp
Compiling config_reader.cpp
Compiling tl.cpp
Compiling external_functions.c
Compiling error_util.cpp
Building binary code from:
tl.o preconfiguredLanguages.o handler.o external_functions.o abstractParser.o parserLisp.o parserToy.o metaparser.o ast.o helper.o util.o error_util.o config_reader.o lexer.o precedence.o
Linking...
cd bin; <myhome>/projects/llvm-3.4.2.src/buildARMCompileX86/Release+Asserts/bin/llvm-link -o tl.bc tl.o preconfiguredLanguages.o handler.o external_functions.o abstractParser.o parserLisp.o parserToy.o metaparser.o ast.o helper.o util.o error_util.o config_reader.o lexer.o precedence.o
Optimizing...
cd bin; <myhome>/projects/llvm-3.4.2.src/buildARMCompileX86/Release+Asserts/bin/opt tl.bc -o tl.thumb.opt.bc -float-abi=hard -std-compile-opts
System compiling...
cd bin; <myhome>/projects/llvm-3.4.2.src/buildARMCompileX86/Release+Asserts/bin/llc -float-abi=hard -march=arm -mtriple=arm-unknown-linux-gnueabihf -filetype=obj tl.thumb.opt.bc -o tl.thumb.opt.o
...And finally linking to native...
arm-linux-gnueabihf-g++ -o bin/tl bin/tl.thumb.opt.o -v -L/usr/lib/arm-linux-gnueabihf -L/usr/local/lib/LLVM_ARM/BOOST -L/usr/local/lib/LLVM_ARM -L/usr/lib/arm-linux-gnueabihf -L/usr/local/lib/LLVM_ARM/BOOST -L/usr/local/lib/LLVM_ARM -lz -lpthread -lrt -ldl -lm -lLLVMInterpreter -lLLVMMCJIT -lLLVMJIT -lLLVMRuntimeDyld -lLLVMExecutionEngine -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMCodeGen -lLLVMObjCARCOpts -lLLVMScalarOpts -lLLVMInstCombine -lLLVMTransformUtils -lLLVMipa -lLLVMAnalysis -lLLVMARMAsmParser -lLLVMMCParser -lLLVMARMDesc -lLLVMARMInfo -lLLVMTarget -lLLVMCore -lLLVMARMAsmPrinter -lLLVMMC -lLLVMObject -lLLVMSupport -lpthread -ldl
`test -f bin/tl` && echo 'Make was successful. Find Turbo Lisp in folder' bin
Make was successful. Find Turbo Lisp in folder bin
It would be very nice, if anybody knowing much more about compiling for ARM could share his knowledge with me and direct me to the point I made so wrong.
Would like to comment but can't due to low "reputaion"...
Since you are "near to frustration" I would suggest trying gcc instead of LLVM because then it's likely easier to get help.
Eventually, I did it!
Maybe many of you are more interested in gcc than in LLVM and clang. But I think the issue here is more generally, than specific to LLVM. After I tried to compile LLVM and clang for ARM I ran another gdb session. It has turned out that glibc has different versions on my raspberry (2.13) and on my ubuntu (2.15). So I copied the libc from my ARM to my ubuntu system, but this didn't worked. I received messages from my gdb like "invalid machine instruction". This has caused me to check a bit more thoroughly the configure.log file of the clang build.
And, yes, the gcc cross compiler of ubuntu is simply compiled for an ARMv7 architecture, but the Raspberry is of ARMv6 (with ARM11 chip set).
So, the next point was to build my own gcc toolchain. First I tried to build my binutils, which allegedly was successful. Then I was heading to compile gcc linaro. And this has cost me days. At the end I hadn't achieved this mission. Either some include files were missing or linker issues have stopped me.
But I had the brilliant idea to make some more research, especially with keywords for the rasperry pi. And this has then pushed me back on track as I found crosstool-ng. What a great tool! You only need to configure in a kind of a menu which platform you like to address and then this tool downloads all your required files for a complete toolchain and installs it. Great! As I made this hurdle, it was pretty easy to build LLVM and clang.
The only point everybody needs to manage is to upgrade the Raspberry Pi, i.e. upgrade libc and libstdc++ by apt-get with the "testing" stage.
Feel free to ignore it or just check it out if you have also troubles to build up a correct gcc toolchain: Tutorial to setup crosstool-ng for RPi