I'm trying to compile my project and I use the lib ncurse. And I've got some errors when compiler links files.
Here is my flags line in Makefile:
-W -Wall -Werror -Wextra -lncurses
I've included ncurses.h
Some layouts :
prompt$> dpkg -S curses.h
libslang2-dev:amd64: /usr/include/slcurses.h
libncurses5-dev: /usr/include/ncurses.h
libncurses5-dev: /usr/include/curses.h
prompt$> dpkg -L libncurses5-dev | grep .so
/usr/lib/x86_64-linux-gnu/libncurses.so
/usr/lib/x86_64-linux-gnu/libcurses.so
/usr/lib/x86_64-linux-gnu/libmenu.so
/usr/lib/x86_64-linux-gnu/libform.so
/usr/lib/x86_64-linux-gnu/libpanel.s
And here are my erros :
gcc -W -Wall -Werror -Wextra -I./Includes/. -lncurses -o Sources/NCurses/ncurses_init.o -c Sources/NCurses/ncurses_init.c
./Sources/NCurses/ncurses_init.o: In function `ncruses_destroy':
ncurses_init.c:(.text+0x5): undefined reference to `endwin'
./Sources/NCurses/ncurses_init.o: In function `ncurses_write_line':
ncurses_init.c:(.text+0xc5): undefined reference to `mvwprintw'
./Sources/NCurses/ncurses_init.o: In function `ncurses_init':
ncurses_init.c:(.text+0xee): undefined reference to `initscr'
collect2: error: ld returned 1 exit status
Thanks a lot
You need to change your makefile so that the -lncurses directive comes after your object code on the gcc command line, i.e. it needs to generate the command:
gcc -W -Wall -Werror -Wextra -I./Includes/. -o Sources/NCurses/ncurses_init.o -c Sources/NCurses/ncurses_init.c -lncurses
This is because object files and libraries are linked in order in a single pass.
In C++ , I fixed it just by linking the ncurses library .
Here is the command :
g++ main.cpp -lncurses
I got flags to correct order by using LDLIBS variable:
ifndef PKG_CONFIG
PKG_CONFIG=pkg-config
endif
CFLAGS+=-std=c99 -pedantic -Wall
LDLIBS=$(shell $(PKG_CONFIG) --libs ncurses)
man gcc | grep -A10 "\-l library"
-l library
Search the library named library when linking. (The second alternative with the library as a separate argument is only for POSIX
compliance and is not recommended.)
It makes a difference where in the command you write this option; the linker searches and processes libraries and object files
in the order they are specified. Thus, foo.o -lz bar.o searches
library z after file foo.o but
before bar.o. If bar.o refers to functions in z, those functions may not be loaded.
Related
I got an error when try to link (-aarch64-linux-gnu-ld) (the script containing the Makefile was downloaded from https://github.com/Icenowy/aw-el2-barebone). Error is "aarch64-linux-gnu-ld: Error: unable to disambiguate: -nostartfiles (did you mean --nostartfiles ?)
make: *** [Makefile:31: el2-bb.elf] Error 1" How to recode the line 31? of the Makefile
CROSS_COMPILE = /usr/bin/aarch64-linux-gnu-
DEBUG = 1
CC = $(CROSS_COMPILE)gcc
AS = $(CROSS_COMPILE)as
LD = $(CROSS_COMPILE)ld
OBJCOPY = $(CROSS_COMPILE)objcopy
INCLUDES = -I ./include -I ./uboot-headers -ffreestanding
DEFINES = -DSOC_HEADER="\"h6.h\""
ifneq ($(DEBUG),1)
DEFINES += -DNDEBUG
endif
ASFLAGS = $(INCLUDES) $(DEFINES) -D__ASSEMBLY__
CFLAGS = $(INCLUDES) $(DEFINES) -O2
LDSCRIPT = ldscripts/a64.ld
LDSCRIPTS = ldscripts/a64.ld ldscripts/common.ld
LDFLAGS = -nostdlib -nostartfiles -static -T $(LDSCRIPT)
OBJS = start.o init.o uart.o stack.o exceptions.o exception_funcs.o panic.o pgtables.o trapped_funcs.o
all: el2-bb.bin
el2-bb.elf: $(OBJS) $(LDSCRIPTS)
$(LD) $(LDFLAGS) $(OBJS) -o $#
el2-bb.bin: el2-bb.elf
$(OBJCOPY) -O binary $< $#
.PHONY: clean
clean:
rm -f el2-bb.* *.o
-nostartfiles is a gcc option but not an ld option.
If you use gcc to invoke the linker (say with LD=gcc in your Makefile) for making a standalone program that does not use standard startup files, you should use -nostartfiles because gcc links the startup files by default and -nostartfiles disables this.
ld doesn't links any startup files by default, so there is no option to disable linking them. You always pass startup files explicitly to ld. If you don't want startup files, just don't pass them to ld.
In order to see what startup files on your system are create an empty C program:
int main(){}
and compile it:
gcc -c empty.c
gcc -v empty.o
You are likely to see an invocation of ld (or perhaps of collect2, which calls ld) with a long, long list of options and object files.
Now run
gcc -nostartfiles -v empty.o
The .o files are now gone. That's exactly what -nostartfiles does.
When you invoke ld empty.o, these files and options are not there to begin with. In order to make a working program for say a Linux system, you need to pass most of them to ld explicitly. If you are building a program for something other system, you may not need some or all of them. So just don't pass them in.
I have a problem trying to create a Makefile that compile multiple sorces, generate only a shared library and make an exe with another file wiht the main function.
The sorces also have dependencies.
My Makefile is
CC=gcc
CFLAGS=-Wall -g
BINS=libsensorMotor.so maintarget
all: $(BINS)
libsensorMotor.o: libsensorMotor.cpp sensorMotor.h Adafruit_ADS1015.cpp Adafruit_ADS1015.h wiringPiI2C.c wiringPiI2C.h enumADCGain.h
$(CC) $(CFLAGS) -c libsensorMotor.cpp Adafruit_ADS1015.cpp wiringPiI2C.c
libsensorMotor.so: libsensorMotor.cpp sensorMotor.h
$(CC) $(CFLAGS) -fPIC -shared -o $# libsensorMotor.cpp -lc
maintarget: maintarget.c
$(CC) $(CFLAGS) -o $# $^ -L. -lsensorMotor -pthread
clean:
rm *.o $(BINS)
The script show the errors:
libsensorMotor.so Undefined reference to 'functionXXXX'
maintarget contains the main and use libsensorMotor as a shared library. libsensorMotor depends and include all the rest of the files
The error mention all the functions that libsensorMotor uses from the include sources.
I only need to generate a correct libsensorMotor.so that can use as shared library from any other main file. Internet has many tutorials but are unclear, weird and complicated, and not show how do this simple.
Is not Makefile problem, simply the line
gcc -pthread -lm -o maintarget maintarget.c libsensorMotor.cpp Adafruit_ADS1015.cpp wiringPiI2C.c
sends same error, the compiler not recongnice the function inside the pthread_create while compile C and C++ with gcc
A am using below command to compile my c++ code and which is using OpenCV libraries and my command is just like
opencv main.cpp -o binary_name
where opencv is an alias command like
alias opencv="g++ `pkg-config --cflags opencv` `pkg-config --libs opencv`"
but if I forget the "-o binary_name" the command delete my source file. Why this happening....?
What modification should I made on the above alias command to compile my source file like
opencv main.cpp binary_name
Thanks in advance.......
The order of arguments to gcc is important, source or object files should be given before libraries, and libraries should be invoked with higher level libraries before the lower level libraries they are using.
So you should compile with
g++ -Wall -g $(pkg-config --cflags opencv) main.cpp \
$(pkg-config --libs opencv) -o binaryprog
But you really should use a Makefile, or at least have a shellscript.
Don't forget the -Wall option to get all warnings. Improve your code till no warnings are given by the compiler. Use the -g option to get debugging information, to be able to use gdb ./binaryprog to debug your program.
Once your program is debugged, replace -g by -O3 (or perhaps by -O2 -g) to ask GCC to optimize the generated code.
You can use a function instead of an alias, and use arguments:
function opencv() { g++ `pkg-config --cflags opencv` `pkg-config --libs opencv` "$1" -o "$2"; }
I got an assignment to improve running time of some code. The only problem is, I can't even compile it to run it on my machine in the first place. Every time I try, it stops somewhere in the midst of compiling saying this:
"undefined reference to `boost::re_detail::put_mem_block(void*)'
collect2: ld returned 1 exit status make: * [cpu] Error 1"
This is how makefile looks:
SHELL = /bin/bash
OBJECTS = main.o atom.o molecule.o charges.o pdb.o asa.o amino.o chain.o addition.o string_operation.o pdb_peptide.o protein_chain.o residue_atom.o chain_residue.o residue_contact.o atom_grid.o circles.o atom_space_calculations.o
OBJDIR = obj
VPATH = src:src/ext:$(OBJDIR)
CFLAGS = -O3 -Wall -lm -lboost_regex -L/usr/local/boost/lib
HDIRS = src,src/ext,src/qt_redistributable, usr/lib, usr/local/lib, usr/local/lib/include/boost, /usr/local/lib/lib/
IOPTS = $(addprefix -I, $(HDIRS))
cpu : $(addprefix $(OBJDIR)/, $(OBJECTS) $(CPUOBJS))
g++ $(CFLAGS) -o mcpu $^
$(OBJDIR)/%.o : %.cpp
g++ $(CFLAGS) $(IOPTS) -c $< -o $#
clean :
rm obj/*.o $(PROG)
I'm using Linux Mint x64 and I have tried everything I googled out. Installed the whole boost library in usr/local/lib (for no obvious reason because it didn't help), tried to edit LD PATH (I'm very new to Linux and I have no idea if that went right) and lots of stuff, but this thing doesn't seem to go through. Any help appreciated.
One problem with your makefile happens when you link your program. As you can see in these questions with g++ the order of your arguments at link time is really important. You need to put your libraries after your object files. One easy way to solve would be separating your linker flags (LDFLAGS) from the compiler flags (CFLAGS), and then putting LDFLAGS after $^ (your object files) in the link command.
CFLAGS = -O3 -Wall
LDFLAGS = -L/usr/local/boost/lib -lm -lboost_regex
cpu : $(addprefix $(OBJDIR)/, $(OBJECTS) $(CPUOBJS))
g++ $(CFLAGS) -o mcpu $^ $(LDFLAGS)
$(OBJDIR)/%.o : %.cpp
g++ $(CFLAGS) $(IOPTS) -c $< -o $#
As can be seen in the Catalogue of Built-In Rules:
Linking a single object file
n is made automatically from n.o by running the linker (usually called
ld) via the C compiler. The precise recipe used is:
$(CC) $(LDFLAGS) n.o $(LOADLIBES) $(LDLIBS)
and Variables Used by Implicit Rules:
LDFLAGS
Extra flags to give to compilers when they are supposed to invoke the linker,
ld, such as -L. Libraries (-lfoo) should be added to the LDLIBS variable
instead.
So in this case -lboost_regex should be set or added to LDLIBS, not LDFLAGS.
I know -Wl,-shared is a option of ld. I've seen some person compile like this,
$ gcc -shared -Wl,-soname,libtest.so -o libtest.so *.o
And some person like this
$ gcc -Wl,-shared -Wl,-soname,libtest.so -o libtest.so *.o
So, I want to know if there is some difference between -shared and -Wl,-shared.
Thanks.
There is a difference between passing -shared to gcc or -shared to ld (via -Wl). Passing -shared to GCC may enable or disable other flags at link time. In particular, different crt* files might be involved.
To get more information, grep for -shared in GCC's gcc/config/ directory and subdirectories.
Edit: To give a specific example: on i386 FreeBSD, gcc -shared will link in object file crtendS.o, while without -shared, it will link in crtend.o instead. Thus, -shared and -Wl,-shared are not equivalent.
I don't think there is any difference. -shared is not a supported option of gcc and it is passed to linker whether you specify it with -Wl or not. -Wl option of gcc is used to specify that a comma separated list of options is to be passed to linker for further processing.