make command with math library - makefile

I need to just run the make command for makefile. But when I run this make command I get the error that "undefined reference to `log'" because I know this fact that it doesn't include math Library and we have to include at runtime. I know that if I run this using gcc comiler then i can write -lm at the end, it will include math library. My problem is I need to run it using make command that is- make lu.
In this if I write make lu -lm it is not linking math library. Please help
Using this link How to use LDFLAGS in makefile
I updated my make file but still same problem persists. Please Help.
SHELL=/bin/sh
BENCHMARK=ep
BENCHMARKU=EP
include ../config/make.def
OBJS = ep.o ${COMMON}/c_print_results.o ${COMMON}/c_${RAND}.o \
${COMMON}/c_timers.o ${COMMON}/c_wtime.o
include ../sys/make.common
LDLIBS=-lm
LDFLAGS=-lm
${PROGRAM}: config ${OBJS}
${CLINK} ${CLINKFLAGS} -o ${PROGRAM} $(LDFLAGS) $(LOADLIBES) ${OBJS} ${C_LIB}
ep.o: ep.c npbparams.h
${CCOMPILE} ep.c
clean:
- rm -f *.o *~
- rm -f npbparams.h core

Why does your makefile refer to all sorts of variables that don't exist, like LOADLIBES, C_LIB? Why do you set variables that you never use, like LDLIBS?
The reason it doesn't work is that you're putting the library reference in the LDFLAGS variable, which comes early in your link command before any of your object files. So when the linker goes to link in the math library it thinks that it's not needed because nothing is using it yet.
You have to put libraries at the end of the link line.
Since you already have the C_LIB variable at the end which you are not using, if you add:
C_LIB = -lm
then it should work.

Related

Cannot pass flags to Makefile to compile my code

I have a project that basically compiles from the command line in the following form:
g++ -o stack_raster stack_raster.cpp -lgdal -lboost_filesystem -lboost_system
I made a Makefile, and this is the content:
CXX =g++
LDDFLAGS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rm -f stack_raster
However I got a collect2: error: ld returned 1 exit status.
A second variation of my Makefile I tried was:
CXX = g++
CPPFLAGS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rem -f stack_raster
but I still receive the following message (even though the compile flags appear as they should for my program to compile successfully).
collect2: error: ld returned 1 exit status
<builtin>: recipe for target `stack_raster` failed
make: *** [stack_raster] Error 1
Does anyone could help me with a reference or hint about my problem, and how could I tackle it?
Does anyone could help me with a reference or hint about my problem, and how could I tackle it?
To begin with, you should have a look at the actual link command that make executed. It should have been echoed to make's output just before the error message from collect2. Understanding what's wrong with the command is the first step in determining how to fix your makefile.
In the first case, the command is probably something like
g++ stack_raster.cpp -o stack_raster
In the second, it is probably something like
g++ -lgdal -lboost_system -lboost_filesystem stack_raster.cpp -o stack_raster
The latter is probably also very similar to what you would get with the first makefile if you corrected the spelling of LDDFLAGS to LDFLAGS.
You will note that the library flags come in a different place in that command than they do in your manual command, and I assume you know that the order of objects and library flags on the linker command line is significant to Unix-style linkers such as GNU's (which is the one that the g++ driver will use).
You can certainly fix this by writing an explicit rule, as you describe in your own answer, but your makes' built-in rules may be up to the task, too. If you are using GNU make then they certainly are. For this purpose it is useful to know what the built-in rules actually are, and essential to know what the variables on which these rules depend mean.
Specifically,
LDFLAGS provides options to pass when invoking the linker, and conventionally, they appear on the command line before the objects being linked. As a result, this variable typically is not appropriate for specifying libraries (but it is fine for other link-specific options, such as -L to add directories to the library search path).
CPPFLAGS provides options for modulating the behavior of the C preprocessor (including when compiling C++). These do not typically appear at all in link(-only) commands executed by make, but they will appear (early) in commands for compiling object files from C or C++ sources, and in rules for building executables directly from C or C++ sources.
Neither of those is what you want, but if you are using GNU make, then its documentation for the former explicitly tells you what (with that make implementation) you should do instead:
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.
(emphasis added)
In GNU make, and perhaps some others, the LDLIBS variable serves exactly the purpose you need: to specify the libraries to link. These will appear at the end of the link command line from built-in rules, as you can confirm from GNU make's catalog of implicit rules, or from the list obtainable by running make -p in a directory containing no makefile.
So, with GNU make you can get the build you seem to want from the built-in rules, with this:
CXX = g++
LDLIBS = -lgdal -lboost_system -lboost_filesystem
all: clean stack_raster
clean:
rm -f stack_raster
In closing, I note that cleaning before building by default, as your examples do and mine imitates, largely defeats the purpose of using make instead of a simple script. Part of the point of make is to do the minimum work necessary, and if your target executable is present and not out of date with respect to its sources then there is no reason to force it to be rebuilt.
Check out the answer:
Set up my makefile to compile C with just "make"
YOu have to specify in the Makefile the file you want to create in this case stack_raster.exe and the objective file in this case stack_raster.cpp and specify the command line arguments you normally pass for compiling. So the Makefile would be something like:
CXX=g++
stack_raster.exe: stack_raster.cpp
g++ -o stack_raster.exe stack_raster.cpp -lgdal -lboost_filesystem -lboost_system
all: clean stack_raster.exe
clean:
rm -f stack_raster.exe

Trouble with simple makefile in C

I am somewhat of a beginner in C and have a project due where I need to include a makefile to compile my single file program that uses pthreads and semaphores. My makefile looks like:
# Makefile for pizza program
pizza: pizza.o
gcc -lrt -lpthread -g -o pizza pizza.o
pizza.o: pizza.c
gcc -lrt -lpthread -g -c pizza.o pizza.c
and I keep getting:
make: Nothing to be done for 'Makefile'.
I have done several makefiles before and have never gotten this message. I've tried different semantics in the makefile and have only gotten this same message. And yes, the command is tabbed after the target and dependency line.
Using gcc on tcsh. I have read other makefile posts on SO but I wasn't able to use any of the answers to figure it out for my case.
Any help would be greatly appreciated!
The arguments to make are the targets to be built.
You are running make Makefile which is telling make to try to build the Makefile target.
There is no such target in your makefile, make has no built-in rule that applies to that target and the file exists (and is assumed to be up-to-date) which is what that message is telling you.
To run the default target (by default the first target listed) you can just run make (assuming you are using a default name like Makefile for your makefile).
You can also use the -f argument to make to select an alternate makefile name.
So make -f Makefile will in this case (since Makefile is a default searched name) do the same thing as make.

How to see exactly what make is doing

Ive got some large make files for a third party project that are not building due to linker issues.
From looking at the make files, I think it should be executing something like:
LIBS = -lm
CC = gcc
bin = bin
myapp: $(bin)/main.o $(bin)/other.o $(bin)/etc.o
$(CC) $(bin)/main.o $(bin)/other.o $(bin)/etc.o $(LIBS) -o myapp
gcc bin/main.o bin/other.o bin/etc.o -lm -o myapp
Instead from the error it seems to be failing on something like: It also didn't put any of the .o files in the expected bin/ location, but just left them in the source directory...
cc main.o -o myapp
But I cant locate anywhere that might come from. Is there some way to get some kind of stacktrace through the make files?
I am aware of -n and -d, but neither seems to tell me what target line and file yeilded that command, or which series of targets led there and the values of any $() expansions (The one im expecting is the only myapp: I can find in any of the makefiles...)
Check out the --debug option. From my manpage:
--debug[=FLAGS]
Print debugging information in addition to normal processing. If the
FLAGS are omitted, then the behavior is the same as if -d was specified.
FLAGS may be a for all debugging output (same as using -d), b for basic
debugging, v for more verbose basic debugging, i for showing implicit
rules, j for details on invocation of commands, and m for debugging
while remaking makefiles.
remake is a very good choice but in a pinch something like the following (saved as debug.mk) can be a good help too. It won't tell you as much as remake but it might tell you enough to start with.
# Use as: MAKEFILES=debug.mk make
OLD_SHELL := $(SHELL)
ifneq (undefined,$(origin X))
override X = -x
endif
SHELL = $(if $#,$(warning Running $#$(if $<, (from: $<))$(if $?, (newer: $?))))$(OLD_SHELL) $(X)
You can print out the other automatic variables there too if you wanted to see a bit more about what was going on.

Library Linking

I am trying to learn to C programing using Zed Shaw's Learn C the hard way. I have been working on ex26 where we create a program "devpkg" used to install software. This exercise requires installing Apache Portable Runtime library. After writing the code for this exercise I could not get program to compile using the following makefile:
PREFIX?=/user/local
CFLAGS=-g -Wall -I${PREFIX}/apr/include/apr-1 -I{PREFIX}/apr/include/apr-util-1
LDFLAGS=-L${PREFIX}/apr/lib -lapr-1 -pthread -laprutil-1
all: devpkg
install: all
install -d${DESTDIR}/${PREFIX}/bin/
install devpkg ${DESTDIR}/${PREFIX}/bin/
clean:
rm -f *.o
rm -f devpkg
rm -f *.dSYM
This makefile did not seem to work as when I used "$make devpkg" not all of the APR library functions were declared. As a side note I am running this on a Ubuntu virtual machine. A solution given in the text says to alter a config file and then "run ldconfig" to help the linker find the appropriate library.
I do not understand the man page for ldconfig well enough to correctly utilize the function. How do run ldconfig correctly?
Also after some digging I found a reference that using "LDLIBS" instead of "LDFLAGS" in the makefile fixed the problem. I altered the makefile and the program compiled.
What is the difference between "LDFLAGS" and "LDLIBS" that allowed the C compiler to correctly link to the APR library? Is there a handy list of commands somewhere that can help me better understand how a makefile is correctly generated?
Thanks for your time.
From the GNU Make Manual, section 10.2 Catalogue of Implicit 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)'.
As you can see, LDFLAGS comes before your object file and LDLIBS after. Sometimes that order can matter - apparently it does in your case.
Editorial note: While it might sometimes be convenient to use make's implicit rule support, it almost always ends up more confusing down the road. I'd urge you to write a complete makefile - it'll help you understand what's going on better and hopefully avoid this sort of problem in the future.
I just wanted to add this answer as an alternative to changing "LDFLAGS" to "LDLIBS". The above solution did work in my case but I found an alternative (though less direct) solution before I saw this thread which others may find useful or interesting. When compiling I was seeing lots of "undefined reference" errors e.g.:
/MyCode/LCTHW/devpkg/devpkg.c:18: undefined reference to `apr_pool_initialize'
After much trial and error, I changed the makefile thus (still using LDFLAGS):
CC=gcc
PREFIX?=/usr/local
CFLAGS=-g -Wall -I$(PREFIX)/apr/include/apr-1 -I$(PREFIX)/apr/include/apr-util-1
LDFLAGS=-L$(PREFIX)/apr/lib -lapr-1 -laprutil-1 -pthread
OBJECTS=bstrlib.o db.o shell.o commands.o devpkg.o
all: devpkg
devpkg: $(OBJECTS)
$(CC) $(CFLAGS) $(OBJECTS) -o devpkg $(LDFLAGS)
install: all
install -d $(DESTDIR)/$(PREFIX)/bin/
install devpkg $(DESTDIR)/$(PREFIX)/bin/
clean:
rm -f *.o
rm -f devpkg
rm -rf *.dSYM
I then had to add a .conf file to /etc/ld.so.conf.d containing the path to the apr libraries, namely
/usr/local/apr/lib
And then run
sudo ldconfig
so the system would pick up the new .conf file and so know where to find the library. From what I have read, it seems this last step was necessary because the library wasn't stored in /usr/local/lib. If I remove the .conf file and re-run ldconfig to update, the program compiles but then fails to find the libraries at run-time (whether compiled with my makefile or OP's).
While I don't fully understand my solution, it at least allowed me to compile and run the program with no errors. Hopefully this solution will be of interest to others, and maybe somebody more knowledgeable will be able to explain in more detail why it works.

Using gfortran with libraries

I have a legacy code written using fortran 77. I'm trying to build it with gfortran. But I seem to be failing at the stage where I include the libraries in the build. The dozens of *.f source files compile fine, but when they are being linked, I get a bunch of "undefined reference" errors all relating to subroutines and functions that are defined in my libraries. I already ran the makefile for the libraries first, so the variables I need should all be exported. I'm playing with the "-L" option, but can't get it to work as desired.
First, here's my syntax of the linking line in my makefile:
29 $(PROGRAM): $(SRCS) $(LIBS)
30 $(FC) $(FLFLAGS) -o $# $+ -L$(DIRLIB)
PROGRAM is the program name, SRCS are all the compiled source files, LIBS is set to two different files - an archive file (file.a) and a file.o file.
FC is gfortran, I don't have any specific linking flags for FLFLAGS as of now, and DIRLIB is the main directory of the libraries.
The thing is that my *.o files that resulted from building my librarires don't reside in just the main directory, DIRLIB. DIRLIB contains several directories, all with their own *.o files that are needed by my code.
I tried adding each individual directory after the -L option (e.g. DIRLIB/DIR1/*.o DIRLIB/DIR2/*.o DIRLIB/DIR3/*.o), but I eventually start getting errors that some subroutines are multiply defined.
All this business of user-defined libraries and archive files just confuses me and I'm pretty new to making makefiles in the first place, so I'm just taking a shot in the dark here that somebody might be able to help me shed some light on this.
Libraries need to come after the .o files that reference them in the linking command.
I'm guessing the object file in LIBS comes after the library, but needs some of the procedures from it. Can you show the command that is actually run (with all variables expanded), to confirm this?
I tried to build this code again using the library. It worked this time. I'm pretty sure I'm doing the same thing in my makefile as I did before, so it must be related to the library I had. Maybe somebody altered it along the way and inadvertently broke it. But I got a fresh clean copy of the library. My steps are to:
1) run the makefile for the library source files; it creates a library.a archive file
2) run my code makefile:
it has a line to specify the location of this archive file and assign it to "DIRLIB"
DIRLIB := ../library
then the linking command of the makefile becomes
$(FC) $(FLFLAGS) -o $# $+ -L$(DIRLIB) -lskit
FC is my compiler, FLFLAGS are my linking flags, -L is the option specifying the location of libraries to be included and -lskit is a crucial option which appears to allow the use of F77 libraries... without the -lskit option, I get many undefined reference errors. It may have been that last time I was not including this -lskit option at the end.

Resources