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 */);
}
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 am novice in C programming. So I learned different process of compilation(preproccessing, compiling, linking). My program is
#include <stdio.h>
#define testDefinition(x) printf(#x " is equal to %lf\n",x)
int main(void)
{
testDefinition(3.15);
return 0;
}
It is simple program which doesn't have any sense,but problem is when I use gcc -o test test.c it works fine, but when I do that
gcc -E test.c -o test.i
gcc -C test.i -o test.o
gcc test.o -o test
I get error
usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':
(.text+0x24): undefined reference to `main'
collect2: error: ld returned 1 exit status
I am using Ubuntu 20.04 and GCC compiler.
test.o is already the executable, you did not pass -c.
$ gcc -E test.c -o test.i
$ gcc -C test.i -o test.o
$ ./test.o
3.15 is equal ....
Because of it, test.o is an ELF file and gcc treats it as shared library (I think). Because there are no source files passed in gcc test.o -o test there is no main, so it's undefined.
I guess, you wanted to do gcc -C -c test.i -o test.o to create an object file.
I have a statically linked library, containing a global variable barvar. I can compile the library with no problems with either gcc-10 or clang (this is on macOS Catalina). Interestingly, the behavior differs between the two when I try to link it into a program that uses the library. Here's the code:
In globvars.h, int barvar is declared:
#ifndef H_GLOBVARS_H
#define H_GLOBVARS_H
extern int barvar;
#endif
In globvars.c, int barvar is defined:
#include "globvars.h"
int barvar;
In foo.c, the function foo sets and prints barvar:
#include <stdio.h>
#include "globvars.h"
void foo()
{
barvar = 10;
printf("barvar is: %d\n", barvar);
return;
}
Here's test.c, the program that uses the library:
void foo();
int main(int argc, char **argv)
{
foo();
return 0;
}
When I compile and link with gcc-10, no problems:
gcc-10 -c foo.c -o foo.o
gcc-10 -c globvars.c -o globvars.o
gcc-10 -c test.c -o test.o
gcc-ar-10 rcs liblinktest.a foo.o globvars.o
gcc -o testlinkrun test2.o -L. -llinktest
When I compile and link with clang, I get an undefined symbol error at the last step:
cc -c foo.c -o foo.o
cc -c globvars.c -o globvars.o
cc -c test.c -o test.o
ar rcs liblinktest.a foo.o globvars.o
cc -o testlinkrun test2.o -L. -llinktest
with error:
Undefined symbols for architecture x86_64:
"_barvar", referenced from:
_foo in liblinktest.a(foo.o)
Any ideas? Interestingly, it appears the only step that has to be done with gcc-10 is compiling globvars.c. I can use clang and the clang linker for all other steps, and everything is fine. Is it possible that clang is optimizing away all the variables in globvars.c? How can I prevent this?
As #EricPostpischil observed in this comment, the issue is that clang defaults to treating barvar as a common symbol. Either changing int barvar; to int barvar = 0;, or compiling with -fno-common, fix the issue.
Beginning with gcc-10, gcc's default behavior is -fno-common instead of -fcommon.
I am trying to compile the following source file using gcc -g -Wall -Wextra -pedantic -std=c99 -o main -lm.
source.h
void simple_sum(void)
source.c
#include "source.h"
#include <stdio.h>
void simple_sum(void)
{
int a, b;
scanf("%d %d", &a, &b);
printf("%d + %d = %d\n",a, b, a + b);
}
main.c
#include "source.h"
#include <stdio.h>
int main(void)
{
printf("\n");
simple_sum();
return 0;
}
I get following error:
gcc -g -Wall -Wextra -pedantic -std=c99 -o main -lm
/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o: In function _start':
(.text+0x20): undefined reference to `main'
collect2: error: ld returned 1 exit status
Makefile:6: recipe for target 'main' failed
make: *** [main] Error 1
Could someone please suggest how to fix this?
Edit
I get the following error when I run using gcc -g -Wall main.c -o main
/tmp/ccEAL4iG.o: In functionmain':
/home/a/aalto_university/functions/calculation/main.c:7: undefined reference to simple_sum'
collect2: error: ld returned 1 exit status
Compile with
gcc -g -Wall -Wextra -pedantic -std=c99 source.c main.c -o myprog -lm
(actually, -lm is not needed, you don't use <math.h> functions; but keeping -lm should not harm)
Later, learn to write your Makefile to do these things in several steps:
First, get the source.o object file with
gcc -g -Wall -Wextra -pedantic -std=c99 -c source.c
then get the main.o object file with
gcc -g -Wall -Wextra -pedantic -std=c99 -c main.c
At last, link both of them
gcc -g source.o main.o -lm -o myprog
Here
gcc -g -Wall -Wextra -pedantic -std=c99 -o main -lm
you are not providing source file name to linker, hence it throw error like
undefined reference to `main'
While compiling provide source file main.c and source.c. For e.g first run this
gcc -g -Wall -Wextra -pedantic -std=c99 -c main.c source.c -lm
to create the object.o files & then create the executable by running
gcc source.o main.o -o my_exe
And finally run the executable. Also declaration of simple_sum() missing ; it should be
void simple_sum(void); /* you miss ;*/
Also learn how to use Makefile for compilation as #Basile pointed, there you don't have to create .o file manually, your Makefile will create .o file & compile if it's written correctly.
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.