gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:08:56 26 4
gpt4 key购买 nike

我正在尝试学习如何使用 linux 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

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

最佳答案

如果您使用 -j,则不能将 clean 添加为 all 目标的先决条件,因为它将并行运行使用链接器删除文件比链接它们要快得多。

因此,您必须从 ALL_PARAMETERS 变量中删除 clean 目标,这样您就不会再删除链接行中间的对象。

我不知道你为什么要在每次运行后删除所有对象:如果你每次都要从头开始重建一切,你甚至根本不需要 make 或 makefile:只需创建一个 shell 脚本。使用 makefile 的全部意义在于避免重建项目中未更改的部分。

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

all: $(ALL_PARAMETERS)
$(MAKE) clean

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

关于linux - 如何防止 Makefile 在链接之前清理对象(使用 -j 选项),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41049663/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com