Need to customize the linker in CodeBlocks - arduino

I am using CodeBlocks to compile Arduino projects. The default linker command is the following:
$avr-gcc -o bin/Release/test2.elf .objs/cores/CDC.o .objs/cores/HardwareSerial.o .objs/cores/HID.o .objs/cores/IPAddress.o .objs/cores/main.o .objs/cores/new.o .objs/cores/Print.o .objs/cores/Stream.o .objs/cores/Tone.o .objs/cores/USBCore.o .objs/cores/WInterrupts.o .objs/cores/wiring.o .objs/cores/wiring_analog.o .objs/cores/wiring_digital.o .objs/cores/wiring_pulse.o .objs/cores/wiring_shift.o .objs/cores/WMath.o .objs/cores/WString.o .objs/libraries/libraries.o .objs/test2.o -Wl,--gc-sections -Os -mmcu=attiny84 -lc -lm
The Arduino IDE uses a different approach. It uses avr-ar to create a single library and then performs a link on it:
/usr/bin/avr-ar rcs build-attiny84at1/libcore.a build-attiny84at1/WInterrupts.o build-attiny84at1/wiring_analog.o build-attiny84at1/wiring.o build-attiny84at1/wiring_digital.o build-attiny84at1/wiring_pulse.o build-attiny84at1/wiring_shift.o build-attiny84at1/CDC.o build-attiny84at1/HardwareSerial.o build-attiny84at1/HID.o build-attiny84at1/IPAddress.o build-attiny84at1/main.o build-attiny84at1/new.o build-attiny84at1/Print.o build-attiny84at1/Stream.o build-attiny84at1/Tone.o build-attiny84at1/USBCore.o build-attiny84at1/WMath.o build-attiny84at1/WString.o
/usr/bin/avr-gcc -mmcu=attiny84 -Wl,--gc-sections -Os -o build-attiny84at1/test.elf build-attiny84at1/sketch.o build-attiny84at1/test.o build-attiny84at1/libcore.a -lc -lm
My problem is the CodeBlocks link statement results in code that is substantially larger. The only difference I can see between the two is that the Arduino way creates a single library first. When I compared the disassembly (.lss file) of the two, the Arduino one had a nice tight file with the source code interspersed. In contrast, the CodeBlocks one had a lot of mystery code, and there were none of my source code statements.
Is there a way to get CodeBlocks to create a library via avr-ar first, and then link with that? That seems to be my problem, or am I missing something?

Related

Can you run a user-defined pass before ASAN sanitizer?

I compile my code with -fsanitize=address switch. I have my own llvm pass that I want to execute. By the time the pass starts, I can see that the ASAN pass was made. Is it possible to run my pass before the ASAN pass?
I‘ve also tried to run my pass before the ASAN pass in different ways to instrument my program at BasicBlock-level.
And this seems to be available for me:
Register a "StandardPasses" with EP_EarlyAsPossible flag which makes your pass works earlier than ASAN.
static RegisterStandardPasses Y(PassManagerBuilder::EP_EarlyAsPossible,
[](const PassManagerBuilder &Builder,
legacy::PassManagerBase &PM) {
PM.add(new MyPass());
});
Compile your pass as a ".so" file.
Then use clang -Xclang -load -Xclang xxYourPassxx.so -fsanitize=address main.c -o main to compile your code.
I also compiled the main.bc & main.ll for checking. And the results show me that my instrumentation doesn't appear in ASAN's block (Because my pass runs before ASAN).

ld : 0711-224 warning : Duplicate symbol (Overriding a System Call in AIX)

I read this article (http://qasim.zaidi.me/2009/05/overriding-system-call-in-aix.html;) about overriding a systemcall in aix;
I wrote two kernel extensions just like the article said "The first kernel extension would merely re-export the original system call with a different name. The second, will actually override the syscall by redefining it, and then call the original one as exported by the first module."
But there is a error when I make the second extension:
1> gcc -O2 -maix64 -ffreestanding -o my_syscall.o -c my_syscall.c -D_KERNEL
1> ld -b64 -o my_syscall my_syscall.o -e my_syscall_init -bI:/home/rabbitte/output/test_system/my_syscall.exp -bI:/usr/lib/kernex.exp -lsys -lcsys
1>ld : 0711-224 warning : Duplicate symbol: .getpid
1> ld: 0711-345 Use the -bloadmap or -bnoquiet option to obtain more information.
The file "/home/rabbitte/output/test_system/my_syscall.exp" is the export file of the first extension.
I don't understand the what the "Duplicate symbol: .getpid" means. Could you tell me how to solve this problem?
Thanks very much.
The reason is that the file “kernex.exp” also include the symbol “getpid”. I should comment the getpid in file kernex.exp.
I've never done any of this, so this might not be sufficient to solve your problem, but your linker line has two -bI options. It should be -bI for the AIX kernex.exp, and -bE for your exp file according to the docs you point to.

Clang + AVR Compilation error: '=w' in asm

I got this error below and I can not find a solution. Does anybody know how
to fix this error?
rafael#ubuntu:~/avr/projeto$ clang -fsyntax-only -Os -I /usr/lib/avr/include -D__AVR_ATmega328P__ -DARDUINO=100 -Wno-ignored-attributes -Wno-attributes serial_tree.c
In file included from serial_tree.c:3:
In file included from /usr/lib/avr/include/util/delay.h:43:
/usr/lib/avr/include/util/delay_basic.h:108:5: error: invalid output
constraint
'=w' in asm
: "=w" (__count)
^
1 error generated.
util/delay.h is a Header from avr-libc, and the feature which you are using (some of the delay stuff) is using inline asm to implement it. avr-libc is written to be used with avr-gcc and uses features from avr-gcc like machine dependent constrains in inline asm. llvm does not recognize constraint "w", thus you have to use a different approach like using avr-gcc or porting that code to llvm.
avr-gcc also implements built-in function __builtin_avr_delay_cycles to implement wasting a specified number of clock cycles. If llvm is properly mimicking avr-gcc, then you can use that function as a starting point.

blackfin gcc-toolchain linking error math function like atan2 :undefined reference to ... within watan2.o

I've a problem with the classic math function linking of my bare metal program with blackfin tool chain linker. I tried many things but I cannot see why the libm.a does't provide the definitions for the function it use. Do I need to add an extra library? if yes which one?
I've put my linker verbose lign with linked libraries and the example linking error I got.
Thanks,
William
bfin-elf-ld -v -o test_ad1836_driver -T coreb_test_ad1836_driver.lds --just-symbol ../../icc_core/icc queue.o ezkit_561.o heap_2.o port.o tasks.o test_ad1836_driver.o list.o croutine.o user_isr.o bfin_isr.o app_c.o context_sl_asm.o cycle_count.o CFFT_Rad4_NS_NBRev.o fir_decima.o fir_decima_spl.o math_tools.o -Ttext 0x3c00000 -L /opt/uClinux/bfin-elf/bfin-elf/lib -lbffastfp -lbfdsp -lg -lc -lm -Map=test_ad1836_driver.map
argv[0] = 'bfin-elf-ld'
bindir = '/opt/uClinux/bfin-elf/bin/'
tooldir = '/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/'
linker = '/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/ld.real'
elf2flt = '/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/elf2flt'
nm = '/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/nm'
objdump = '/opt/uClinux/bfin-elf/bin/bfin-elf-objdump'
objcopy = '/opt/uClinux/bfin-elf/bin/bfin-elf-objcopy'
ldscriptpath = '/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/../lib'
Invoking: '/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/ld.real' '-v' '-o' 'test_ad1836_driver' '-T' 'coreb_test_ad1836_driver.lds' '--just-symbol' '../../icc_core/icc' 'queue.o' 'ezkit_561.o' 'heap_2.o' 'port.o' 'tasks.o' 'test_ad1836_driver.o' 'list.o' 'croutine.o' 'user_isr.o' 'bfin_isr.o' 'app_c.o' 'context_sl_asm.o' 'cycle_count.o' 'CFFT_Rad4_NS_NBRev.o' 'fir_decima.o' 'fir_decima_spl.o' 'math_tools.o' '-Ttext' '0x3c00000' '-L' '/opt/uClinux/bfin-elf/bfin-elf/lib' '-lbffastfp' '-lbfdsp' '-lg' '-lc' '-lm' '-Map=test_ad1836_driver.map'
GNU ld version 2.17
/opt/uClinux/bfin-elf/bfin-elf/lib/libm.a(w_atan2.o): In function `atan2':
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/w_atan2.c:96: undefined reference to `__eqdf2'
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/w_atan2.c:96: relocation truncated to fit: R_BFIN_PCREL24 against undefined symbol `__eqdf2'
.....
/opt/uClinux/bfin-elf/bfin-elf/lib/libm.a(e_sqrt.o): In function `_ieee754_sqrt':
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/e_sqrt.c:110: undefined reference to `__muldf3'
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/e_sqrt.c:110: undefined reference to `__adddf3'
.....
/opt/uClinux/bfin-elf/bfin-elf/lib/libm.a(s_atan.o): In function `atan':
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/s_atan.c:169: undefined reference to `__muldf3'
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/s_atan.c:170: undefined reference to `__muldf3'
/usr/src/packages/BUILD/blackfin-toolchain-2010R1/gcc-4.3/newlib/libm/math/s_atan.c:172: undefined reference to `__muldf3'
Add -lgcc. You need the functions to compare, add and multiply C double type values, respectively, __eqdf2, __adddf3 and __muldf3.
Usually, I'd recommend using the compiler driver (gcc) instead of linking directly with ld, even for firmware/kernel type outputs, because the former will take care of the necessary startup files and compiler runtime libraries.
Hi I think I know the problem, blackfin is not really compatible with the maths std lib. It is why in the VDSP version the maths functions are re implemented. To solve my problem, I did convert the VDSP maths lib to gcc and it compile fine now.
Thanks
Actually I found a better answer,
blackfin does in fact support std math. I just had some library flag in the wrong order.
For the linker, use the following lib flag order and it should work:
/opt/uClinux/bfin-elf/bin/../bfin-elf/bin/ld.real' '-v' '-o' .... '-L' '/opt/uClinux/bfin-elf/lib/gcc/bfin-elf/4.3.5/' '-lgcc' '-L' '/opt/uClinux/bfin-elf/bfin-elf/lib' '-lbfdsp' '-lg' '-lm' '-lbffastfp' '-lc'

CMake, Qt, gcc and precompiled headers

I'm (once again) struggling with the creation of precompiled headers in conjunction with gcc and Qt on the Apple platform.
When now creating my precompiled header I use a code section (based on good old "PCHSupport_26.cmake") to extract the compile flags as follows:
STRING(TOUPPER "CMAKE_CXX_FLAGS_${CMAKE_BUILD_TYPE}" _flags_var_name)
SET(_args ${CMAKE_CXX_FLAGS} ${${_flags_var_name}})
GET_DIRECTORY_PROPERTY(DIRINC INCLUDE_DIRECTORIES )
FOREACH(_item ${DIRINC})
LIST(APPEND _args "-I${_item}")
ENDFOREACH(_item)
GET_DIRECTORY_PROPERTY(_defines_global COMPILE_DEFINITIONS)
LIST(APPEND defines ${_defines_global})
STRING(TOUPPER "COMPILE_DEFINITIONS_${CMAKE_BUILD_TYPE}" _defines_for_build_name) GET_DIRECTORY_PROPERTY(defines_build ${_defines_for_build_name})
LIST(APPEND _defines ${_defines_build})
FOREACH(_item ${_defines})
LIST(APPEND _args "-D${_item}")
ENDFOREACH(_item ${_defines})
LIST(APPEND _args -c ${CMAKE_CURRENT_SOURCE_DIR}/${PRECOMPILED_HEADER} -o ${_gch_filename})
SEPARATE_ARGUMENTS(_args)
Unfortunately the above compiler flags miss two important parameter that CMake does generate when using the build-in compiler rules:
-DQT_DEBUG
and when compiling with the generated precompiled header, I get errors as follows:
file.h: not used because QT_DEBUG is defined.
I would need your help with the following:
Is the above way to retrieve the compiler flags correct ?
Is there a better, easier, simpler way to do this ?
Why does -DQT_DEBUG not show up in COMPILE_DEFINITIONS or COMPILE_DEFINITIONS_${CMAKE_BUILD_TYPE}
If you are using XCode simply:
SET_TARGET_PROPERTIES(${target} PROPERTIES XCODE_ATTRIBUTE_GCC_PRECOMPILE_PREFIX_HEADER YES)
SET_TARGET_PROPERTIES(${target} PROPERTIES XCODE_ATTRIBUTE_GCC_PREFIX_HEADER "${target}/std.h")
I'm trying myself to use precompiled headers with raw gcc on linux through CMake but I haven't still figured it out. It look like it's working but I don't see any speed improvements.
Edit:
I managed to use pch in gcc finally with the macro you can find here: http://www.mail-archive.com/cmake#cmake.org/msg04394.html

Resources