Resolved
I'm currently working on LabWindows/CVI, this is a C. The only version of C supported is c99. I'm trying to integrate Google Flatbuffers (the c version flatcc) to my current project. When I'm trying to link my solution, I'm facing a linking error :
First question : how could I fix this error ?
According to the vendor, LabWindows/CVI use CLANG as compiler. if I take a look at the file where the symbol aligned_free /algined_malloc apear, I can read this :
/*
* NOTE: MSVC in general has no aligned alloc function that is
* compatible with free and it is not trivial to implement a version
* which is. Therefore, to remain portable, end user code needs to
* use `aligned_free` which is not part of C11 but defined in this header.
*
* glibc only provides aligned_alloc when _ISOC11_SOURCE is defined, but
* MingW does not support aligned_alloc despite of this, it uses the
* the _aligned_malloc as MSVC.
*
* The same issue is present on some Unix systems not providing
* posix_memalign.
*
* Note that clang and gcc with -std=c11 or -std=c99 will not define
* _POSIX_C_SOURCE and thus posix_memalign cannot be detected but
* aligned_alloc is not necessarily available either. We assume
* that clang always has posix_memalign although it is not strictly
* correct. For gcc, use -std=gnu99 or -std=gnu11 or don't use -std in
* order to enable posix_memalign, or live with the fallback until using
* a system where glibc has a version that supports aligned_alloc.
*
* For C11 compliant compilers and compilers with posix_memalign,
* it is valid to use free instead of aligned_free with the above
* caveats.
*/
Second question : According to the text above, I should have definition of aligned_free/aligned_malloc, but for some reason, I don't have it. Why ? What I'm missing ?
Additionnal information : LabWindows/CVI only accepte .lib as lib (no .a) so I had to compile flatcc using Cmake and MSVS19. I have try several configuration but nothing to do I always get the same error.
Best regard
EDIT : I fixed one undefined symbol '__allmul' by doing this cmake command :
cmake -G "MinGW Makefiles" -DCMAKE_C_COMPILER=x86_64-w64-mingw32-c99 -DFLATCC_PORTABLE=true -DFLATCC_ALLOW_WERROR=false -DBUILD_TESTING=false -DFLATCC_CXX_TEST=false -DFLATCC_REFLECTION=false -B .
Then editing flatcc\src\compiler\CMakeFiles\flatcc.dir\flags.make and flatcc\src\runtime\CMakeFiles\flatcc.dir\flags.make
to looks like that : C_FLAGS = -m32 -DFLATCC_REFLECTION=0 -Wstrict-prototypes -Wsign-conversion -Wconversion -std=c99 -pedantic -Wall -Wextra -DFLATCC_PORTABLE
-m32 is for 32 bit binary and -std=c99 instead of -std=c11 (can't put c89 because flatcc contain some inline keyword)
Then editing flatcc\src\compiler\CMakeFiles\flatcc.dir\link.txt and flatcc\src\runtime\CMakeFiles\flatcc.dir\link.txt to look like this :
...\bin\clang\bin\ar.exe rc ..\..\..\lib\flatcc.lib CMakeFiles/flatcc.dir/__/__/external/hash/cmetrohash64.c.obj ...
...bin\clang\bin\ranlib.exe ..\..\..\lib\flatcc.lib
Then running Mingw32-make.exe
2 errors remain :
Could you try to compile flatcc as a static library and force the output as .lib instead of the (by default) .a (with the "-o flatcc.lib" flag)? The problem I guess is that you're using two different compilers here (msvc and clang), on the same plateform (win32), and clang by default could have a "unix way of doing things". ;)
But actually the important point here I guess is from this comment quote:
Note that clang and gcc with -std=c11 or -std=c99 will not define *
_POSIX_C_SOURCE and thus posix_memalign cannot be detected but * aligned_alloc is not necessarily available either. We assume * that
clang always has posix_memalign although it is not strictly *
correct.
Maybe simply try to compile flatcc with clang and with the "-std=c89" flag to avoid any problem.
Do:
cmake -G "MinGW Makefiles" -DCMAKE_C_COMPILER=clang .
Then in the flatcc\src\compiler\CMakeFiles\flatcc.dir\flags.make file generated, you can change -std=c11 to -std=c89.
Then compile the project again with:
make
By default when I compile flatcc with mingw-32 on windows, I have the -std=c11 flag set (gcc version 7.3)
Well, to fix this issue, I had to compile flatcc Using clang in 32bit. To do this, I moved into flatcc directory and did :
cmake -G "MinGW Makefiles" -DCMAKE_C_COMPILER=x86_64-w64-mingw32-c99 -DFLATCC_PORTABLE=true -DFLATCC_ALLOW_WERROR=false -DBUILD_TESTING=false -DFLATCC_CXX_TEST=false -DFLATCC_REFLECTION=false -DFLATCC_USE_GENERIC_ALIGNED_ALLOC -B .
Then edited flatcc\src\compiler\CMakeFiles\flatcc.dir\flags.make and flatcc\src\runtime\CMakeFiles\flatcc.dir\flags.make to add -m32 to C_FLAGS :
C_FLAGS = -m32 -DFLATCC_REFLECTION=0 -Wstrict-prototypes -Wsign-conversion -Wconversion -std=c11 -pedantic -Wall -Wextra -DFLATCC_PORTABLE -DFLATCC_USE_GENERIC_ALIGNED_ALLOC
Then changed flatcc\src\compiler\CMakeFiles\flatcc.dir\link.txt and flatcc\src\runtime\CMakeFiles\flatcc.dir\link.txt to look like this :
...\bin\clang\bin\ar.exe rc ..\..\..\lib\flatcc.lib CMakeFiles/flatcc.dir/__/__/external/hash/cmetrohash64.c.obj ...
...bin\clang\bin\ranlib.exe ..\..\..\lib\flatcc.lib
Note: I just changed name of .a generated to .lib
Then finally I run mingw32-make.exe (or make.exe)
Thanks to Victor Gallet
Related
I am using (STM32F407VG-Discovey board) with compiler "gcc-arm-none-eabi-7-2017-q4-major" (arm-none-eabi-gcc) and I am trying to implement "google project flatbuffers". That needs for running time library malloc.h, and also heap memory.
I turn on heap memory on my ARM processor and tested it with include and and try basic operation calling malloc function. All works fine.
Now I include google flatbuffers header files and now I get error "undefined reference to `posix_memalign'". My linker can't find this function. It doesn't find but it should already have it posix_memalign in stdlib.h
Error looks like that:
In my CMake file I have set my flags to
SET(CMAKE_C_FLAGS "-mthumb -fno-builtin -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp -Wall -std=gnu11 -ffunction-sections -fdata-sections -fomit-frame-pointer -mabi=aapcs -fno-unroll-loops -ffast-math -ftree-vectorize -lc -lrdimon" CACHE INTERNAL "c compiler flags")
Also I figure out, if I don't use flag -lc and -lrdimo, there will be undefined reference to _write(), _read(), _sbrk, _exit .....
Explanation why this is not duplicate: I know adding, linker library with CMake you execute command target_link_libraries().
Problem here is that for non trivial reason my liner will not find posix_memalign function. But it will find other functions like malloc, alloc, free, ... They all are in "stdlib.h".
Try to use
#include <malloc.h>
void* p;
p = memalign(alignment, size);
instead of
posix_memalign(&p, alignment, size);
See also this link
Using -std=c99 was not a viable solution for our team because we have C11 code.
A better solution is to get flatcc to use the generic aligned alloc functions provided by flatcc instead of the posix ones.
In your build process, make sure that -DFLATCC_USE_GENERIC_ALIGNED_ALLOC is passed to your compilation command line to activate these generic versions.
Defining FLATCC_USE_GENERIC_ALIGNED_ALLOC activates the generic implementations of aligned allocations in include/flatcc/flatcc_alloc.c.
At ARM ToolChain official site under section 6.5.5. Alignment of C heap storage, it said for usage of function `posix_memalign´ you must use standard C99 not C11 as I have set.
So you must add in your CMAKE_C_FLAGS this flag: -std=c99
If you have set flag -std=c11 you should remove it.
A function, before being used, needs to be declared either in a included header or otherwise (though not a good practice). The header file describes the functions and variables that may be found in a library or an object file and the compiler can create (as of yet) unreferenced symbols to be resolved later whilst linking.
However, my compiler (gcc based toolchain called esp-open-sdk (xtensa CPU)) continues despite finding no reference to a function in the headers and only in the linking stage does the linker intimate of an `undefined reference to <-function-name->'.
Another strange behaviour is that the compiler says nothing if there is no return statement, and the function is not "void".
My question is: What is causing this behaviour? I think it's unlikely but is it some compiler flag?
My compiler flags are:
CFLAGS = -Os -g -O2 -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH
and the linker flags are:
LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static
Probably you use an old version of gcc. Before version 5.x, gcc defaults to a non-standard called "gnu90", which is a non-standard version of the obsolete C90 standard. There is no reason to ever use gnu90 unless you are maintaining some old Linux code. To avoid this, compile with:
-std=c11 -pedantic-errors
-std=c11 meaning you want the compiler to use the current C standard, without involving gnus or other strange animals. -pedantic-errors means that you want it to actually follow the standard and not just pretend to do it.
In order to get the warning for no return from functions, you need to use the option -Wreturn-type, which is included by using -Wall. Always compile with
-Wall -Wextra
Note that "Wall" does not stand for "all warnings", as it leads you to believe. Rather, -Wall means a fistful of warnings and -Wextra means a few warnings more.
This question already has answers here:
Why does the order in which libraries are linked sometimes cause errors in GCC?
(9 answers)
Closed 2 years ago.
Im currently writing a program for a uni asssessment and they have a set line to compile it, so if it doesn't work with that it won't be accepted.
They command they use is
gcc -Wall -ansi -lm program.c -o program.out
My program will not compile that way, and it'll give me a undefined referance error (Referring to my log10 using math.h library)
if i use:
gcc -Wall -ansi program.c -o program.out -lm
it works
What could be my issue?
Im using windows 10 64bit and have windows bash installed and gcc.
This would be explained if your instructors are using gold and you are using GNU ld. These are two linkers, both are part of the GNU project, and both are commonly used with GCC.
If you are using GNU ld, you get the "traditional" behavior:
The order of specifying the -L and -l options, and the order of specifying -l options with respect to pathname operands is significant.
This means that you have to put -lm after any object files and libraries that depend on it.
However, if you are using gold, the -l options may appear first.
If you have gold installed on your system, you can test it yourself.
Here is what I get:
$ gcc -lm program.c
/tmp/ccJmBjmd.o: In function `main':
program.c:(.text+0x15): undefined reference to `sin'
collect2: error: ld returned 1 exit status
But if I use gold, it works fine:
$ gcc -lm program.c -fuse-ld=gold
-lm needs to be at the end of the command, most likely in the first case with the literal the compiler is optimizing out the call to any function and therefore does not need to link against the library. This is called constant folding and for example we can see in the gcc docs on Other Built-in Functions Provided by GCC says:
GCC includes built-in versions of many of the functions in the
standard C library. The versions prefixed with __builtin_ are always
treated as having the same meaning as the C library function even if
you specify the -fno-builtin option. (see C Dialect Options) Many of
these functions are only optimized in certain cases; if they are not
optimized in a particular case, a call to the library function is
emitted.
I have a static library which I compiled with gcc without c99 mode. I am trying to link it in compilation using gcc -std=c99. This is giving me an error:
undefined reference to 'functionName'
Here, functionName is function inside the static library.
This is my compilation:
gcc -std=c99 -g -I../ -Llib/ -lmylib test.c ../file1.c ../file2.c -o test
I am using C99 here because my code in test.c #includes header files whose implementation uses C99 standard.
The static library(lib/libmylib.a) in not compiled with c99 standard because it's code uses some libraries which are failing to compile in C99 mode(but compiles without c99 flag).
I also tried changing the order of the -L & -l flags to the end & immediately after gcc -std=c99 but it gave the same 'undefined reference' error.
How do I link these together?
Thank you.
EDIT: The function which I've mentioned as functionName is a pseudonym for setupStacktrace() shown here: http://pastebin.com/2RbEEPaj. It is signature is void setupStacktrace();
The order of the command line arguments matter. The way you have it now, the linker goes through your static libraries, realizes that nothing so far need anything it provides, and throw away everything in it. Do this:
gcc -std=c99 -g -I../ -Llib/ test.c ../file1.c ../file2.c -lmylib -o test
I'm writing a shared library using autoconf/libtool which I want to compile for Linux and for Windows (Using the mingw cross-compiler). For Linux (and maybe other platforms which support it) I need to set -fPIC. So I put it into the CFLAGS in Makefile.am. But when I cross-compile it with mingw then gcc complains with a warning:
warning: -fPIC ignored for target (all code is position independent)
So obviously this option is not needed for Windows code. It is only a warning but I want to get rid of it anyway. How can I do this? Maybe there is already a libtool/autoconf feature which checks if the option is supported and only sets it when needed so I don't have to do this manually in Makefile.am?
You shouldn't need to set -fPIC manually, libtool will add it if you tell it what type of binary/library you're building.
lib_LTLIBRARIES = mylibrary.la
mylibrary_la_SOURCES = mylibrary.c
This can produce both a mylibrary.so with PIC (if needed) and a mylibrary.a without, depending on other Autoconf/Automake options. (Probably something like .dll and .lib on Windows, but I don't use that platform.)
I have used the following in configure.ac to add -fPIC conditionally:
AC_MSG_CHECKING(whether fPIC compiler option is accepted)
SAVED_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS -fPIC -Werror"
AC_COMPILE_IFELSE([AC_LANG_PROGRAM([], [return 0;])],
[AC_MSG_RESULT(yes)
CFLAGS="$SAVED_CFLAGS -fPIC"],
[AC_MSG_RESULT(no)
CFLAGS="$SAVED_CFLAGS"])