I am trying to compile a program with arm-linux-gnueabi-gcc containing neon instructions and executing it over Qemu. The code is,
#include <arm_neon.h>
void NeonTest(short int * __restrict a, short int * __restrict b, short int * __restrict z)
{
int i;
for (i = 0; i < 200; i++) {
z[i] = a[i] * b[i];
}
}
I successfully do it without using -static flag. But Qemu does not execute/recognize an executable if -static flag is not used. So when I use -static to compile and link, I get the following error,
junaid#junaid755:~/code/c$ arm-linux-gnueabi-gcc -static -march=armv7-a -mtune=cortex-a9 -ftree-vectorize -mhard-float -mfloat-abi=softfp -mfpu=neon -ffast-math -mvectorize-with-neon-quad -S neon_test.c
junaid#junaid755:~/code/c$ arm-linux-gnueabi-gcc -static -march=armv7-a -mtune=cortex-a9 -ftree-vectorize -mhard-float -mfloat-abi=softfp -mfpu=neon -ffast-math -mvectorize-with-neon-quad -c neon_test.s -o neon_test.o
junaid#junaid755:~/code/c$ arm-linux-gnueabi-gcc -static -march=armv7-a -mtune=cortex-a9 -ftree-vectorize -mhard-float -mfloat-abi=softfp -mfpu=neon -ffast-math -mvectorize-with-neon-quad neon_test.o -o neon_test
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/bin/ld: attempted static link of dynamic object `/lib/ld-linux.so.3'
collect2: error: ld returned 1 exit status
I have tried the ermine, statifier and other softwares for portable linux applications. But the issue is they work on executables, while in my case the executable generation is causing error.
The problem is solved when i installed arm-linux-gnueabihf-gcc on my system. Maybe additional packages installed may have resloved the problem. Now I use arm-linux-gnueabihf-gcc command instead of arm-linux-gnueabi-gcc. Now the exe file is statically linked. But the problem is not totally solved. On qemu it give segmentation fault now.
Related
I have a header file that declares two functions:
// ff.h
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt);
FRESULT f_mkfs (const TCHAR* path, const MKFS_PARM* opt, void* work, UINT len);
And a source file that defines both functions:
// ff.c
#include "ff.h"
FRESULT f_mount (FATFS* fs, const TCHAR* path, BYTE opt) {...}
FRESULT f_mkfs (const TCHAR* path, const MKFS_PARM* opt, void* work, UINT len) {...}
When I call them from my main file, however, one of the functions works perfectly and the other raises undefined reference, even though they are in the same file:
#include "ff.h"
[...]
fresult = f_mount(&fs, "0:", 1);
[...]
fresult = f_mkfs("0:", &fmt_opt, work, sizeof work);
>> output:
11:24:45 **** Incremental Build of configuration Debug for project laser_manual ****
make -j8 all
arm-none-eabi-gcc -o "laser_manual.elf" #"objects.list" -mcpu=cortex-m4 -T"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\STM32F407ZGTX_FLASH.ld" --specs=nosys.specs -Wl,-Map="laser_manual.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -u _printf_float -u _scanf_float -Wl,--start-group -lc -lm -Wl,--end-group
c:\st\stm32cubeide_1.9.0\stm32cubeide\plugins\com.st.stm32cube.ide.mcu.externaltools.gnu-tools-for-stm32.10.3-2021.10.win32_1.0.0.202111181127\tools\arm-none-eabi\bin\ld.exe: ./Src/main.o: in function `main':
C:/Users/Pesquisa2/Documents/stm32/LM_STM32/Debug/../Src/main.c:55: undefined reference to `f_mkfs'
collect2.exe: error: ld returned 1 exit status
make: *** [makefile:68: laser_manual.elf] Error 1
"make -j8 all" terminated with exit code 2. Build might be incomplete.
How is this possible?
(Obs.: this are standard Elm Chan library)
Paths
I'm using STM32CubeMX for compilation and debugging. On properties, I set my C/C++ General/Paths and Symbols as following:
Includes: /laser_manual/FATFS/inc
Source Location: /laser_manual/FATFS
Tool Settings
MCU GCC Assembler:
-mcpu=cortex-m4 -g3 -DDEBUG -c -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\FATFS\src" -x assembler-with-cpp --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb
MCU GCC Compiler:
-mcpu=cortex-m4 -std=gnu11 -g3 -DDEBUG -DSTM32 -DSTM32F4 -DSTM32F407ZGTx -c -I"C:\Users\Pesquisa2\STM32Cube\Repository\STM32Cube_FW_F4_V1.27.0\Drivers\CMSIS\Include" -I"C:\Users\Pesquisa2\STM32Cube\Repository\STM32Cube_FW_F4_V1.27.0\Drivers\CMSIS\Device\ST\STM32F4xx\Include" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Inc\App" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Inc\HAL" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Inc" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Src\Midware" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Src\HAL" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Src\App" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\Inc\Midware" -I"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\FATFS\inc" -O0 -ffunction-sections -fdata-sections -Wall -fstack-usage --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb
MCU GCC Linker:
-mcpu=cortex-m4 -T"C:\Users\Pesquisa2\Documents\stm32\LM_STM32\STM32F407ZGTX_FLASH.ld" --specs=nosys.specs -Wl,-Map="${BuildArtifactFileBaseName}.map" -Wl,--gc-sections -static --specs=nano.specs -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -u _printf_float -u _scanf_float -Wl,--start-group -lc -lm -Wl,--end-group
you need to make sure that two defines are:
FF_FS_READOLNY == 0
FF_USE_MKFS == 1
Some older versions use names without the FF
edit ffconf.h
I have a program which is linked (dynamically) with libm.
There are also several plugins for this program.
Plugins are loaded explicitely with dlopen().
Some of these plugins use round() from libm.
On one system (Linux Mint 19.1 gcc 7.5.0) the program
does not work because of unresolved round.
Here is simple example:
Library (lib.c)
#include <stdio.h>
#include <math.h>
void func(double a, double b)
{
double c;
c = round(a + b);
printf("c = %lf\n", c);
}
Main program (main.c)
#include <stdio.h>
#include <dlfcn.h>
void *dll;
void (*f)(double, double);
double a = 1.234, b = 4.321;
int main(void)
{
dll = dlopen("./lib.so", RTLD_LAZY);
f = dlsym(dll, "func");
f(a,b);
return 0;
}
Building (Makefile)
all:
gcc -Wall -Os -shared -fPIC lib.c -o lib.so
gcc -Wall -Os -rdynamic -fPIC main.c -o main -ldl -lm
Run on Debian 8, gcc 4.9.2
./main
c = 6.000000
Run on Linux Mint 19.1, gcc 7.5.0
./main
./main: symbol lookup error: ./lib.so: undefined symbol: round
Now, add -lm for dll compilation
gcc -Wall -Os -shared -fPIC lib.c -o lib.so -lm
./main
c = 6.000000
So, the question is - why on this particular system one must use -lm not only for main program but for plugin also?
Just like an executable program, shared libraries are linked entities (unlike static libraries which are archives of object files).
Since shared libraries are linked like executables, you also need to link with the libraries that your library depends on:
gcc -Wall -Os -shared -fPIC lib.c -o lib.so -lm
I am trying to build gcc for my linux. I'm cross compiling since I don't have a preexisting gcc.
I'm using musl as libc.
I configured gcc like this:
export CFLAGS="-pipe -march=native -fstack-protector-strong -fno-plt -pie -fpie"
../gcc-10.1.0/configure --target=x86_64-unknown-linux-musl \
--host=x86_64-unknown-linux-musl --build=x86_64-pc-linux-gnu \
--enable-lto --prefix=/usr --disable-nls --disable-multilib \
--enable-languages=c --without-isl --with-newlib --disable-libsanitizer \
--with-sysroot=/root/mnt
When I run make gcc compiles for a few minutes. After a while the build tries to execute the following
x86_64-unknown-linux-musl-gcc -O2 -g -O2 -pipe -march=native -fstack-protector-strong -fno-plt -pie -fpie -DIN_GCC -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition -isystem ./include -fpic -mlong-double-80 -DUSE_ELF_SYMVER -DGTHREAD_USE_WEAK=0 -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc -shared -nodefaultlibs -Wl,--soname=libgcc_s.so.1 -Wl,--version-script=libgcc.map -o ./libgcc_s.so.1.tmp -g -O2 -pipe -march=native -fstack-protector-strong -fno-plt -pie -fpie -B./ _muldi3_s.o _negdi2_s.o _lshrdi3_s.o _ashldi3_s.o _ashrdi3_s.o _cmpdi2_s.o _ucmpdi2_s.o _clear_cache_s.o _trampoline_s.o __main_s.o _absvsi2_s.o _absvdi2_s.o _addvsi3_s.o _addvdi3_s.o _subvsi3_s.o _subvdi3_s.o _mulvsi3_s.o _mulvdi3_s.o _negvsi2_s.o _negvdi2_s.o _ctors_s.o _ffssi2_s.o _ffsdi2_s.o _clz_s.o _clzsi2_s.o _clzdi2_s.o _ctzsi2_s.o _ctzdi2_s.o _popcount_tab_s.o _popcountsi2_s.o _popcountdi2_s.o _paritysi2_s.o _paritydi2_s.o _powisf2_s.o _powidf2_s.o _powixf2_s.o _mulhc3_s.o _mulsc3_s.o _muldc3_s.o _mulxc3_s.o _divhc3_s.o _divsc3_s.o _divdc3_s.o _divxc3_s.o _bswapsi2_s.o _bswapdi2_s.o _clrsbsi2_s.o _clrsbdi2_s.o _fixunssfsi_s.o _fixunsdfsi_s.o _fixunsxfsi_s.o _fixsfdi_s.o _fixdfdi_s.o _fixxfdi_s.o _fixunssfdi_s.o _fixunsdfdi_s.o _fixunsxfdi_s.o _floatdisf_s.o _floatdidf_s.o _floatdixf_s.o _floatundisf_s.o _floatundidf_s.o _floatundixf_s.o _divdi3_s.o _moddi3_s.o _divmoddi4_s.o _udivdi3_s.o _umoddi3_s.o _udivmoddi4_s.o _udiv_w_sdiv_s.o sfp-exceptions_s.o addtf3_s.o divtf3_s.o multf3_s.o negtf2_s.o subtf3_s.o unordtf2_s.o fixtfsi_s.o fixunstfsi_s.o floatsitf_s.o floatunsitf_s.o fixtfdi_s.o fixunstfdi_s.o floatditf_s.o floatunditf_s.o fixtfti_s.o fixunstfti_s.o floattitf_s.o floatuntitf_s.o extendsftf2_s.o extenddftf2_s.o extendxftf2_s.o trunctfsf2_s.o trunctfdf2_s.o trunctfxf2_s.o getf2_s.o letf2_s.o eqtf2_s.o _divtc3_s.o _multc3_s.o _powitf2_s.o enable-execute-stack_s.o unwind-dw2_s.o unwind-dw2-fde-dip_s.o unwind-sjlj_s.o unwind-c_s.o emutls_s.o libgcc.a -lc
in my build directory under x86_64-unknown-linux-musl/libgcc which fails with:
/root/mnt/tools/lib/gcc/x86_64-unknown-linux-musl/10.1.0/../../../../x86_64-unknown-linux-musl/bin/ld: /root/mnt/tools/lib/gcc/x86_64-unknown-linux-musl/10.1.0/../../../../x86_64-unknown-linux-musl/lib/Scrt1.o: in function `_start_c':
Scrt1.c:(.text._start_c+0x1b): undefined reference to `main'
collect2: error: ld returned 1 exit status
I verified with objdump -t crt1.o and objdump -t Scrt1.o that these object files define main, which they do.
Im pretty confused by now because the name libgcc suggests that it's a library, which of course does not have a main method. Why is ld expecting one? What is the build trying to do here?
I am trying to generate assembly and executable of a simple neon-based c code. The code is,
#include <arm_neon.h>
void NeonTest(short int * __restrict a, short int * __restrict b, short int * __restrict z)
{
int i;
for (i = 0; i < 200; i++) {
z[i] = a[i] * b[i];
}
}
First, I am going for the assembly to calculate the neon instructions,
arm-linux-gnueabi-gcc -O2 -march=armv7-a -mtune=cortex-a9 -ftree-vectorize -mhard-float -mfloat-abi=softfp -mfpu=neon -S neon_test.c -o nt.s
Then I am converting the nt.s file to object file.
arm-linux-gnueabi-gcc -O2 -march=armv7-a -mtune=cortex-a9 -ftree-vectorize -mhard-float -mfloat-abi=softfp -mfpu=neon -c nt.s -o nt.o
Finally, for the executable I do,
arm-linux-gnueabi-gcc -O2 -march=armv7-a -mtune=cortex-a9 -ftree-vectorize -mhard-float -mfloat-abi=softfp -mfpu=neon nt.o -o nt
I get the error,
/usr/lib/gcc-cross/arm-linux-gnueabi/4.7/../../../../arm-linux-gnueabi/lib/crt1.o: In function `_start':
(.text+0x34): undefined reference to `main'
collect2: error: ld returned 1 exit status
I am using Ubuntu 14LTS on Intel system.
You're not including the C file that contains main() when compiling, so the linker isn't seeing it
You need to add it:
arm-linux-gnueabi-gcc -O2 -march=armv7-a -mtune=cortex-a9 -ftree-vectorize -mhard-float -mfloat-abi=softfp -mfpu=neon nt.o main.o -o nt
where main.o is also created following the same step as neon.o
Every program needs a starting point so the computer knows where to begin execution. In C/C++, the starting point is the beginning of the function int main. Give your program an int main by either linking your object file to an object file with int main, or adding one in this code.
To add main in your code, beneath your function definition, try
int main()
{
NeonTest(/* your parameters */);
}
I made a library, and I'm trying to make a test client for it to test my Debian packages. This test is being done on Ubuntu 14.04.
I installed the binary and the developer files and their dependencies.
Here's the source for my test program:
#include <stdio.h>
#include <cquel.h>
int main(int argc, char *argv[])
{
cq_init(1024, 128);
struct dbconn mydb = cq_new_connection(u8"pattstest.delwink.com", u8"patts",
u8"patts", u8"pattsdb");
struct dlist *users;
int rc = cq_select_all(mydb, u8"User", &users, u8"");
if (rc)
return 2;
for (size_t i = 0; i < users->fieldc; ++i)
printf("%s\n", users->fieldnames[i]);
cq_free_dlist(users);
return 0;
}
The program is supposed to connect to a test server and get the column headers from the database (no, that server is not production and does not need to be particularly secure).
I attempted to compile using gcc:
$ gcc -Wall `pkg-config --cflags --libs cquel` `mysql_config --cflags --libs` -std=c11 main.c
/tmp/ccjd21kP.o: In function `main':
/home/mac/c/main.c:6: undefined reference to `cq_init'
/home/mac/c/main.c:8: undefined reference to `cq_new_connection'
/home/mac/c/main.c:12: undefined reference to `cq_select_all'
/home/mac/c/main.c:19: undefined reference to `cq_free_dlist'
collect2: error: ld returned 1 exit status
I knew something was up, so I attempted the same with clang:
$ clang -Wall `pkg-config --cflags --libs cquel` `mysql_config --cflags --libs` -std=c11 main.c
Clang compiled just fine! I ran my a.out binary, and it printed the column headers as expected.
Why did gcc fail to link to my library?
EDIT: I thought to check my LD_LIBRARY_PATH to find that it was blank. However, setting it to /usr/lib/x86_64-linux-gnu (which is the location of my shared object) did not change the behavior of gcc.
Order of arguments matter a lot for gcc; you should use
gcc -Wall $(pkg-config --cflags cquel) $(mysql_config --cflags) \
-std=c11 main.c \
$(pkg-config --libs cquel) $(mysql_config --libs)
See also this & that.