I am trying to use fft functions in my application code for particle-photon. I have managed to link my library to the cmsis prebuilt-library for Cortex M3. However when I call the actual fft function:
arm_rfft_q31( &rfftStruct, buffer, buffer); // in-place fft
The build fails with an undefined reference:
/u/susom/cmsis-integ/CMSIS/Lib/libarm_cortexM3l_math.a(arm_cfft_q31.o): In function `arm_cfft_q31':
/u/susom/cmsis-integ/CMSIS/DSP_Lib/TransformFunctions/arm_cfft_q31.c:139: undefined reference to `arm_bitreversal_32'
The arm_bitreversal_32 happens to be a routine implemented in assembly in enter link description here
Any idea as to how to overcome this issue.
There are two library entries in the project
modal windows (only available if you have the project selected in eclipse
then you can it it from properties of menu project).
One of them seems to be cosmetic. You need the one under build
in the linker section.
Eclipse seems to randomly remove this entry sometimes, which to put it mildly
is extremely unhelpful.
open project properties -> C/C++ Build -> Settings -> MCU GCC Linker -> Libraries:
Add a library (the top one)
"arm_cortexM4lf_math"
do not put ".a" at the end or a "lib" in the start (you'd have thought they would have regex guarded that but no)
The the path:
something like this
"${workspace_loc:/${ProjName}/Middlewares/ST/ARM/DSP/Lib}"
BTW: use CUBEMX to load in the DSP libraries and remeber to tick the ever so useful "enable" box or it wont work.
Related
Is there a way to produce a C static library from Go code, but without Go runtime function definitions?
Rationale:
Project A creates a C static library with go build -buildmode=c-archive, libA.a .
Works well: project B uses pure C and is able to easily create an executable, statically linking with libA.a, all is fine.
Problem 1: project C happens to also use Go, but would like to use libA.a as a regular C library. Now it has a link problem: the Go runtime functions such as e.g. _cgo_panic are now defined both in project C runtime (as it uses Go) and in libA.a.
Problem 2: project D uses pure C, same as B. Yet it wants to use two different libraries from project A, e.g. libA.a and some libA2.a. Sadly, it does not link either, because Go runtime functions are now defined in both libA.a and libA2.a.
The problems faced by project C and project D could be easily resolved if project A could produce its libraries without the Go runtime definitions inside. Project C could just link with libA.a. Project D would link with libA.a, libA2.a and some libGo.a that would contain definitions of all the Go runtime stuff.
What I tried:
Using linker flags at 'project C' level, such as -Wl,--allow-multiple-definition. Now its build fails with a cryptic message 'function symbol table not sorted by program counter'.
Manually removing go.o from 'libA.a' (as it's just an "ar" archive): didn't work as 'go.o' also contained implementations of my exported functions, so I've removed too much.
Using go build -buildmode=c-shared. As expected, it produces a dynamic library which uses another format, so I could not directly use it as a static library.
Any solution at the client side (such as finding a proper way to ignore duplicate definitions at the link stage for project C) would be also considered a valid answer.
I can also accept a negative answer (no solution) if it provides enough evidence.
Update: see a related question Is there a way to include multiple c-archive packages in a single binary
With the current implementation it's not going to work to use -buildmode=c-archive multiple times and put the results into multiple shared libraries, as you've discovered. The essential problem is that there has to be only one Go runtime, but you have multiple runtimes. When using -buildmode=c-archive there's no way to isolate the different runtimes.
The -buildmode=c-shared libraries differ from buildmode=c-archive in that they are built with -Bsymbolic which forces all their local references to be local. The effect is that we have multiple Go runtimes, but they don't refer to each other so there is no confusion.
You could try adding -Wl,-Bsymbolic to build each shared library that includes Go code in c-archive if your C code doesn't mind being linked with -Bsymbolic.
I wish you luck.
Recently I've got interested in learning the heap management of C (the malloc module). I want to break the malloc source files(e.g., malloc.c, arena.c) into smaller files so it's easier to read and study for me. I'm using the glibc 2.23 and have successfully built it locally (in a separate "build" folder) on Ubuntu 14.04 following the instructions on wiki.
As my initial attempt, I put the __malloc_assert into the files massert.h and massert.c but then realized I have no idea how to add them to the makefiles so they can get compiled and linked.
Since I moved __malloc_assert out of malloc.c, I got the link errors when running make again, which was expected:
/home/mvs/git/glibc/build/libc_pic.os: In function `detach_arena':
/home/mvs/git/glibc/malloc/arena.c:629: undefined reference to `__malloc_assert'
/home/mvs/git/glibc/build/libc_pic.os: In function `mremap_chunk':
/home/mvs/git/glibc/malloc/malloc.c:2832: undefined reference to `__malloc_assert'
/home/mvs/git/glibc/malloc/malloc.c:2813: undefined reference to `__malloc_assert'
/home/mvs/git/glibc/malloc/malloc.c:2812: undefined reference to `__malloc_assert'
/home/mvs/git/glibc/malloc/malloc.c:2830: undefined reference to `__malloc_assert'
/home/mvs/git/glibc/build/libc_pic.os:/home/mvs/git/glibc/malloc/malloc.c:2776: more undefined references to `__malloc_assert' follow
I thought I should look at how the malloc/malloc.c is used in the makefiles, but I couldn't find where it is used. I'm mainly looking at the following files:
glibc/Makeconfig
glibc/Makefile
glibc/Rules
glibc/malloc/Makefile
Alternatively, I've searched the makefile on libc-help mailing list and looked at all the results but didn't find one that matches what I want. Two of the threads, "glibc + add new function" and "Adding a function to glibc?", were talking about adding a new function to the library, which is not my case (I'm not adding new function but merely restructuring the code).
I'm kind of new to the makefile system and still reading the GNU makefile manual, but thought shooting an email here may get me out of the struggle more quickly.
Thanks!
You need to add massert (not massert.c) to the routines variable in malloc/Makefile.
There are several such variables: routines is for libc it self, but there is also libm-routines for libm, and so on.
By default, these source files are built for all variants: static (.o), shared (.os), profiling (.op, profiling builds are disabled by default though). Some special functions are only intended for static builds (.oS, they go into libc_nonshared.a) and are listed in static-only-routines as well. Specific build targets can be excluded using the elide-routines.os variable.
I am struggling to get my code down to minimal bare bones size! I am using a STM32F0 with only 32k flash and need a good part of the flash for data storage. My code is already at approx 20k flash size! Some of this is due to use of the STM32 HAL functions which I can account for and optimise later if needed.
However, my biggest consumer of flash is all the implicitly included library routines. I can not seem to remove these functions. They are not called anywhere in my code or any HAL code. Functions such as _malloc_r (1.3k Bytes), and __vfiprintf_r (3kB) and many others are using a large part of my flash. I think these are all the libc functions. I do not use these and would like them gone!
Does anybody know how to remove these?
I have tried different optimisation levels and linker options but no luck so far. I have tried -nostdlib and --specs=nosys.specs with no change. If I remove my file with definitions for functions such as _exit I get a linker error suggesting that the library is still included and needs these. Also linker map confirms presence of a lot of unwanted functions!
Any suggestions?
When you are wondering about what takes space, or why functions and libraries have been linked in, generate a map file with cross references - something like "-Wl,-Map=program.map,--cref". Look at the file with a text editor, and you can see why a function like malloc has been included.
Solved... Some of my code included and called assert. The moment I removed assert calls my code size more than halved! I instead used the STM32 HALs assert_param macro that is a light weight assert that just redirects to a user defined function.
It would be helpful if someone could explain to me how gcc decides to include library functions when assert is called? I see that assert.h declares an external function __assert_func. How does the linker know to reference it from a library rather than just say "undefined reference to __asert_func"?
I have an autotools C project.
How do I compile a binary which works with both libcrypto.so.0.9.8 and libcryto.so.1.0.0? (i.e. Ubuntu 9.10 and 12.04)
Depending on the age of the OS on which I do the build, the binary requires one version or the other.
Is there a way of making it not care, or are the differences between the libcryto versions insurmountable?
In my opinion, you want to use some function of libcrypto.so.0.9.8 and some from libcryto.so.1.0.0. If most of the functions are required from 1.0.0 or is preferred choice then link with libcrypto.so.1.0.0.
And you may need some function from libcrypto.so.0.9.8 or you may have other good reasons to use libcrypto.so.0.9.8.
In my view, if you link from both the library, you will get linker error (duplicate symbols as both of the library contains same symbols).
If you need to use 0.9.8, then load it dynamically using dlopen and get the function callback which you want use with dlsym.
This can be accomplished as follows:
void * handle;
/*reqd_callback is the callback of required function.*/
reqd_callback cb;
handle = dlopen ("libcrypto.so.0.9.8", RTLD_LAZY);
cb = (reqd_callback)dlsym(handle, "reqd_function");
//Call the cb
cb (parameters);
//Close the library.
dlclose(handle);
I think this may solve your purpose. If the preference is inverse, invert the library in linking and in loading through program.
Can you make a soft link that will "point" to either libcrypto.so.0.9.8 or libcryto.so.1.0.0.
Give it a generic name and then use that, then whatever version of the library the link "points" to, will be picked up? On app install, you set your soft link to point to the library version available. Your software might be tested up to 1.0.0 if the lib is backward compatible enough, i.e. you don't rely on somthing in 1.0.0 that's not in 0.9.8, your ok.
You can rebuild ssl-0.9.8 (not 1.x because it contains some things that won't work on the older version) and change the line in the makefile where it does the final shared library linkage and embeds the SONAME
recompile it with the SONAME changed from libssl.so.0.9.8 to libssl.so.0
it will look something like: -Wl,-soname,libssl.so.0.9.8
change it to: -Wl,-soname,libssl.so.0
now when you compile against this library the binaries built against it will look for libssl.so.0 (which is included as a symlink in both versions)
Using TinyCC in my C program lets me use C as a sort of scripting language, reload C files on the fly, and do a lot of fairly neat things... But, one thing is really bothering me. Linking.
I do my normal tcc_new, and tcc_set_output_type with TCC_OUTPUT_MEMORY, but if I don't include a lot of these:
tcc_add_symbol(tcc_ctx, "printf", &printf);
tcc_add_symbol(tcc_ctx, "powf", &powf);
tcc_add_symbol(tcc_ctx, "sinf", &sinf);
everything is very limited.
I want a way to automatically bring in all symbols in the host program. I don't want to have to manually link in every last function in libc, and libm. What mechanisms exist to facilitate auto linking, or adding of symbols. How can I use libm in my code without manually dropping in every last component.
I'm currently using GCC, but on another platform use Visual Studio to compile my program. I could switch entirely to TCC.
TCC comes with a rudimentary runtime library libtcc1. It includes basic functions like those you mention. Therefore, in most cases you can replace all your calls with a single tcc_add_library(tcc_ctx, "libtcc1.a").
libtcc1 is not complete, so you might have to add manually some functions.