I have been working on porting a project from Visual Studio/VisualGDB running on a Win10 machine to a CMake/GCC build system running on Ubuntu 16.04. The complete build will eventually run on a Cortex-M4.
In this process, I encountered a linker issue where several references within libc are undefined
{...}/arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libg_nano.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
{...}/arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libg_nano.a(lib_a-writer.o): In function `_write_r':
writer.c:(.text._write_r+0x10): undefined reference to `_write'
{...}/arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libg_nano.a(lib_a-closer.o): In function `_close_r':
closer.c:(.text._close_r+0xc): undefined reference to `_close'
{...}/arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libg_nano.a(lib_a-fstatr.o): In function `_fstat_r':
fstatr.c:(.text._fstat_r+0xe): undefined reference to `_fstat'
{...}/arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libg_nano.a(lib_a-isattyr.o): In function `_isatty_r':
isattyr.c:(.text._isatty_r+0xc): undefined reference to `_isatty'
{...}/arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libg_nano.a(lib_a-lseekr.o): In function `_lseek_r':
lseekr.c:(.text._lseek_r+0x10): undefined reference to `_lseek'
{...}/arm-none-eabi/lib/thumb/v7e-m/fpv4-sp/hard/libg_nano.a(lib_a-readr.o): In function `_read_r':
readr.c:(.text._read_r+0x10): undefined reference to `_read'
I use the following flags:
CFLAGS:
-fdata-sections -ffunction-sections -std=gnu99 -mabi=aapcs -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16
ASM_FLAGS:
-x assembler-with-cpp
LDFLAGS:
-static -Wl,--gc-sections -mabi=aapcs -mcpu=cortex-m4 -mthumb -mfloat-abi=hard -mfpu=fpv4-sp-d16 --specs=nano.specs -lc -lnosys
These flags are from the original VisualGDB-build which build without any problems.
I found that when using --specs=nosys.specs instead of nano.specs, the build completes, but when running on target, a hard fault is triggered somewhere inside __libc_init_array().
My suspicions are that this is due to the difference between nano.specs and nosys.specs, however I am unable to verify this due to the linker issues mentioned above. I tried the combination <...> --specs=nono.specs --specs=nosys.specs -lc -lnosys without any luck.
Does anyone know why this works with VisualGDB and not with CMake/GCC? As far as I understand, VisualGDB still use arm-none-eabi? This is of course the same toolchain I am using (tested versions 4.9.3 and 6.3.1)
Related
I am building an executable ("tool") on Linux. Using include $(GNUSTEP_MAKEFILES)/tool.make.
It's linked to a static lib that has also be build with GNUstep. The lib
contains Categories.
The executable builds fine but has errors at runtime not recognizing
methods defined in the static lib's Category:
Uncaught exception NSInvalidArgumentException, reason:
ClassNameOfClassTheCategoryExtends(instance) does not recognize
nameOfMethodInCategory
I am trying to fix that by passing -ObjC to the linker flags (also
tried -all_load) in the executable's GNUmakefile:
ADDITIONAL_LDFLAGS = -ObjC -all_load
But that seems to be ignored by clang. Here is the relevant output of
make install messages=yes debug=yes
clang: warning: argument unused during compilation: '-ObjC'
[-Wunused-command-line-argument]
clang: warning: argument unused during compilation: '-all_load'
[-Wunused-command-line-argument]
It looks like ADDITIONAL_LDFLAGS are used compiling, not linking.
Using this leads to the same result:
LDFLAGS := $(LDFLAGS) -ObjC
The excecutables GNUmakefileincludes the following:
include $(GNUSTEP_MAKEFILES)/common.make
# My make
include $(GNUSTEP_MAKEFILES)/tool.make
The resulting command line output is:
$ make install messages=yes debug=yes
This is gnustep-make 2.9.0. Type 'gmake print-gnustep-make-help' for help.
Running in gnustep-make version 2 strict mode.
Making all for tool NameOfExcecutable...
clang -ObjC -fuse-ld=/usr/bin/ld.gold -pthread -fexceptions -rdynamic -fobjc-runtime=gnustep-2.0 -fblocks -o obj/NameOfExcecutable \
./obj/NameOfExcecutable.obj/main.m.o ./obj/NameOfExcecutable.obj/MyClass.m.o ./obj/NameOfExcecutable.obj/StreamRunLoop.m.o ./obj/NameOfExcecutable.obj/Connector.m.o ./obj/NameOfExcecutable.obj/HTTPClient.m.o \
-L/home/user/GNUstep/Library/Libraries -L/usr/GNUstep/Local/Library/Libraries -L/usr/GNUstep/System/Library/Libraries -lgnustep-base -ldispatch -l/path/to/libOwnLib1.a -l/path/to/libOwnLib2.a -l/path/to/libOwnHavingTheCategories.a -l/path/to/libOwnLib4.a -l/path/to/libOwnLib5.a -luuid -lz -lpthread -ldl -lpthread -lobjc -lm
clang: warning: argument unused during compilation: '-ObjC' [-Wunused-command-line-argument]
Question:
What am I doing wrong
or
How can I work around the issue?
After digging into the issue of the linker not knowing the -ObjC flag (which we are used to use in Xcode) it looks like:
only ld.ld64 is aware of this flag
ld.ld64 is a (too genericly named) "linker for macOS" (from LLDB.org)
thus is not available for Linux linkers
To workaround we first stopped using GNUstep makefiles to
disable all GNUstep magic understand what is going on and wrote our own makefiles.
The actual fix to force link/load all .o files was to explicitly pass --whole-archive to the linker:
-Wl,-whole-archive path/to/static/lib/containing/categories/libOwnLib1.a -Wl,-no-whole-archive
I'm trying to compile Objective-C or .m file using command-line (generated by CMake) for Catalyst, but am stuck with two compile errors!
1. Whenever I enable Catalyst with one of below flags:
-target x86_64-apple-ios-macabi
-target x86_64-apple-ios13.0-macabi
-target x86_64-apple-ios13.5-macabi
-target x86_64-apple-ios13.7-macabi
2. Then force rebuild (click Clean Build Folder, then Build).
3. The build fails with error:
fatal error: 'UIKit/UIKit.h' file not found
4. But once I switch to 13.6, I mean, change the flag to:
-target x86_64-apple-ios13.6-macabi
5. Then force-rebuild, I get a new error:
error: target Objective-C runtime differs in PCH file vs. current file
Note that I am not using any PCH file, and both errors seem completely confusing.
Also, I searched and found post similar to second error, but the fix suggested (namely, switching to 13.6) is the cause of the second error.
(Was supposed to fix it, yet is triggering it).
After capturing Xcode's full command-line, I noticed that it had -x objective-c flag while my CMake had not!
After searching (about how CMake support's Obj-C),
found actual mistake!
1. Basically, CMake needed me to do something like:
project(MyProject C CXX OBJC OBJCXX)
Instead of:
project(MyProject)
2. Also, should add Obj-C flags into CMAKE_OBJC_FLAGS instead of CMAKE_C_LINK_FLAGS variable.
3. Now CMake automaticaly adds missing -x objective-c flag, and I just need to add my custom flags.
Full Xcode command-line:
-x objective-c -target x86_64-apple-ios13.6-macabi -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -fobjc-arc -fmodules -gmodules -fmodules-cache-path=/Users/admin/Library/Developer/Xcode/DerivedData/ModuleCache.noindex -fmodules-prune-interval=86400 -fmodules-prune-after=345600 -fbuild-session-file=/Users/admin/Library/Developer/Xcode/DerivedData/ModuleCache.noindex/Session.modulevalidation -fmodules-validate-once-per-build-session -fmodule-name=MyProject -fapplication-extension -fpascal-strings -O0 -fno-common -DDEBUG=1 -DOBJC_OLD_DISPATCH_PROTOTYPES=0 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk -fasm-blocks -fstrict-aliasing -g -fprofile-instr-generate -fcoverage-mapping -index-store-path /MyBuildDir/Index/DataStore -iquote /MyBuildDir-cofig/MyProject-generated-files.hmap -I/MyBuildDir-cofig/MyProject-own-target-headers.hmap -I/MyBuildDir-cofig/MyProject-all-non-framework-target-headers.hmap -ivfsoverlay /MyBuildDir-cofig/all-product-headers.yaml -iquote /MyBuildDir-cofig/MyProject-project-headers.hmap -I/MyProductDir/include -isystem /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/iOSSupport/usr/include -I/MyBuildDir-cofig/DerivedSources-normal/x86_64 -I/MyBuildDir-cofig/DerivedSources/x86_64 -I/MyBuildDir-cofig/DerivedSources -F/MyProductDir -iframework /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.15.sdk/System/iOSSupport/System/Library/Frameworks -MMD -MT dependencies -MF /MyBuildDir-cofig/Objects-normal/x86_64/my-source.d --serialize-diagnostics /MyBuildDir-cofig/Objects-normal/x86_64/my-source.dia -c /Users/admin/my-project/my-source.m -o /MyBuildDir-cofig/Objects-normal/x86_64/my-source.o
Note that I replaced paths to shorten above, like:
MyBuildDir => /Users/admin/Library/Developer/Xcode/DerivedData/MyProject-gczfeuobxydqjrfbdhwzpqjsseyr
MyBuildDir-config => /Users/admin/Library/Developer/Xcode/DerivedData/MyProject-gczfeuobxydqjrfbdhwzpqjsseyr/Build/Intermediates.noindex/MyProject.build/Debug-maccatalyst/MyProject.build/
MyProductDir => /Users/admin/Library/Developer/Xcode/DerivedData/MyProject-gczfeuobxydqjrfbdhwzpqjsseyr/Build/Products/Debug-maccatalyst
I am trying to compile openjdk 7 on my arm ubuntu:
make all ALLOW_DOWNLOADS=true DISABLE_HOTSPOT_OS_VERSION_CHECK=ok
Then I received this error:
g++ -DLINUX -D_GNU_SOURCE -DIA32 -I/home/darklord/Develop/jdk7/hotspot/src/share/vm/prims -I/home/darklord/Develop/jdk7/hotspot/src/share/vm -I/home/darklord/Develop/jdk7/hotspot/src/cpu/x86/vm -I/home/darklord/Develop/jdk7/hotspot/src/os_cpu/linux_x86/vm -I/home/darklord/Develop/jdk7/hotspot/src/os/linux/vm -I/home/darklord/Develop/jdk7/hotspot/src/os/posix/vm -I/home/darklord/Develop/jdk7/hotspot/src/share/vm/adlc -I../generated -DASSERT -DTARGET_OS_FAMILY_linux -DTARGET_ARCH_x86 -DTARGET_ARCH_MODEL_x86_32 -DTARGET_OS_ARCH_linux_x86 -DTARGET_OS_ARCH_MODEL_linux_x86_32 -DTARGET_COMPILER_gcc -DCOMPILER2 -DCOMPILER1 -fno-rtti -fno-exceptions -D_REENTRANT -fcheck-new -fvisibility=hidden -m32 -march=i586 -pipe -Werror -g -c -o ../generated/adfiles/adlparse.o /home/darklord/Develop/jdk7/hotspot/src/share/vm/adlc/adlparse.cpp
g++: error: unrecognized argument in option '-march=i586'
It seems it is trying compile using x86 configuration. So how can I make the build pass on ARM machine?
You have to specify proper architecture option for g++. Reference here.
-march=name
This specifies the name of the target ARM architecture. GCC uses this name to determine what kind of instructions it can emit when
generating assembly code. This option can be used in conjunction with
or instead of the -mcpu= option. Permissible names are: armv2',
armv2a', armv3',armv3m', armv4',armv4t', armv5',armv5t',
armv5te',armv6', armv6j',iwmmxt', `ep9312'.
Please make sure you refer proper version docs of gcc
I'm trying to link a really simple GLES2 & EGL program using g++ 4.9.1, on a Ubuntu Trusty system. I'm using the mesa libraries.
I'm getting linker errors for EGL functions:
test.cpp:(.text+0x342): undefined reference to `eglGetDisplay'
test.cpp:(.text+0x389): undefined reference to `eglInitialize'
test.cpp:(.text+0x40f): undefined reference to `eglCreateContext'
test.cpp:(.text+0x458): undefined reference to `eglCreatePbufferSurface'
test.cpp:(.text+0x49e): undefined reference to `eglMakeCurrent'
I am compiling test.cpp with
g++ -std=c++0x -Wall -Werror -lEGL -lGLESv2 -o test test.cpp
I've tried switching the order of libraries, which sometimes matters, but I get the same problem. Is there a library I'm missing here?
I've run readelf -Ws /usr/lib/x86_64-linux-gnu/mesa-egl/libEGL.so and all of the required functions are defined.
You should put libraries to the end of a command line
g++ -std=c++0x -Wall -Werror -o test test.cpp -lEGL -lGLESv2
I managed to fix this by compiling the C++ file to an object file, and then linking as a separate step. I'm not sure why this works, when the one-line compilation doesn't.
g++ -std=c++0x -Wall -Werror -c -o test.o test.cpp
g++ -o test test.o -lGLESv2 -lEGL
I've put the question to the community to try to figure out why: Single-command compile and link fails, separate steps work
I'm trying to compile a simple c++ program to run inside ESXi 3.5 console window. It seems I'm linking with wrong libraries... Is there a setup described somewhere - which version of G++ and libraries do I have to be using in order to do so?
Here's how I resolved the issue. I did following to compile:
Compiled using gcc under ubuntu
Ran ldd on executable
Copied all libraries that showed up as dependencies to subfolder ESXi-3.5-lib. In my case they were:
ld-linux.so.2
libc.so.6
libgcc_s.so.1
libm.so.6
libstdc++.so.5
Added following switches to gcc:
-nodefaultlibs (to not attempt to link with default libs)
-lc (prevented link error in some crt library)
-fno-stack-protector (prevented another error, some other function was missing)
Following was my final build command:
g++ file1.cpp file2.cpp file3.cpp -o output-biinary-file-name \
ESXi-3.5-lib/ld-linux.so.2 ESXi-3.5-lib/libc.so.6 ESXi-3.5-lib/libgcc_s.so.1\
ESXi-3.5-lib/libm.so.6 ESXi-3.5-lib/libstdc++.so.5 \
-nodefaultlibs -lc -m32 -fno-stack-protector