我正在尝试学习如何使用linux makefile。
我有以下两个文件:
# 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
我该如何解决这个问题? (防止在链接步骤之前执行清洁对象步骤)
答案 0 :(得分:2)
如果使用clean
,则无法添加all
作为-j
目标的先决条件,因为它将与链接器并行运行并删除文件是比连接它们快得多。
因此,您必须从clean
变量中移除ALL_PARAMETERS
目标,然后您才能删除链接行中间的对象。
我不知道你为什么要在每次运行后删除所有对象:如果你每次都要从头开始重建所有东西,你根本不需要make或makefiles:只需创建一个shell脚本。使用makefile的重点是避免重建没有改变的项目部分。
但是,如果你真的想这样做那么最简单的方法可能是使用递归make;例如:
all: $(ALL_PARAMETERS)
$(MAKE) clean
只有在all
的所有先决条件完全构建完成后才会进行清理,即使您使用-j
运行。