如何在链接之前阻止Makefile清理对象(使用-j选项)

时间:2016-12-08 22:04:53

标签: linux makefile gnu

我正在尝试学习如何使用linux makefile。

我有以下两个文件:

makefile.config

# Project Configurations

   # Project Name

   PROJECT_NAME               =           myapp

   # Project Version

   PROJECT_VERSION            =           0.1

   # Program or Shared Library

   IS_LIBRARY                 =           no

   # Source Files Directory

   SRC_DIRECTORY              =           src

   # Header Files Directory

   INC_DIRECTORY              =           inc

   # Library Header Files Directory

   LIB_DIRECTORY              =           lib

   # Build Output Directory   

   BIN_DIRECTORY              =           ../Executable

   # Installation Directory Exec

   INS_DIRECTORY               =           /usr/local/bin/

   # Installation Directory Headers

   INS_HEARERS_DIRECTORY       =           /usr/local/include/

   # Installation Directory SO      

   INS_SO_DIRECTORY            =           /usr/local/lib/

   # C Flags

   CFLAGS                     =           -O3 -D_GNU_SOURCE -Wfatal-errors

   # C++ Flags

   CXXFLAGS                   =           $(CFLAGS)

   # Linker Flags

   LDFLAGS                    =           $(shell dpkg-buildflags --get LDFLAGS)

   # Linker Libraries

   LDLIBS                     =           -fno-inline 

   # Debug Yes / No

   DEBUG                      =           yes

   # C Compiler

   CC                         =           gcc

   # C++ Compiler

   CXX                        =           g++

生成文件

$(info  Starting building process)

# include configurations

include makefile.conf

$(info  - Makefile.conf loaded)

# find project files

H_FILES   :=    $(shell find -L ./ -name '*.h' -exec dirname {} \; | sed 's/ /\\ /g' | uniq)

C_FILES   :=    $(shell find ./ -name '*.c' -type f | sed 's/ /\\ /g' | uniq)

CXX_FILES :=    $(shell find ./ -name '*.cpp' -type f | sed 's/ /\\ /g' | uniq)

O_FILES   :=    $(C_FILES:.c=.o)

O_FILES   +=    $(CXX_FILES:.cpp=.o)

H_FILES   :=    $(notdir  $(H_FILES))

C_FILES   :=    $(notdir  $(C_FILES))

CXX_FILES :=    $(notdir  $(CXX_FILES))

INCLUDES  :=    $(H_FILES:%=-I%)

$(info  - Project Files Loaded)


ifeq ($(DEBUG),yes)

   $(info  - Debug flag added [makefile.conf DEBUG = yes])

   CFLAGS := -g3 $(CFLAGS)

endif


ifeq ($(IS_LIBRARY),yes)

   $(info  - Set Parameters for Shared Library build process)

   ALL_PARAMETERS = lib$(PROJECT_NAME).so.$(PROJECT_VERSION) clean

   ALL_TYPE = lib$(PROJECT_NAME).so.$(PROJECT_VERSION): $(O_FILES)

   LIBFLAGS = -shared -Wl,-soname,lib$(PROJECT_NAME).so

   CFLAGS :=  -fPIC $(CFLAGS)

   CXXFLAGS := -fPIC $(CXXFLAGS)

else

   $(info  - Set Parameters for Application build process)

   ALL_PARAMETERS = $(PROJECT_NAME) clean

   ALL_TYPE = $(PROJECT_NAME): $(O_FILES)

   LIBFLAGS =

endif

# Build Process

all: $(ALL_PARAMETERS)

$(ALL_TYPE)
    @echo -  [OUTPUT][CXX] $@ @[$(BIN_DIRECTORY)]
    @$(CXX) $(CFLAGS) $(INCLUDES) $(LDFLAGS) $(LIBFLAGS) -o $(BIN_DIRECTORY)/$@ $^ $(LDLIBS)

%.o: %.c
    @echo -  [CC] $@
    @$(CC) $(CFLAGS) -c $(INCLUDES) -o $@ $< $(LFLAGS)

%.o: %.cpp
    @echo -  [CXX] $@
    @$(CXX) $(CXXFLAGS) -c $(INCLUDES) -o $@ $< $(LFLAGS)

# Clear Objects

clean:
    $(info  - Remove all .o [object] files)
    @find . -name \*.o -type f -delete

# Clear Objects & Executables 

cleanall:   
    $(info  - Remove all .o [object] files)
    @find . -name \*.o -type f -delete
    $(info  - Remove all files in $(BIN_DIRECTORY))
    @find $(BIN_DIRECTORY) -name \*.* -type f -delete

# Install Project 

install:
    @cp -r $(BIN_DIRECTORY)/lib$(PROJECT_NAME).so.$(PROJECT_VERSION) $(INS_SO_DIRECTORY)
    @cp -r $(LIB_DIRECTORY)/* $(INS_HEARERS_DIRECTORY)
    @ln -s $(INS_SO_DIRECTORY)/lib$(PROJECT_NAME).so.$(PROJECT_VERSION) $(INS_SO_DIRECTORY)/lib$(PROJECT_NAME).so
    @ldconfig
    $(info  - Installation completed)

# Uninstall Project 

uninstall:
    @rm $(INS_SO_DIRECTORY)/lib$(PROJECT_NAME).so
    @rm $(INS_SO_DIRECTORY)/lib$(PROJECT_NAME).so.*.*
    @rm $(INS_HEARERS_DIRECTORY)/$(PROJECT_NAME).h
    @ldconfig
    $(info  - Uninstallation completed)

一切都很完美......至少对于我用它来做什么..但是当我尝试用-j选项执行makefile时(例如)

$ make -j4

该过程在链接之前清除对象(.o)。

iikem@isca-lab:Source Code$ make -j4
Starting building process
- Makefile.conf loaded
- Project Files Loaded
- Debug flag added [makefile.conf DEBUG = yes]
- Set Parameters for Shared Library build process
- [CXX] src/isca-streamer.o
- [CXX] src/isca-streamer-pause.o
- [CXX] src/isca-streamer-thread-image.o
- [CXX] src/isca-streamer-initialize.o
- [CXX] src/isca-streamer-start.o
- [CXX] src/isca-streamer-stop.o
- [CXX] src/isca-streamer-thread-socket.o
- [CXX] src/isca-streamer-clear.o
- Remove all .o [object] files
- [CXX] src/isca-streamer-settings.o
- [OUTPUT][CXX] libisca-streamer.so.0.1 @[../Executable]
g++: error: src/isca-streamer.o: No such file or directory
g++: error: src/isca-streamer-initialize.o: No such file or directory
g++: error: src/isca-streamer-thread-image.o: No such file or directory
g++: error: src/isca-streamer-pause.o: No such file or directory
g++: error: src/isca-streamer-start.o: No such file or directory
g++: error: src/isca-streamer-stop.o: No such file or directory
Makefile:71: recipe for target 'libisca-streamer.so.0.1' failed
make: *** [libisca-streamer.so.0.1] Error 1

我该如何解决这个问题? (防止在链接步骤之前执行清洁对象步骤)

1 个答案:

答案 0 :(得分:2)

如果使用clean,则无法添加all作为-j目标的先决条件,因为它将与链接器并行运行并删除文件是比连接它们快得多。

因此,您必须从clean变量中移除ALL_PARAMETERS目标,然后您才能删除链接行中间的对象。

我不知道你为什么要在每次运行后删除所有对象:如果你每次都要从头开始重建所有东西,你根本不需要make或makefiles:只需创建一个shell脚本。使用makefile的重点是避免重建没有改变的项目部分。

但是,如果你真的想这样做那么最简单的方法可能是使用递归make;例如:

all: $(ALL_PARAMETERS)
        $(MAKE) clean

只有在all的所有先决条件完全构建完成后才会进行清理,即使您使用-j运行。