FibreBoy a écrit :
I have been coding Windows API code under Borland IDE for the last three
years and am now moving into a project based on QNX. Since I haven’t had
to look at a Makefile in three years I seem to be having way too much
trouble trying to get my Makefile to behave properly. I am trying to
build a simple user level application with 3 source files and 3 header
files. I used to code extensively in VxWorks. I have tried to take an
old VxWorks makefile and adapt it to QNX.
My goal is to have the makefile recompile the proper source file if it
or any of its dependent header files have been modified and then relink
the binary. At present it will recompile a module if the source or
header file has changed but it will not rebuild the binary image. I am
also trying to store the object files and header files in there
respective directories. With the makefile I have included here, I
basically have to “make clean” and then “make” to rebuild the entire
app each time I change anything.
There is no system rebuild involved, just a simple user level
application. I would also like to only edit the top part of the file in
one place when adding a new source or header file rather than the old
fashioned way of creating a whole new compile line for each source
module in the application.
Can anyone take a quick look and point out the error of my ways or
possibly provide a short makefile to accomplish my goal ?
As you can see in the file below I have not been able to get the object
modules to be written to a seperate subdirectory.
DEST_DIR =/home/johndoe/bin
TARGET_DIR = .
OBJ_DIR = ./objs
LOCAL_INCS = ./inc
APP = $(DEST_DIR)/demo
OBJS = $(TARGET_DIR)/demo.o
$(TARGET_DIR)/dbgout.o
$(TARGET_DIR)/BldFrame.o
#OBJS = $(OBJ_DIR)/demo.o \
$(OBJ_DIR)/dbgout.o \
$(OBJ_DIR)/BldFrame.o
INCS = $(LOCAL_INCS)/demo.h
$(LOCAL_INCS)/sysheaders.h
$(LOCAL_INCS)/fceerror.h
CFLAGS =-I$(LOCAL_INCS) -nopipe
CC = qcc
LD = qcc
LINKFLAGS = -o $(APP)
LPTH =
LIBS =
$(APP): $(OBJS) $(INCS)
$(LD) $(LINKFLAGS) $(LPTH) $(OBJS) $(LIBS)
$(OBJS): $(INCS)
.c.o: ; $(CC) $(CFLAGS) -c -o $(OBJ_DIR)/$@ $
clean:
rm -f $(OBJS)
rm -f $(APP)
I suggest you to forget such makefiles and to move to recursive makefiles.
It’ really VERY powerfull.
Try to organize your application like it follows, starting your directory
tree by ./src, it’s imperative!
you will have something like that:
/home/you/src/product_name/project_name/subproject/nto/x86/o
in details with an example. Just imagine that this example is an application
with a server and a client:
/home/you/src/
|
-/helloworld
|
|- Makefile
|- /helloworld
| |-Makefile
| |-common.mk
| |-helloworld.use
| |-your_source_and_header_files
| |-/nto
| |-Makefile
|
|-some_specific_neutrino_source_and_header_files_if_any
| |-/x86
|
|-some_specific_x86_source_and_header_files_if_any
| |-Makefile
| |-/o
| |-Makefile
|
|- /client
|-Makefile
|-common.mk
|-client.use
|-your_source_and_header_files
|-/nto
|-Makefile
|-some_specific_neutrino_source_and_header_files_if_any
|-/x86
|-Makefile
|-some_specific_x86_source_and_header_files_if_any
|-/o
|-Makefile
In your makefiles, except whose are in /o directories, just write:
include recurse.mk
It’ a magic formula to invoke the Big Spirit.
In the Makefile located in /o, just write:
include …/…/…/common.mk
to be able to find the common.mk file.
We are going to create a very basic common.mk file:
ifndef QCONFIG
QCONFIG=qconfig.mk
endif
include $(QCONFIG)
include $(MKFILES_ROOT)/qmacros.mk
include $(MKFILES_ROOT)/qtargets.mk
It’s enough like that!
Now, if you want to deal with dependencies, you can write in the common.mk
in /Helloworld/client/:
ifndef QCONFIG
QCONFIG=qconfig.mk
endif
include $(QCONFIG)
include $(MKFILES_ROOT)/qmacros.mk
include $(MKFILES_ROOT)/qtargets.mk
client.o: client.c client.h
$(PROJECT): client.o
Do the same in /Helloworld/Helloworld/ if you want
The location where is the common.mk give the name to your executable based
on the name of it’s directory (by default)
so, you will have two executables, Helloworld, and client.
The .use files can be empty to begin.
Now, it maybe incredible but if you cd /home/you/src/Helloworld and type
make, everything will be built!
You need an executable with debug infos?
just do that:
$cd /home/you/src/Helloworld
$mkdir client/nto/x86/o.g
$cp client/nto/x86/o/Makefile client/x86/o.g/
$make
You need a shared library to provide an API to your server, just do that:
$mkdir -p Helloworld_API/nto/x86/so
$mkdir Helloworld_API/nto/x86/so.g
$
Of course, you may need to build the API before building the client. It’s
possible!
You may no need to add API dependencies to rebuild the client. It’s
possible!
Look at “Conventions for Makefiles and Directories” in the Helpviewer for
more infos.
It’s not always very clear, articles will come soon.
hope it’s enough to begin!
Alain.