Here is my makefile.
# The intuitive "all" target will be our default.
.DEFAULT_GOAL := all
# Component dir's to search and invoke make.
# (Try preserving the order of directories)
COM := src_dir1 src_dir2 src_dir3
PROJ_DIR = $(shell pwd)
EXEC := anonymousforconfidentiality
CC := g++
CFLAGS := -g3
LIBS = `pkg-config --cflags --libs glib-2.0 gio-unix-2.0 bluez protobuf lrt`
.PHONY : clean compile link all
all: | clean compile link
link:
$(eval $#_ALLOBJECTS := $(shell find . -name '*.o'))
$(CC) $(CFLAGS) -o $(EXEC) $($#_ALLOBJECTS) $(LIBS)
compile:
for COMDIR in $(COM) ; do \
$(MAKE) INCLUDE_PATH=$(PROJ_DIR) -C $$COMDIR ; \
done
clean:
for COMDIR in $(COM) ; do \
rm -f $$COMDIR/bin/*.o ; \
done
rm -f $(EXEC)
I am not able to link the library 'lrt'. I make extensive use of POSIX real time such as mq_open(), mq_send(), mq_receive() etc... So it is imperative I link it.
Some of the variations I tried:
1. librt
2. lrt
3. rt
4. librt-dev
However I always get this error:
Package lrt was not found in the pkg-config search path.
Perhaps you should add the directory containing `lrt.pc'
to the PKG_CONFIG_PATH environment variable
No package 'lrt' found
I even tried to manually install "librt" but was unsuccessful in locating the package. Nor did apt-get find it.
I was assuming this lib comes prepackaged with Ubuntu normal kernel (no real time patch). Need help with resolution of this issue.
You probably want to link rt library. This is done with -lrt. No need to use pkg-config for it.
E.g.:
LIBS := `pkg-config --libs glib-2.0 gio-unix-2.0 bluez protobuf` -lrt
Related
Pardon my question, I am a beginner to GCC. I have a framework project that holds source code for multiple subcomponents.
The structure is below:
Framework/
makefile //Master makefile in root
Component1/
src/
bin/
makefile
Component2/
src/
bin/
makefile
...
...
...
ComponentN/
src/
bin/
makefile
Now each makefiles in ComponentN/ each of directories will compile the code in its respective src/ and output .o to bin/ directory.
The root makefile however searches all the .o files recursively and links them all into one executable named 'framework'
Problem:
For code dependencies like glib,gdbus,gio I have to link them once when creating .o objects, in each of the component projects.
Plus I have to link the dependencies again when linking all the .o into one executable at root level.
Why do I have to do it twice? I am interested in understanding the internal mechanics.
As per request I am putting in makefile of the individual component libs that products *.o files
CC = gcc
CFLAGS = -g3
LIBS = `pkg-config --cflags --libs glib-2.0`
BINDIR = bin
OUTOBJ = $(addprefix $(BINDIR)/, objex.o)
$(BINDIR)/%.o : %.c
$(CC) -c $< $(CFLAGS) -o $# $(LIBS)
all: $(OUTOBJ)
$(OUTOBJ): | $(BINDIR)
$(BINDIR):
mkdir $(BINDIR)
.PHONY: clean
clean:
rm bin/*
Object files (.o) are created by compilation commands, e.g.
gcc -c -o foo.o foo.c ...
g++ -c -o baz.o baz.cpp ...
-c means compile; don't link. No linkage happens in the creation of
object files by the compiler. Any linkage options that you add to a compilation
command, e.g.
gcc -c -o foo.o foo.c -L/my/libs -lbar -lgum
are simply ignored.
Linkage options are acted on by a linkage command, which creates a program, or shared/dynamic
library, by linking together object files and libraries, e.g.
gcc -o prog foo.o baz.o -L/my/libs -lbar -lgum
gcc -shared -o libfoobaz.so foo.o baz.o -L/my/libs -lbar -lgum
So:
For code dependencies like glib,gdbus,gio I have to link them once when creating .o objects, in each of the component projects.
No you don't, and you can't.
Later
With sight of the problem makefile it is quite clear how to eliminate
the $(LIBS) reference from the compilation recipe, and what has been stopping you. The makefile defines:
LIBS = `pkg-config --cflags --libs glib-2.0`
which is a mistake. That makes $(LIBS) expand to the standard output of the
command:
pkg-config --cflags --libs glib-2.0
which is a single string containing both the compilation options required
for compiling source that #include-s the glib-2.0 API (on account of --cflags)
and also the linkage options required for linking a program or shared library
against libglib-2.0 (on account of --libs). On my system that is:
$ pkg-config --cflags --libs glib-2.0
-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -lglib-2.0
of which the compilation options alone would be output by:
$ pkg-config --cflags glib-2.0
-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include
and the linkage options alone would be output by:
$ pkg-config --libs glib-2.0
-lglib-2.0
But because both sets of options are available only together through the expansion
of $(LIBS) you cannot successfully compile without passing the
linkage option -lglib-2.0, which is redundant and ignored.
As your make tool is evidently GNU Make, the makefile (which BTW is not that bad!) would be better written as:
Makefile
CC := gcc
CFLAGS := -g3 $(shell pkg-config --cflags glib-2.0)
BINDIR := bin
SRCS := objex.c
OUTOBJ := $(addprefix $(BINDIR)/, $(SRCS:.c=.o))
.PHONY: all clean
all: $(OUTOBJ)
$(BINDIR)/%.o : %.c
$(CC) -c $< $(CFLAGS) -o $#
$(OUTOBJ): | $(BINDIR)
$(BINDIR):
mkdir -p $(BINDIR)
clean:
$(RM) $(OUTOBJ)
which dispenses with LIBS and runs from scratch like:
$ make
mkdir -p bin
gcc -c objex.c -g3 -I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -o bin/objex.o
Note a few other improvements:-
The use of immediate expansion (:=) wherever applicable in preference to unnecessary
recursive expansion (=). See 6.2 The Two Flavors of Variables
The use of direct shell substitution by make - $(shell command) - in preference to backtick-expansion in
recipe execution. See 8.13 The shell Function.
all, like clean is a phony target
and you need to tell make that it is, to avoid the booby-trap in which something creates a file called all in
the project directory without you noticing and make mysteriously stops detecting any work for it to do.
With your clean receipe:
clean:
rm bin/*
make clean will fail if ever run except following a successful build. The recipe
is replaced with $(RM) $(OUTOBJ), using GNU Make's predefined delete macro, which
won't fail.
Finally, remember that your linkage recipe, wherever it is, does need the library options for glib-2.0,
which you should provide in its makefile with:
LIBS := $(shell pkg-config --libs glib-2.0) # ...and any more library options required
for use in a recipe similar to:
prog: $(OBJS)
$(CC) -o $# $(LDFLAGS) $^ $(LIBS)
[1] Strictly, preprocessor options should appear in the definition of CPPFLAGS
(C PreProcessor Flags), not to be confused with CXXFLAGS (C++ compilation options).
[2] Strictly, linkage options other than libraries should appear in the definition
of LDFLAGS.
I searched on the inet but I did not find any clear answer. Could you point me in the right direction on how to convert a Makefile into a CMakeLists?
I want to do that because I am new both to makefile and to cmake. In my job CMake is more used and since I need to start using one of them I prefer having everything in CMake. I know CMake is generating a Makefile but for me CMake is way easier to read than a Makefile.
I have the following Makefile:
PREFIX ?= /usr/local
CC = gcc
AR = ar
CFLAGS = -std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4
APRILTAG_SRCS := $(shell ls *.c common/*.c)
APRILTAG_HEADERS := $(shell ls *.h common/*.h)
APRILTAG_OBJS := $(APRILTAG_SRCS:%.c=%.o)
TARGETS := libapriltag.a libapriltag.so
# LIBS := -Lusr/include/flycapture
.PHONY: all
all: $(TARGETS)
#$(MAKE) -C example all
.PHONY: install
install: libapriltag.so
#chmod +x install.sh
#./install.sh $(PREFIX)/lib libapriltag.so #this should be the line that install the library
#./install.sh $(PREFIX)/include/apriltag $(APRILTAG_HEADERS)
#sed 's:^prefix=$$:prefix=$(PREFIX):' < apriltag.pc.in > apriltag.pc
#./install.sh $(PREFIX)/lib/pkgconfig apriltag.pc
#rm apriltag.pc
#ldconfig
libapriltag.a: $(APRILTAG_OBJS)
#echo " [$#]"
#$(AR) -cq $# $(APRILTAG_OBJS)
libapriltag.so: $(APRILTAG_OBJS)
#echo " [$#]"
#$(CC) -fPIC -shared -o $# $^
%.o: %.c
#echo " $#"
#$(CC) -o $# -c $< $(CFLAGS)
.PHONY: clean
clean:
#rm -rf *.o common/*.o $(TARGETS)
#$(MAKE) -C example clean
I am not asking you to do my job but I would like to have some kind of guide or a good link where to look.
The project contains both C and C++ programming languages.
I started creating a new CMakeLists.txt file, but it is still not working. It gives me the following errors:
You have called ADD_LIBRARY for library librapriltag.a without any source files. This typically indicates a problem with your CMakeLists.txt file
-- Configuring done
CMake Error: Cannot determine link language for target "librapriltag.a".
CMake Error: CMake can not determine linker language for target: librapriltag.a
-- Generating done
-- Build files have been written to: .....
The CMakeLists.txt I started creating is the following:
project( apriltag2 C CXX)
cmake_minimum_required(VERSION 2.8)
set(CMAKE_C_FLAGS "-std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4")
include_directories("/home/fschiano/Repositories/apriltag2")
include_directories("/home/fschiano/Repositories/apriltag2/common")
add_library( librapriltag.a )
The CMakeLists.txt which works is the following:
project( apriltag2 )
cmake_minimum_required(VERSION 2.8)
set(CMAKE_C_FLAGS "-std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4")
message("CMAKE_SOURCE_DIR=${CMAKE_SOURCE_DIR}")
file(GLOB apriltag_SRC "*.c")
file(GLOB apriltag_HEADERS "*.h")
set(APRILTAG_SRCS ${apriltag_SRC})
set(APRILTAG_HEADERS ${apriltag_HEADERS})
message(STATUS "CMAKE_CURRENT_LIST_DIR=${CMAKE_CURRENT_LIST_DIR}")
add_library(apriltag STATIC ${APRILTAG_SRCS})
target_include_directories(apriltag PUBLIC ${CMAKE_SOURCE_DIR})
target_compile_options(apriltag PUBLIC -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -O4)
install(TARGETS apriltag
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib)
install(DIRECTORY CMAKE_CURRENT_LIST_DIR/include/
DESTINATION CMAKE_CURRENT_LIST_DIR/include/
FILES_MATCHING PATTERN *.h)
EDIT:
Something is still not right. If I want to change something in my library, like something which is in /home/fschiano/Repositories/apriltag2/common
If I use the Makefile which I had before doing all these modifications and I do:
make
do some modifications in the files I wanted to modify
sudo make install, which would give me the following output:
/usr/local/lib/libapriltag.so
/usr/local/include/apriltag/apriltag.h
/usr/local/include/apriltag/common/g2d.h
/usr/local/include/apriltag/common/getopt.h
/usr/local/include/apriltag/common/homography.h
/usr/local/include/apriltag/common/image_f32.h
/usr/local/include/apriltag/common/image_u8.h
/usr/local/include/apriltag/common/image_u8x3.h
/usr/local/include/apriltag/common/matd.h
/usr/local/include/apriltag/common/math_util.h
/usr/local/include/apriltag/common/pnm.h
/usr/local/include/apriltag/common/postscript_utils.h
/usr/local/include/apriltag/common/string_util.h
/usr/local/include/apriltag/common/svd22.h
/usr/local/include/apriltag/common/thash_impl.h
/usr/local/include/apriltag/common/timeprofile.h
/usr/local/include/apriltag/common/time_util.h
/usr/local/include/apriltag/common/unionfind.h
/usr/local/include/apriltag/common/workerpool.h
/usr/local/include/apriltag/common/zarray.h
/usr/local/include/apriltag/common/zhash.h
/usr/local/include/apriltag/common/zmaxheap.h
/usr/local/include/apriltag/tag16h5.h
/usr/local/include/apriltag/tag25h7.h
/usr/local/include/apriltag/tag25h9.h
/usr/local/include/apriltag/tag36artoolkit.h
/usr/local/include/apriltag/tag36h10.h
/usr/local/include/apriltag/tag36h11.h
/usr/local/lib/pkgconfig/apriltag.pc
/sbin/ldconfig.real: /usr/lib/libstdc++.so.5 is not a symbolic link
and the modifications would take effect.
Now, if I remove the Makefile and I do:
cmake .
make
do some modifications in the files I wanted to modify
sudo make install, it gives me the following output:
Install the project...
-- Install configuration: ""
-- Up-to-date: /usr/local/lib/libapriltag.a
So it seems that the install part of the CMakeLists.txt is not right!
The file install.sh is the following.
#!/bin/sh -e
# Usage: install.sh TARGET [RELATIVE PATHS ...]
#
# e.g. ./install.sh /usr/local foo/file1 foo/file2 ...
# This creates the files /usr/local/foo/file1 and /usr/local/foo/file2
TARGETDIR=$1
shift
for src in "$#"; do
dest=$TARGETDIR/$src
mkdir -p $(dirname $dest)
cp $src $dest
echo $dest
done
Could you try to help me?
Thanks
Let's go through that step-by-step:
PREFIX ?= /usr/local
We ignore that, as it's the default. Can be overwritten by CMAKE_INSTALL_PREFIX.
CC = gcc
AR = ar
Ignore these as well. Use CMAKE_C_COMPILER and CMAKE_CXX_COMPILER to forcibly switch the compiler.
CFLAGS = -std=gnu99 -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -I. -O4
They are pretty special for gcc-like compilers. Set them conditionally for CMAKE_C_COMPILER_ID MATCHES GNU further down after defining the target.
The standard is set by set(C_STANDARD 98) and set(CXX_STANDARD 98).
APRILTAG_SRCS := $(shell ls *.c common/*.c)
Define a variable listing all the source files individually: set(APRILTAG_SRCS ...)
APRILTAG_HEADERS := $(shell ls *.h common/*.h)
Define a variable listing all the header file individually: set(APRILTAG_HEADERS ...). However, you don't really need them anywhere (unless you want Visual Studio to list them).
APRILTAG_OBJS := $(APRILTAG_SRCS:%.c=%.o)
In most cases, you don't need that. For those rare cases there are Object Libraries.
TARGETS := libapriltag.a libapriltag.so
# LIBS := -Lusr/include/flycapture
We define our libraries here with add_library:
add_library(apriltag ${APRILTAG_SRCS})
target_include_directories(apriltag PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include/apriltag)
target_compile_options(apriltag PUBLIC -fPIC -Wall -Wno-unused-parameter -Wno-unused-function -O4)
The switch between static and shared is done via BUILD_SHARED_LIBS on invocation of CMake.
.PHONY: all
all: $(TARGETS)
#$(MAKE) -C example all
Nothing to do here. CMake will automatically create that.
.PHONY: install
install: libapriltag.so
#chmod +x install.sh
#./install.sh $(PREFIX)/lib libapriltag.so #this should be the line that install the library
#./install.sh $(PREFIX)/include/apriltag $(APRILTAG_HEADERS)
#sed 's:^prefix=$$:prefix=$(PREFIX):' < apriltag.pc.in > apriltag.pc
#./install.sh $(PREFIX)/lib/pkgconfig apriltag.pc
#rm apriltag.pc
#ldconfig
CMake will ease this up by a magnitude:
install(TARGETS apriltag
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
LIBRARY DESTINATION lib)
install(DIRECTORY include/
DESTINATION include/
FILES_MATCHING PATTERN *.h)
That will install the library static and shared library (whatever exists) and the header files.
libapriltag.a: $(APRILTAG_OBJS)
#echo " [$#]"
#$(AR) -cq $# $(APRILTAG_OBJS)
libapriltag.so: $(APRILTAG_OBJS)
#echo " [$#]"
#$(CC) -fPIC -shared -o $# $^
%.o: %.c
#echo " $#"
#$(CC) -o $# -c $< $(CFLAGS)
All this is not needed.
.PHONY: clean
clean:
#rm -rf *.o common/*.o $(TARGETS)
#$(MAKE) -C example clean
You don't need that. CMake will generate a clean target automatically.
Judging from TARGETS := libapriltag.a libapriltag.so, you'll defintely need add_library command to create targets.
Instead of gathering souces to be compiled using wildcards like APRILTAG_SRCS := $(shell ls *.c common/*.c) it is recommended to list them explicitly in add_library call. But if you really want to list them automatically, see file(GLOB ...) command. (There are some important things to be aware of, though, see Specify source files globally with GLOB?).
The clean target would be generated automatically by CMake.
Finally, see the documentation for install() command to create install rules.
Compiler flags are set using set(CMAKE_C_FLAGS "blabla"), or appended using set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} blabla").
I'm writing a makefile like so:
LIB_DIR = $(shell pwd)/.linuxbrew/Cellar/boost/1.62.0/
FLAGS = -std=c++14
INC= -I$(LIB_DIR)include
LIB_PATH = -L$(LIB_DIR)lib
LIB = $(LIB_DIR)lib
LIBNAMES := filesystem-mt filesystem system-mt system
LIBS := $(foreach N,$(LIBNAMES),$(LIB)libboost_$N.a $(LIB)libboost_$N.dylib)
PATH = /Some/Path/
default:
g++ main.cpp $(FLAGS) $(INC) $(LIB_PATH) $(LIBS) -o assemble
./assemble $(PATH)
clean:
rm assemble
The problem is, once I include the variable 'LIB_DIR', it complains that g++ can't be found. I could use some help.
It's not LIB_DIR, but rather PATH that's killing you. Try commenting out that line. (I'm assuming g++ is not in /Some/Path/)
Try the below command:
yum groupinstall 'Development Tools'
The command install all development tools like make, gcc, etc.
I've searched around for this issue, but nobody but me seems to have it, which is why I'll now ask.
If have this basic makefile:
CCPP = arm-none-linux-gnueabi-g++
CFLAGS = "-WALL -DPLATFORM_TARGET -DPRINT_MESSAGE"
LIB = lib/libarm.a
LDFLAGS = -lpthread
OBJECTS = $(wildcard ./*/*.o)
PROG = /exports/appl
MODULES = lib src
all: $(PROG)
$(CCPP) $(LDFLAGS) $(OBJECTS) $(LIB) -o $(PROG)
$(PROG): $(MODULES)
#for i in $(MODULES); do (cd $$i && $(MAKE) \
CCPP=$(CCPP) LDPP=$(CCPP) CFLAGS=$(CFLAGS) LDFLAGS=$(LDFLAGS)) || exit 1 ;\
done
clean:
#for i in $(MODULES); do (cd $$i && $(MAKE) clean) || exit 1 ; done
rm $(PROG)
lib:
ar cr ../lib/$(LIB) $(OBJECTS)
This works. It takes whatever source file is within lib and src and compiles and links it nicely together. (By using local makefiles found in these folders which I can post too if need be)
Anyway, what I WANT now, is add more -D directives conditionally.
I've tried:
ifdef ALLOW_BACKTRACE
CFLAGS += -DALLOW_BACKTRACE
LDFLAGS += -rdynamic
endif
and also:
ifdef ALLOW_BACKTRACE
CFLAGS := $(CFLAGS) -DALLOW_BACKTRACE
#endif
or by putting the whole thing in quotes etc...but each time I try, it brings up the help page of make, telling me that it can't 'recognize' the new define.
Any idea what I'm doing wrong?
Any help is much appreciated.
Okay, this should be a more correct version of your makefile, I can not test it though because I don't have your sources:
export CCPP := arm-none-linux-gnueabi-g++
# Note that -pthread is required for both compiling and linking.
export CFLAGS := -pthread -WALL -DPLATFORM_TARGET -DPRINT_MESSAGE
export LDFLAGS := -pthread
LIB := lib/libarm.a
PROG := /exports/appl
MODULES := lib src
all: $(PROG)
$(PROG): $(MODULES)
$(CCPP) -o $# $(LDFLAGS) ./*/*.o $(LIB)
$(MODULES) : % :
$(MAKE) -C $#
touch $#
clean-module.%:
$(MAKE) -C $* clean
clean : $(MODULE:%=clean-module.%)
rm -f $(PROG)
.PHONY: all clean clean-module.%
What I changed:
LDFLAGS = -lpthread: when building multi-threaded applications you need both an extra compiler and linker flag, which is what -pthread/-pthreads gcc options is.
Contents of OBJECTS = $(wildcard ./*/*.o) are only correct when $(MODULES) built correctly. Removed it.
$(PROG) commands actually build $(PROG) target as it should.
$(MODULES) commands build the modules by invoking make in the corresponding directory. And then they update the timestamp of the directory to force rebuild of $(PROG). Since it is a recursive make it can't know whether anything have actually been updated in the module, hence it need to trigger the rebuild of anything that depends on the modules.
I still have a feeling that this won't work for you because your original makefile is missing dependencies.
Try doing this -->
ifeq ($(ALLOW_BACKTRACE),1)
CFLAGS += -DALLOW_BACKTRACE
endif
You've got to be KIDDING me!
Ahem. I seem to have found the solution to my own problem. I don't quite get it, but whatever works, right?
Anyway, here's what I did:
CFLAGS += -Wall -DPLATFORM_TARGET -DPRINT_MESSAGE
ifdef ALLOW_BACKTRACE
CFLAGS += -DALLOW_BACKTRACE
LDFLAGS += -rdynamic
endif
LDFLAGS += -lpthread
$(PROG): $(MODULES)
#for i in $(MODULES); do (cd $$i && $(MAKE) \
CCPP=$(CCPP) LDPP=$(CCPP) CFLAGS="$(CFLAGS)" LDFLAGS=$(LDFLAGS)) || exit 1 ;\
done
First thing: -rdynamic needs to be the first flag in the linker, otherwise it refuses to work. (Don't ask me why, if anyone could enlighten me, be my guest.
Second: I had to put quotes around the expanded $(CFLAGS) in my actual build step. As soon as I did that, it worked like a charm...probably because it had a problem with the spaces.
Thanks to everyone, who went to the trouble of trying to help me.
My makefile looks as follows
program_NAME := myprogram
program_C_SRCS := $(wildcard *.cc)
program_C_OBJS := ${program_C_SRCS:.cc=.o}
program_OBJS := $(program_C_OBJS)
program_INCLUDE_DIRS := ../INCLUDE
program_LIBRARY_DIRS :=
program_LIBRARIES :=
CPPFLAGS += $(foreach includedir,$(program_INCLUDE_DIRS),-I$(includedir))
LDFLAGS += $(foreach librarydir,$(program_LIBRARY_DIRS),-L$(librarydir))
LDFLAGS += $(foreach library,$(program_LIBRARIES),-l$(library))
.PHONY: all clean distclean
all: $(program_NAME)
$(program_NAME): $(program_OBJS)
$(LINK.cc) $(program_OBJS) -o $(program_NAME)
clean:
#- $(RM) $(program_NAME)
#- $(RM) $(program_OBJS)
distclean: clean
I have created a library stack.a in some path /home/Desktop/kk/stack.
I want to include this library into my makefile so that during linking it should be picked up from that path.
I tried to give:
program_LIBRARY_DIRS := /home/Desktop/kk/stack
and in linking step I gave:
$(LINK.cc) $(program_OBJS) stack.a -o $(program_NAME)
But the makefile is not able to pick up the library from the path mentioned.
Instead, if I directly give:
$(LINK.cc) $(program_OBJS) /home/Desktop/kk/stack/stack.a -o $(program_NAME)
it works perfectly.
Please help me how to include this library path so that I do not have to give the location of library in link command.
The -L link option only applies to libraries named libX.a or libX.so and linked using -lX, for some string X. You would need to rename stack.a to libstack.a and refer to it in the link command as -lstack.
(You should also, ideally, put that in the program_LIBRARIES definition and use that in the $(LINK.cc) line.)