makefile 如何指定.o的输出路径

j_now 2011-04-17 08:16:26
利用make的隐含规则,能够编译,但是.o 会输出到当前目录中。。。 感觉总是不爽,不知道哪位有好办法,让.o输出到build目录中,makefile如下:


CUR_DIR = $(shell pwd)

SRC = $(CUR_DIR)/src
INCLUDES = $(CUR_DIR)/include

CFLAGS = -I$(INCLUDES) -Wall -g -std=c99
VPATH = $(SRC)
#%.o : %.c
# $(CC) -c $(CFLAGS) $< -o $(OBJ_DIR)/$@

all: main

main: shrink_space.o main.o

main.o: shrink_space.o

clean:
$(RM) *.o
$(RM) main



参考了
http://www.cppblog.com/converse/archive/2009/02/23/74716.html
http://makepp.sourceforge.net/1.18/t_dirs.html
这里介绍的不是我需要的,如果使用 gcc的-o,makefile就太麻烦了,工程一大添加起来很费劲,没有我的简单。。。
先提前谢谢了!
...全文
6026 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
j_now 2011-07-02
  • 打赏
  • 举报
回复
It looks good. I will try later. thank you very much!!!!
j_now 2011-07-02
  • 打赏
  • 举报
回复
谢谢 yfkiss 和 mLee79, it works!!!
看帖的同学别忘记把blank题换成tab,稍微解释下,供以后才考

目录结构如下
.
|-- Makefile
|-- cp_constructor_failed
| `-- cp_constructor_failed.cpp
|-- deps
| `-- cp_constructor_failed.d
|-- include
| `-- cp_constructor_failed.h
|-- main
| |-- 112
| |-- 112.o
| `-- main_failed.cpp
|-- o
`-- obj
`-- cp_constructor_failed.o

wildcard 是扩展通配符。$(wildcard ./main/*.cpp) 扩展结果是 ./main/main_failed.cpp

notdir:用于去除路径。$(notdir $(wildcard ./main/*.cpp)) 相当于 $(notdir ./main/main_failed.cpp),所以扩展结果是main_failed.cpp

patsubst用来替换通配符,例如:$(patsubst %.cpp,%.o,$(notdir $(wildcard ./main/*.cpp)))相当于$(patsubst %.cpp,%.o,$(notdir ./main/main_failed.cpp)),也就相当于$(patsubst %.cpp,%.o,main_failed.cpp),那么计算记过就是main_failed.o
估计patsubst是path substitution的缩写,linux中的所写真让人无语

gcc的-MM不会让gcc进行编译,而是输出make的规则,说起来不太容易,看以下两断代码应该能明白,还不行就man gcc

echo "#include <stdio.h>" > tmp.c; cc -M tmp.c
echo "#include <stdio.h>" > tmp.c; cc -MM tmp.c


sed -e 1's,^,$(OBJ_DIR)/,' 我不是很懂,不知道这里面的1是什么意思,不过可以理解成sed -e 's/^/$(OBJ_DIR)\//',哪位能给个解释最好了:)

sinclude用来指定头文件的查找路径,也就是-include,include -include 是什么,参考http://sunsite.ualberta.ca/Documentation/Gnu/make-3.79/html_chapter/make_3.html


http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-zh_CN_html/index.html#content


mLee79 2011-07-02
  • 打赏
  • 举报
回复
这样子也可以...

TARGET = foo

my-dir = $(patsubst %/,%,$(dir $(lastword $(MAKEFILE_LIST))))
obj-path = $(addprefix $(OUTPUT_PATH)/,$(addsuffix .o,$(basename $(notdir $1))))
dep-path = $(addprefix $(OUTPUT_PATH)/,$(addsuffix .d,$(basename $(notdir $1))))

CFLAGS := -I$(INCLUDES)
LOCAL_PATH := $(my-dir)
OUTPUT_PATH := $(LOCAL_PATH)/out
LOCL_CFLAGS := -Wall -g -std=c99

LOCAL_SOURCE := $(wildcard $(LOCAL_PATH)/src/*.c $(LOCAL_PATH)/src/*/*.c $(LOCAL_PATH)/src/*/*/*.c)
LOCAL_OBJECTS := $(call obj-path,$(LOCAL_SOURCE))

.PHONY : all clean
all:$(TARGET)

include $(wildcard $(OUTPUT_PATH)/*.d)

define make-object
$2 : $1
gcc -c $(CFALGS) $(LOCL_CFLAGS) -MMD -MT $$@ -MF $3 -o $$@ $$<
endef

$(foreach file,$(LOCAL_SOURCE),\
$(eval $(call make-object,$(file),$(call obj-path,$(file)),$(call dep-path,$(file)))))

$(TARGET):$(LOCAL_OBJECTS)
gcc -o $@ $(LOCAL_OBJECTS)

clean:
rm -rf $(OUTPUT_PATH)/* $(TARGET)


$ find ; make ; touch src/*.h; make
.
./Makefile
./out
./src
./src/inc.h
./src/lib.c
./src/main.c
gcc -c -Wall -g -std=c99 -MMD -MT out/lib.o -MF ./out/lib.d -o out/lib.o src/lib.c
gcc -c -Wall -g -std=c99 -MMD -MT out/main.o -MF ./out/main.d -o out/main.o src/main.c
gcc -o foo ./out/lib.o ./out/main.o
gcc -c -Wall -g -std=c99 -MMD -MT out/lib.o -MF ./out/lib.d -o out/lib.o src/lib.c
gcc -c -Wall -g -std=c99 -MMD -MT out/main.o -MF ./out/main.d -o out/main.o src/main.c
gcc -o foo ./out/lib.o ./out/main.o

yfk 2011-07-01
  • 打赏
  • 举报
回复
通用makefile~

######################################################################
# makefile 模版
#
######################################################################

###################项目路径和程序名称#################################
DIR=$(shell pwd)
BIN_DIR=$(DIR)/bin
LIB_DIR=$(DIR)/lib
SRC_DIR=$(DIR)/src
INCLUDE_DIR=$(DIR)/include
OBJ_DIR=$(DIR)/obj
DEPS_DIR=$(DIR)/deps
#PROGRAM=$(BIN_DIR)/test
PROGRAM=$(BIN_DIR)/test

###################OBJ文件及路径############################################
EXTENSION=cpp
OBJS=$(patsubst $(SRC_DIR)/%.$(EXTENSION), $(OBJ_DIR)/%.o,$(wildcard $(SRC_DIR)/*.$(EXTENSION)))
DEPS=$(patsubst $(OBJ_DIR)/%.o, $(DEPS_DIR)/%.d, $(OBJS))

###################include头文件路径##################################
INCLUDE=\
-I$(INCLUDE_DIR)

###################lib文件及路径######################################

###################编译选项及编译器###################################
CC=g++
CFLAGS=-Wall -W -g
LDFLAGS=

###################编译目标###########################################
.PHONY: all clean rebuild

all:$(OBJS)
@echo $(DEPS_DIR)
$(CC) -o $(PROGRAM) $(OBJS) $(LDFLAGS)


$(DEPS_DIR)/%.d: $(SRC_DIR)/%.$(EXTENSION)
$(CC) -MM $(INCLUDE) $(CFLAGS) $< | sed -e 1's,^,$(OBJ_DIR)/,' > $@

sinclude $(DEPS)

$(OBJ_DIR)/%.o:$(SRC_DIR)/%.$(EXTENSION)
$(CC) $< -o $@ -c $(CFLAGS) $(INCLUDE)

rebuild: clean all

clean:
rm -rf $(OBJS) $(PROGRAM)


j_now 2011-06-30
  • 打赏
  • 举报
回复
up it
j_now 2011-05-01
  • 打赏
  • 举报
回复

###
#########
############ ####
############# #######
#### #### ######
### ### ##
## ## ##
## ### ###
### ### ####
#######################
######################
#####################
###
#

## ##
#########################
#########################
#########################
#########################
## ##
##
###
####
####
#########################
########################
#######################
#####################
##
### ##
##### ####
##### #######
##### ##########
##### ##############
##### ############### ##
###### ##############
##############
########
######
######
###### ##
######
###
##
















## ##
######################### #####
######################### ######
######################### ######
######################### #####
##
##########
#################
####################
######################
##### #####
### ###
## ###
# ##
## ###
### ## #
#########################################
#########################################
#########################################
#########################################
##
########
###############
##################
#####################
#### ## ####
## ## ##
## ## ##
## ## ##
## ## ###
# ## ###
## ## ######
### ###########
## ##########
########

###
#########
############ ####
############# #######
#### #### ######
### ### ##
## ## ##
## ### ###
### ### ####
#######################
######################
#####################
###
#

###### ###
###### ########
#### ###########
### #############
## ###### ##
## ###### ##
## ###### ##
## ###### ###
## ###### ###
## ####### ###
############# ######
########### ######
#######

####
#######
#########
### ####
###
##### ####### #
###### ########### #
##### ############ #
### ### #### ##
##### ####
###################
#################
#############
##########

















##
##
############################
##############################
##############################
##### ##
#### ##
##
###
#
## #
#########################################
#########################################
#########################################
#########################################
## ##
##
###
####
####
#########################
########################
#######################
#####################
##
###
#########
############ ####
############# #######
#### #### ######
### ### ##
## ## ##
## ### ###
### ### ####
#######################
######################
#####################
###
#

## ##
#########################
#########################
#########################
#########################
## ##
##
###
####
####
#########################
########################
#######################
#####################
##
## #
#########################################
#########################################
#########################################
#########################################
## ######
#########
#############
########## ### ##
## ########## #####
########## ###
####### ##
######
###
##
###### ###
###### ########
#### ###########
### #############
## ###### ##
## ###### ##
## ###### ##
## ###### ###
## ###### ###
## ####### ###
############# ######
########### ######
#######
j_now 2011-05-01
  • 打赏
  • 举报
回复

# # # # #
# # ## # # #
# # # # # # #
# # # # # #
####### # # # #
# # # ## #
# # # # #


### ###### ####### # ##### #####
# # # # # # # # # #
# # # # # # # #
# # # ##### # # ##### ###
# # # # ####### # #
# # # # # # # #
### ###### ####### # # ##### #


####### # # # # # # # #####
# # # # # ## # # # # #
# # # # # # # # # # #
# ####### # # # # # ### #####
# # # ####### # # # # # #
# # # # # # ## # # # #
# # # # # # # # # #####
j_now 2011-05-01
  • 打赏
  • 举报
回复
# # # # #
# # ## # # #
# # # # # # #
# # # # # #
####### # # # #
# # # ## #
# # # # #


### ###### ####### # ##### #####
# # # # # # # # # #
# # # # # # # #
# # # ##### # # ##### ###
# # # # ####### # #
# # # # # # # #
### ###### ####### # # ##### #


####### # # # # # # # #####
# # # # # ## # # # # #
# # # # # # # # # # #
# ####### # # # # # ### #####
# # # ####### # # # # # #
# # # # # # ## # # # #
# # # # # # # # # #####
yyysss520 2011-04-28
  • 打赏
  • 举报
回复
*.o的路径没有找到,加个vpath %.o $(BUILD)
xjmlj2010 2011-04-21
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 luciferisnotsatan 的回复:]
http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-zh_CN_html/make-08.html

SRC为一堆源文件文件

OBJ := $(SRC:%.c=%.o)
OBJ := $(OBJ:%.cpp=%.o)
OBJ := $(OBJ:%.s=%.o)
SHARE_OBJ := $(notdir $(OBJ))
S……
[/Quote]
k
j_now 2011-04-21
  • 打赏
  • 举报
回复
感谢luciferisnotsatan和yyysss520的回复

我修改了一下makefile,如下,而后 make -f mk.fromcsdn :

CUR_DIR = $(shell pwd)

SRC = $(CUR_DIR)/src
INCLUDES = $(CUR_DIR)/include
BUILD = $(CUR_DIR)/build

CFLAGS = -I$(INCLUDES) -Wall -g -std=c99
VPATH = $(SRC)

all: main

main: shrink_space.o main.o
$(CC) $(CFLAGS) $(addprefix $(BUILD)/, *) -o $@

main.o: shrink_space.o

%.o : %.c
$(CC) -c $(CFLAGS) $< -o $(BUILD)/$@

clean:
$(RM) $(BUILD)/*.o
$(RM) main


没问题,确实能编译,很感谢,但是还有一个问题,再次make -f mk.fromcsdn还是会对整个工程进行编译。。。 但是刚开始自己些的mk.mine如下,如果连续make两次,第二次不会编译整个工程,而是提示:
make: Nothing to be done for `all'. 怎么能让.o输出到build中,还能只编译修改过了文件呢?

CUR_DIR = $(shell pwd)

SRC = $(CUR_DIR)/src
INCLUDES = $(CUR_DIR)/include

CFLAGS = -I$(INCLUDES) -Wall -g -std=c99
VPATH = $(SRC)


all: main

main: shrink_space.o main.o

main.o: shrink_space.o

clean:
$(RM) *.o
$(RM) main



谢谢
luciferisnotsatan 2011-04-21
  • 打赏
  • 举报
回复

CC = gcc
CFLAGS = -o

OBJECTS = SMBIOS.o \
Biosinfo.o



all: biosinfo


biosinfo: $(OBJECTS)
$(CC) $(addprefix ./libs/, $^) -o biosinfo // 使用./libs下的*.o

clean:
rm -f *.o
rm -f biosinfo
%.o: %.c
$(CC) -c -O3 $< -o ./libs/$(notdir $@) // 把 *.o 放到./libs下


addprefix 就是加前缀。
notdir 就是去掉目录,取文件名。

把文件调整到相应你想要的位置就行了。
yyysss520 2011-04-21
  • 打赏
  • 举报
回复
目录肯定要自己加, vpath 只是设置搜索路径 如: vpath %.o ./build
addprefix 在每个变量前添加前缀

Dist=build
Obj=main.o shrink_space.o

vpath %.cpp ./src
vpath %.o ./build

all:main

main:$(Obj)
$(CC) $(LDFLAGS) $(addprefix $(Dist)/, $(Obj)) -o $@

%.o : %.c
$(CC) -c $(CFLAGS) $< -o $(Dist)/$@
luciferisnotsatan 2011-04-17
  • 打赏
  • 举报
回复
http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-zh_CN_html/make-08.html

SRC为一堆源文件文件

OBJ := $(SRC:%.c=%.o)
OBJ := $(OBJ:%.cpp=%.o)
OBJ := $(OBJ:%.s=%.o)
SHARE_OBJ := $(notdir $(OBJ))
SHARE_OBJ := $(addprefix .libs/,$(SHARE_OBJ))
j_now 2011-04-17
  • 打赏
  • 举报
回复
mv ... 谢谢

有没有更好的办法?

比如像VPATH这种内置变量。 通过设置这种变量,就能让 make 把.o直接输出到build目录里面去,而后在编main时,在自动从build目录里面寻找.o,谢谢
bargio_susie 2011-04-17
  • 打赏
  • 举报
回复
其实也可以直接嵌套shell命令把.o文件搬到你想要的目录下去的
j_now 2011-04-17
  • 打赏
  • 举报
回复
谢谢回复哈:)

可以编译通过的。 就是.o 都输出到 $PWD了:
include main main.o makefile shrink_space.o src

我输出成
build include main makefile src
而后 ls build:
main.o shrink_space.o

这样就方便了 谢谢哈
Arnold9009 2011-04-17
  • 打赏
  • 举报
回复

CUR_DIR = $(shell pwd)

SRC = $(CUR_DIR)/src
INCLUDES = $(CUR_DIR)/include
OBJDIR = $(CUR_DIR)/obj

CFLAGS = -I$(INCLUDES) -Wall -g -std=c99
VPATH = $(SRC)
#%.o : %.c
# $(CC) -c $(CFLAGS) $< -o $(OBJ_DIR)/$@

all: main

main: $(OBJDIR)/shrink_space.o $(OBJDIR)/main.o

$(OBJDIR)/main.o: $(OBJDIR)/shrink_space.o

clean:
$(RM) $(OBJDIR)/*.o
$(RM) main


印象里这样应该可以
j_now 2011-04-17
  • 打赏
  • 举报
回复
谢谢“独孤” 看明白mv的使用方法了

不知道 luciferisnotsatan 是什么意思,再等等看哈

[Quote=引用 5 楼 luciferisnotsatan 的回复:]

http://www.linuxsir.org/main/doc/gnumake/GNUmake_v3.80-zh_CN_html/make-08.html

SRC为一堆源文件文件

OBJ := $(SRC:%.c=%.o)
OBJ := $(OBJ:%.cpp=%.o)
OBJ := $(OBJ:%.s=%.o)
SHARE_OBJ := $(notdir $(OBJ))
……
[/Quote]
太乙 2011-04-17
  • 打赏
  • 举报
回复
CUR_DIR        =        $(shell pwd)

SRC = $(CUR_DIR)/src
INCLUDES = $(CUR_DIR)/include
OBJDIR = $(CUR_DIR)/obj

CFLAGS = -I$(INCLUDES) -Wall -g -std=c99
VPATH = $(SRC)
#%.o : %.c
# $(CC) -c $(CFLAGS) $< -o $(OBJ_DIR)/$@

all: main mymv//引用上面的例子,这里加rm就好了,或者mv

main: $(OBJDIR)/shrink_space.o $(OBJDIR)/main.o

$(OBJDIR)/main.o: $(OBJDIR)/shrink_space.o

clean:
$(RM) $(OBJDIR)/*.o
$(RM) main
mymv:
$(MV) *.o $(OBJDIR)/*.o
加载更多回复(2)

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧