c++ - 无法使用单独的文件夹获取生成文件以使头文件正常工作

标签 c++ c makefile directory-structure

我有一个为共享库创建 makefile 的小问题,但程序 API 的主要头文件位于库项目源文件的单独文件夹中(有许多不同的共享库所有访问这些公共(public)头文件的库项目)。 我的文件夹结构有时是这样的:

-Folder
 |
 +--API Header Files Dir
 |
 +--Library (.so) Project One
 |  +-- MakeFile Project One
 |  +-- *.cpp files
 |
 +--Library (.so) Project Two
 |  +-- MakeFile Project Two
 |  +-- *.cpp files
 |
 +--Library (.so) Project Three
 |  +-- MakeFile Project Three
 |  +-- *.cpp files

其中每个库项目彼此无关,但每个项目都需要访问 “API 头文件目录” 中的 *.h 文件。

因为每个库中的源文件数量可能在 1-20 之间变化,具体取决于库的复杂性,我想编写一个 makefile 来简单地在当前目录中搜索 .cpp 文件并包含头文件另一个目录。

最大的问题是,我仍然不太了解make文件的复杂性,而且我把它弄得一团糟。

# Makefile template for shared library

##############################################################################
# Application-specific variables
# TARGET_LIB is the name of the shared library file
# SRCS is a list of all source code files that must be linked
#           to create the executable
##############################################################################

MAJOR := 1
MINOR := 2
NAME := Test
VERSION := $(MAJOR).$(MINOR)
TARGET_LIB: lib$(NAME).so.$(VERSION) # target lib

# define the C source files 
SRCS = srcFile1.cpp srcFile2.cpp \
    srcFile3.cpp srcFile4.cpp srcFile5.cpp \
    srcFile6.cpp srcFile7.cpp


##############################################################################
# Where to find related files
# API_DIR is where various header files (.h) 
# relating to the API are found.  
# LIB_DIR is where other libraries (not specific) are kept.

# for header files and additional libraries
API_DIR = ../API_SRC_Files
LIB_DIR = 

# What flags should be passed to the C pre-processor
#   In other words, where should we look for files to include - note,
#   you should never need to include compiler specific directories here
#   because each compiler already knows where to look for its system
#   files (unless you want to override the defaults)
#   define any directories containing header files other than /usr/include

INCLUDES = -I. \
           -I$(API_DIR)

##############################################################################
# Compiler specifications
# These match the variable names given in /usr/share/lib/make/make.rules
# so that make's generic rules work to compile our files.
# gmake prefers CXX and CXXFLAGS for c++ programs
############################################################################## 
# Which compiler should be used
# Which compiler should be used
CXX = g++
CC = $(CXX)

# What flags should be passed to the compiler
OPTIMIZE = -O3
DEBUG_LEVEL =       # -g if debug version
CFLAGS = -fPIC -Wall -Wextra -march=native $(OPTIMIZE) $(DEBUG_LEVEL) $(INCLUDES)

# What flags should be passed to the linker
#   In other words, where should we look for libraries to link with - note,
#   you should never need to include compiler specific directories here
#   because each compiler already knows where to look for its system files.
LDFLAGS = -shared 

# For tidying up
RM = rm -f  # rm command

# define the C object files 
#
# This uses Suffix Replacement within a macro:
#   $(name:string1=string2)
#         For each word in 'name' replace 'string1' with 'string2'
# Below we are replacing the suffix .c of all words in the macro SRCS
# with the .o suffix
#
OBJS = $(SRCS:%.cpp=%.o)

 ###########################################################################
# Additional rules make should know about in order to compile our files
###########################################################################
# all is the default rule
.PHONY: all

all: ${TARGET_LIB}
    @echo  Library file has been compiled

lib$(NAME).so.$(VERSION): $(OBJS)
    $(CC) $(CFLAGS) ${LDFLAGS} -o $@ $^

$(SRCS:%.cpp=%.d):%.d:%.cpp 
    $(CC) $(CFLAGS)  -MM $< >$@

include $(SRCS:%.cpp=%.d)

 # clean up after you're done
.PHONY: clean
clean:
    -${RM} ${TARGET_LIB} ${OBJS} $(SRCS:%.cpp=%.d)

无论如何,就像我说的,我已经把它弄得一团糟并且真的不知道问题出在哪里,只是 g++ 随时调用它的头文件之一只是在所有与找不到头文件相关的编译错误之前吐出“没有这样的文件或目录”。

任何帮助解决这个问题的帮助将不胜感激 - 如果有一个简单的方法来为创建的 .so 文件构建目录也很有用 - 但那是在我首先得到编译的东西之后!

最佳答案

是的,您的 makefile 很乱。过多的注释实际上不会有助于提高可读性。我为您清理了它:

NAME := Test
MAJOR := 1
MINOR := 2
VERSION := $(MAJOR).$(MINOR)
TARGET_LIB := lib$(NAME).so.$(VERSION)

SRC := $(wildcard *.cpp)
OBJ := $(SRC:.cpp=.o)
DEP := $(OBJ:.o=.d)

# preprocessor flags
CPPFLAGS := -MMD -MP -I../API_SRC_Files
# C++ compiler flag
CXXFLAGS := -Wall -W -fPIC -O3 -march=native
# Linker parameter flags
LDFLAGS  := -shared
# Linker library flags
LDLIBS   :=

.PHONY: all debug clean

all: $(TARGET_LIB)

debug: CXXFLAGS += -g
debug: $(TARGET_LIB)

$(TARGET_LIB): $(OBJ)
    $(CXX) $(LDFLAGS) $^ $(LDLIBS) -o $@

clean:
    $(RM) $(TARGET_LIB) $(OBJ) $(DEP)

ifeq "$(MAKECMDGOALS)" ""
-include $(DEP)
endif
  • 不要在使用 C++ 时使用 $(CC)$(CFLAGS),使用 $( CXX)$(CXXFLAGS) 代替(这里编译 .o 文件的内置规则就够了,不需要自己使用)。

  • 不要到处散布你的旗帜,保持清晰。

  • 不要不必要地重新定义所有内容:$(RM) 已经按照您想要的方式定义(-f 意味着您不需要破折号在像 -$(RM) 这样的调用中,因为它无论如何都不会失败),$(CXX) 也已经按照你想要的方式定义了。

    <
  • 阅读(甚至部分)manual当您并不真正了解自己在做什么时,这是一个很好的起点。

关于c++ - 无法使用单独的文件夹获取生成文件以使头文件正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31344202/

相关文章:

将 ASCII 字符串转换为 Unicode? Windows,纯 C

c - 如何在 C 中动态定义矩阵

c++ - C++中的继承

c++ - 如何使用 ShellExecuteEx 确保 exe 启动

c++ - DirectShow 视频在音频引脚渲染数据时播放速度过快

c - 纪元(以秒为单位)到 C 中的 MJD 转换

c++ - std::shared_ptr 传递删除器

c++ - 对我的 Makefile 如何重新制作目标文件感到困惑

linux - 在 Makefile 安装中移动目录的最佳方式是什么?

c - 具有不同目录的 Makefile 隐式规则