我使用C和C ++,感谢this answer我能够编译并运行我的项目。现在我正在写一个makefile来腾出时间。但事情变得越来越复杂了:
项目结构
- 项目
- 生成文件
- 客户端
- 仓
- SRC
- C
- CC
- 的java
- 服务器
- ...
# Directories
# CLIENT
CLIENT_BIN_DIR = /client/bin/
CLIENT_SRC_C_DIR = /client/src/c/
CLIENT_SRC_CC_DIR = /client/src/cc/
CLIENT_SRC_JAVA_DIR = /client/src/java/
# SECC
SERVER_BIN_DIR = /server/bin/
SERVER_SRC_C_DIR = /server/src/c/
SERVER_SRC_CC_DIR = /server/src/cc/
SERVER_SRC_JAVA_DIR = /server/src/java/
# Files
# CLIENT
CLIENT_BIN = ${CLIENT_BIN_DIR}client_app
CLIENT_SRC_C = ${wildcard ${CLIENT_SRC_C_DIR}*.c}
CLIENT_SRC_CC = ${wildcard ${CLIENT_SRC_CC_DIR}*.cc}
CLIENT_SRC_JAVA = ${wildcard ${CLIENT_SRC_JAVA_DIR}*.java}
# SERVER
SERVER_BIN = ${SERVER_BIN_DIR}server_app
SERVER_SRC_C = ${wildcard ${SERVER_SRC_C_DIR}*.c}
SERVER_SRC_CC = ${wildcard ${SERVER_SRC_CC_DIR}*.cc}
SERVER_SRC_JAVA = ${wildcard ${SERVER_SRC_JAVA_DIR}*.java}
# Flags
CFLAGS = -g -W -Wall
IFLAGS = -I${INC_DIR}
# Compilers
C = gcc
CC = g++
# Rules
all: ${CLIENT_BIN} ${SERVER_BIN}
${CLIENT_BIN}:
${SERVER_BIN}:
// NEED HELP HERE
既然我有所有的源文件,我应该写下每个文件的以下步骤:
gcc -c -o file.o file.c
g++ -c -o file.o file.cc -I/PATH_TO_C_HEADER
g++ -o APP_NAME C_O_FILES CC_O_FILES
答案 0 :(得分:1)
make built-in rules用于将C和C ++文件编译为目标文件,您可以使用它们而不是使用他们期望的内置标志来编写自己的文件。类似地,make有一个从目标文件构建二进制文件的规则(只要二进制文件与其中一个源文件完全匹配)。
编译C程序
n.o is made automatically from n.c with a recipe of the form ‘$(CC) $(CPPFLAGS) $(CFLAGS) -c’.
编译C ++程序
n.o is made automatically from n.cc, n.cpp, or n.C with a recipe of the form ‘$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c’. We encourage you to use the suffix ‘.cc’ for C++ source files instead of ‘.C’.
链接单个目标文件
n是通过C编译器运行链接器(通常称为ld)从n.o自动生成的。使用的精确配方是'$(CC)$(LDFLAGS)n.o $(LOADLIBES)$(LDLIBS)'。
对于只有一个源文件的简单程序,此规则是正确的。如果有多个目标文件(可能来自各种其他源文件),其中一个名称与可执行文件的名称相匹配,它也会做正确的事情。因此,
x: y.o z.o
当x.c,y.c和z.c全部存在时将执行:
cc -c x.c -o x.o cc -c y.c -o y.o cc -c z.c -o z.o cc x.o y.o z.o -o x rm -f x.o rm -f y.o rm -f z.o
在更复杂的情况下,例如当没有名称来自可执行文件名的目标文件时,您必须编写一个明确的链接配方。
自动制作成'.o'对象文件的各种文件将通过编译器自动链接('$(CC)','$(FC)'或'$(PC)'; C编译器' $(CC)'用于组装'.s'文件)而不使用'-c'选项。这可以通过使用'.o'对象文件作为中间体来完成,但是在一步中进行编译和链接会更快,所以这就是它的完成方式。
因此,只需设置正确的标志(在这些规则中使用)并将正确的.o
文件先决条件添加到二进制目标中,您应该完成。
答案 1 :(得分:0)
# client binary depends on c and c++ .o's
$(CLIENT_BIN): $(CLIENT_SRC_C:.c=.o) $(CLIENT_SRC_CC:.cc=.o)
# server binary depends on c and c++ .o's
$(SERVER_BIN): $(SERVER_SRC_C:.c=.o) $(SERVER_SRC_CC:.cc=.o)
# example header dependency (file.cc depends on file.h and file1.h)
$(CLIENT_SRC_CC_DIR)file.o: $(CLIENT_SRC_CC_DIR)file.h $(CLIENT_SRC_CC_DIR)file1.h
GNU Make有编译C和C ++源文件的隐式规则并生成最终的二进制文件,所以不需要重写它们。
此外,您可能需要RTFM。
答案 2 :(得分:0)
如果你必须使用make,这可以帮助你入门(仅适用于C文件):
# CLIENT
CLIENT_BIN_DIR = client/bin/
CLIENT_SRC_C_DIR = client/src/c/
# CLIENT
CLIENT_BIN = $(CLIENT_BIN_DIR)client_app
CLIENT_SRC_C = $(wildcard $(CLIENT_SRC_C_DIR)*.c)
CLIENT_SRC_C_O = $(CLIENT_SRC_C:.c=.o)
CLIENT_SRC_C_D = $(CLIENT_SRC_C:.c=.d)
# Flags
CFLAGS = -g -W -Wall
IFLAGS = -I$(INC_DIR)
# Compilers
C = gcc
#Create header dependency files (included headers are dependencies too)
%.d: %.c
$(C) $(CFLAGS) -MM -MF $@ -MT $*.o $<
#include will remake the dependency files if they need to be
-include $(CLIENT_SRC_C_D)
#O files will be created via the implicit rule
$(CLIENT_BIN): $(CLIENT_SRC_C_O)
$(C) $(CFLAGS) $(LDFLAGS) $^ -o $(@)
all: $(CLIENT_BIN)
https://www.gnu.org/software/make/manual/make.html非常有帮助。
否则,如果可以,我建议使用tup,这比制作更容易,更灵活,更快速,更先进。