gcc如何指定目标文件的输出目录?

时间:2022-04-25 12:50:48
例如我有这个几个文件:
1.c 2.c 3.c
我想将编译后的目标文件(就是*.o的文件)放到目录output下,改怎么做?

难道只能这样:
gcc -c 1.c -o output/1.o
gcc -c 2.c -o output/2.o
gcc -c 3.c -o output/3.o

不能一条命令就搞定吗?

44 个解决方案

#1


写makefile
再一条make命令不就搞定了。

#2


用makefile,我记得CSDN上有介绍写makefile的文章,你找找

#3


gcc -c 1.c 2.c 3.c -o main.exe

#4


用makefile?
如果我有100个文件,难道要在makefile里写100行?

不能在
gcc -c *.c <...>
后面指定输出目录吗?

#5


没有高手来说说吗?

#6


没有高手来说说吗?

#7


搞不懂你为什么需要在 makefile 里写100行, 1行还不够么 ....

#8


在makefile里写
gcc -c 1.c -o output/1.o
gcc -c 2.c -o output/2.o
gcc -c 3.c -o output/3.o

就可以搞定

#9


makefile里写一个循环就可以了~~

#10


mLee79() 
搞不懂你为什么需要在 makefile 里写100行, 1行还不够么 ....
---------------

一行怎么写?
你说说看,这正是我想知道的。

#11


$ cat makefile
OUTDIR = ./output
CC     = gcc
LINK   = gcc -o
CFLAG  = -c -O2 -o
OBJECTS= $(OUTDIR)/1.o  $(OUTDIR)/2.o  $(OUTDIR)/main.o

all : $(OUTDIR) foo.exe

$(OUTDIR) :
        mkdir $@

foo.exe : $(OBJECTS)
        $(LINK) $@ $(OBJECTS)

$(OUTDIR)/%.o : %.c
        $(CC) $(CFLAG) $@ $<

#12


################
##  GNU Make
################

filename=1 2 3

All:
    for i in $(filename);do gcc -c $$i.c -o output/$$i.o;done

.PHONEY:clean
clean:
    @echo "*****clean*****"
    rm -f *.o

#13


OBJECTS= $(OUTDIR)/1.o  $(OUTDIR)/2.o  $(OUTDIR)/main.o
--------------------------------
filename=1 2 3
--------------------------------
楼上两位大虾给的例子还是要把文件名一一写上啊···

#14


?

#15


makefile

#16


来看看LZ把 .o 生成在当前目录下就怎么不用文件名了 ....

#17


mLee79() 
来看看LZ把 .o 生成在当前目录下就怎么不用文件名了 ....
--------------------------------------------------------
对阿,我就是想这样。
例如
gcc -c *.c <指定输出目录的选项>
能行吗,gcc有这样的参数吗?

#18


mLee79
你在哪里?

#19


Makefile有时候就长这样:
 

#20


TOP_DIR =.
C++ :=g++
CXXFLAGS += -I.  -g   -fpic -Wall   -DDPRINT
LDFLAGS += -g  -L. -llcpp  

%.d:%.cpp
$(C++) $(CXXFLAGS) -M $< \
|sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' >$@

%:%.o
$(C++)  -o $@ $<  $(LDFLAGS)

BINSRCS :=tarray.cpp ta2d.cpp tmt.cpp tll.cpp twrapper.cpp tsas.cpp tsall.cpp\
trpn.cpp tqaa.cpp tqall.cpp tdq.cpp tlaa.cpp tlall.cpp tslaa.cpp\
tslall.cpp tpoly.cpp tcht.cpp tcst.cpp tost.cpp tcw.cpp tgt.cpp tnt.cpp\
tbt.cpp tpti.cpp tbst.cpp tavl.cpp tmwt.cpp tbtree.cpp

LIBSRCS :=  Hash.cpp Object.cpp  NullObject.cpp  Container.cpp NullIterator.cpp \
  Association.cpp StackAsArray.cpp StackAsLinkedList.cpp ToolKits.cpp\
  QueueAsArray.cpp QueueAsLinkedList.cpp Deque.cpp DequeAsArray.cpp\
  DequeAsLinkedList.cpp ListAsArray.cpp ListAsLinkedList.cpp Term.cpp\
  SortedListAsArray.cpp  SortedListAsLinkedList.cpp Polynomial.cpp \
  HashTable.cpp ChainedHashTable.cpp ChainedScatterTable.cpp\
  OpenScatterTable.cpp Tree.cpp  GeneralTree.cpp NaryTree.cpp BinaryTree.cpp\
  BST.cpp AVLTree.cpp MWayTree.cpp BTree.cpp
  
DEPENDS :=$(BINSRCS:%.cpp=%.d) $(LIBSRCS:%.cpp=%.d)
OBJS :=$(BINSRCS:%.cpp=%.o)
LIBOBJS :=$(LIBSRCS:%.cpp=%.o)
BINS :=$(BINSRCS:%.cpp=%)

ifeq ($(lib),so)
LIBFILES = liblcpp.so
libcmd=$(C++)  -shared -o $@ $^ ; rm -f liblcpp.a
else
LIBFILES = liblcpp.a
libcmd=$(AR) rsv  $@ $^ ; rm -f liblcpp.so
endif



.PHONY:all clean
all:$(BINS) $(LIBFILES)

$(BINS):$(LIBFILES)

$(LIBFILES):$(LIBOBJS)
$(libcmd)
clean:
rm -f $(OBJS) $(BINS) $(LIBOBJS) $(LIBFILES) core.[0-9]*  


ifneq ($(MAKECMDGOALS),clean)
-include $(DEPENDS)
endif

#21


难道只能将文件名都打上吗?
不能用"*.c"这类的语法?

#22


可以用,记得有一个gmake 的函数,能获得指定目录下的文件名,
但我记不得是什么名字了,
可是,这样一来,
想区分输出成.o的文件或输出成可执行文件文件名就得多作些工作了



#23


还有没有高手来指导一下啊?

#24


.c.o:
        gcc -c $< -o output/$@

就可以了呀!

对于每个.c都执行 gcc 1.c -o output/1.o

#25


duchuanying() 
.c.o:
        gcc -c $< -o output/$@

就可以了呀!

对于每个.c都执行 gcc 1.c -o output/1.o

----------------------------

即使这样写,好像也要先把文件名一个个打上吧···

例如:
OBJECTS=1.o 2.o 3.o
.SUFFIXES: .o .c
.c.o:
        gcc -c $< -o $(OUTDIR)/$@
all: $(OBJECTS)
1.o : 1.c
2.o : 2.c
3.o : 3.c

#26


SOURCES = $(wildcard *.c)

OBJS = $(patsubst %.c,%.o,$(SOURCES))

#27


lk_517(风雷,http://likunarmstrong.googlepages.com/home) ( ) 
SOURCES = $(wildcard *.c)

OBJS = $(patsubst %.c,%.o,$(SOURCES))
---------------------------------------------------------
这样怎么设定编译的语句?
难道这样:
gcc -c $(SOURCES) -o $(OBJS)
好像不通啊?

#28


?

#29


写MAKEFILE文件

#30


该回复被版主删除

#31


to leehq


用makefile阿

#32


lk_517(风雷,http://likunarmstrong.googlepages.com/home) 
------------------------------------------------------------
你没看贴?

#33


当然看了,晕

在makefile里面写

SOURCES = $(wildcard *.c)

OBJS = $(patsubst %.c,%.o,$(SOURCES))

然后就把.c和.o对应起来了阿,你就不用管具体文件名了阿

#34


lk_517(风雷,http://likunarmstrong.googlepages.com/home) 

当然看了,晕

在makefile里面写

SOURCES = $(wildcard *.c)

OBJS = $(patsubst %.c,%.o,$(SOURCES))

然后就把.c和.o对应起来了阿,你就不用管具体文件名了阿
------------------------------------------------------------
这样写我也会,问题是你如何编译?
难道这样:
gcc $(SOURCES) -o $(OBJS)

好像不行啊????????

#35


多看点有关文档,呵呵

#36


还有没有高手来指点一下?

#37


leehq:

为什么不行?错误信息是什么

#38


一个适合中小规模的makefile模版,基本上自己按照实际情况指定一下 源文件,目标文件,头文件目录,以及源文件后缀就行了。

# ---------------------------------------------------------------------------
#                   commands
# ---------------------------------------------------------------------------
CC := gcc
LINK := gcc
RM := rm -rf
MV := mv
TAR := tar
MKDIR := mkdir


# ---------------------------------------------------------------------------
#                   settings
# ---------------------------------------------------------------------------
SRC_SUFFIX := .c
OBJ_SUFFIX := .o
LIB_SUFFIX := .a
BIN_SUFFIX := .exe
DLL_SUFFIX := .so

INC_PREFIX := -I
LIB_PREFIX := -L

OPT_C := -c
OPT_OUT := -o 
OPT_LINKOUT := -o 

CFLAGS := $(OPT_C)
LIBFLAGS := -Debug


# ---------------------------------------------------------------------------
#                   directories
# ---------------------------------------------------------------------------
SRC_DIR := ./src
OBJ_DIR := ./obj
INC_DIR := ./inc
LIB_DIR := ./lib /usr/local/lib /lib /usr/lib


# ---------------------------------------------------------------------------
#                   common settings
# ---------------------------------------------------------------------------
SRCS := $(wildcard $(SRC_DIR)/*$(SRC_SUFFIX))
OBJS  := $(patsubst $(SRC_DIR)/%$(SRC_SUFFIX),$(OBJ_DIR)/%$(OBJ_SUFFIX),$(SRCS)) 
INCS := $(addprefix $(INC_PREFIX), $(INC_DIR))
LIBS := $(addprefix $(LIB_PREFIX), $(LIB_DIR)) $(LIBFLAGS)
TEMPFILES  := core core.* *$(OBJ_SUFFIX) temp.* *.out typescript*


# ---------------------------------------------------------------------------
#                   make rule
# ---------------------------------------------------------------------------
TARGET := loader

.PHONY: all clean

all: $(TARGET)

clean:
$(RM) $(TARGET)$(BIN_SUFFIX) $(OBJS)

$(TARGET):$(OBJS)
$(LINK) $(OPT_LINKOUT)$(TARGET)$(BIN_SUFFIX) $(LIBS) $(OBJS)

$(OBJS):$(OBJ_DIR)/%$(OBJ_SUFFIX):$(SRC_DIR)/%$(SRC_SUFFIX)
$(CC) $(CFLAGS) $(INCS) $(OPT_OUT)$@ $<

#39


该回复被版主删除

#40


lk_517(风雷,http://likunarmstrong.googlepages.com/home) 
 
   leehq:

为什么不行?错误信息是什么
-----------------------------------------------------
下面这样的语法能够运行? 
gcc $(SOURCES) -o $(OBJS)

你自己看看:
gcc 1.c 2.c -o 1.o 2.o
这样还不错?

#41


chb79(哈哈镜)

你真是神了!
多谢多谢!

#42


OBJS = $(patsubst %.c,%.o,$(SOURCES))

然后就把.c和.o对应起来了阿,你就不用管具体文件名了阿

然后gcc $(AppName) -o $(OBJS)

晕,这个自己试一下就行了阿

怎么会出现gcc $(SOURCES) -o $(OBJS)这种写法?

虽然现在有万能文件,不过建议你还是看看makefile写法

#43


leehq(没有读过高中的人) ( ) 信誉:99    Blog  2007-01-10 14:06:00  得分: 0  
 
下面这样的语法能够运行? 
gcc $(SOURCES) -o $(OBJS)

你自己看看:
gcc 1.c 2.c -o 1.o 2.o
这样还不错?
-----------------------------------------------------

To leehq(没有读过高中的人):
定义了$(SOURCES), $(OBJS)之后,命令行不是像你说的那样
gcc $(SOURCES) -o $(OBJS)
而应该是:
$(OBJS): output/%.o:%.c
gcc -c $<  -o $@

至于为什么这样,这就是makefile的自动变量: %,@,< 的神奇之处啦:)

你可以google一下makefile,自己在研究研究。

下面这个是一个完整的makefile,功能简单,就是将obj放到 output下,你好好研究研究

SRCS := $(wildcard *.c)
OBJS  := $(patsubst %.c,output/%.o,$(SRCS)) 

TARGET := hello

all: $(TARGET)

clean:
rm -f $(TARGET) $(OBJS)

$(TARGET):$(OBJS)
gcc -o $(TARGET) $(OBJS)

$(OBJS):output/%.o:%.c
gcc -c $<  -o $@



 

#44


我还不知道makefile里的目标名可以带两个冒号。

多谢
chb79(哈哈镜) 
!!!!!!!!!!!!!!!1

#1


写makefile
再一条make命令不就搞定了。

#2


用makefile,我记得CSDN上有介绍写makefile的文章,你找找

#3


gcc -c 1.c 2.c 3.c -o main.exe

#4


用makefile?
如果我有100个文件,难道要在makefile里写100行?

不能在
gcc -c *.c <...>
后面指定输出目录吗?

#5


没有高手来说说吗?

#6


没有高手来说说吗?

#7


搞不懂你为什么需要在 makefile 里写100行, 1行还不够么 ....

#8


在makefile里写
gcc -c 1.c -o output/1.o
gcc -c 2.c -o output/2.o
gcc -c 3.c -o output/3.o

就可以搞定

#9


makefile里写一个循环就可以了~~

#10


mLee79() 
搞不懂你为什么需要在 makefile 里写100行, 1行还不够么 ....
---------------

一行怎么写?
你说说看,这正是我想知道的。

#11


$ cat makefile
OUTDIR = ./output
CC     = gcc
LINK   = gcc -o
CFLAG  = -c -O2 -o
OBJECTS= $(OUTDIR)/1.o  $(OUTDIR)/2.o  $(OUTDIR)/main.o

all : $(OUTDIR) foo.exe

$(OUTDIR) :
        mkdir $@

foo.exe : $(OBJECTS)
        $(LINK) $@ $(OBJECTS)

$(OUTDIR)/%.o : %.c
        $(CC) $(CFLAG) $@ $<

#12


################
##  GNU Make
################

filename=1 2 3

All:
    for i in $(filename);do gcc -c $$i.c -o output/$$i.o;done

.PHONEY:clean
clean:
    @echo "*****clean*****"
    rm -f *.o

#13


OBJECTS= $(OUTDIR)/1.o  $(OUTDIR)/2.o  $(OUTDIR)/main.o
--------------------------------
filename=1 2 3
--------------------------------
楼上两位大虾给的例子还是要把文件名一一写上啊···

#14


?

#15


makefile

#16


来看看LZ把 .o 生成在当前目录下就怎么不用文件名了 ....

#17


mLee79() 
来看看LZ把 .o 生成在当前目录下就怎么不用文件名了 ....
--------------------------------------------------------
对阿,我就是想这样。
例如
gcc -c *.c <指定输出目录的选项>
能行吗,gcc有这样的参数吗?

#18


mLee79
你在哪里?

#19


Makefile有时候就长这样:
 

#20


TOP_DIR =.
C++ :=g++
CXXFLAGS += -I.  -g   -fpic -Wall   -DDPRINT
LDFLAGS += -g  -L. -llcpp  

%.d:%.cpp
$(C++) $(CXXFLAGS) -M $< \
|sed 's/\($*\)\.o[ :]*/\1.o $@ : /g' >$@

%:%.o
$(C++)  -o $@ $<  $(LDFLAGS)

BINSRCS :=tarray.cpp ta2d.cpp tmt.cpp tll.cpp twrapper.cpp tsas.cpp tsall.cpp\
trpn.cpp tqaa.cpp tqall.cpp tdq.cpp tlaa.cpp tlall.cpp tslaa.cpp\
tslall.cpp tpoly.cpp tcht.cpp tcst.cpp tost.cpp tcw.cpp tgt.cpp tnt.cpp\
tbt.cpp tpti.cpp tbst.cpp tavl.cpp tmwt.cpp tbtree.cpp

LIBSRCS :=  Hash.cpp Object.cpp  NullObject.cpp  Container.cpp NullIterator.cpp \
  Association.cpp StackAsArray.cpp StackAsLinkedList.cpp ToolKits.cpp\
  QueueAsArray.cpp QueueAsLinkedList.cpp Deque.cpp DequeAsArray.cpp\
  DequeAsLinkedList.cpp ListAsArray.cpp ListAsLinkedList.cpp Term.cpp\
  SortedListAsArray.cpp  SortedListAsLinkedList.cpp Polynomial.cpp \
  HashTable.cpp ChainedHashTable.cpp ChainedScatterTable.cpp\
  OpenScatterTable.cpp Tree.cpp  GeneralTree.cpp NaryTree.cpp BinaryTree.cpp\
  BST.cpp AVLTree.cpp MWayTree.cpp BTree.cpp
  
DEPENDS :=$(BINSRCS:%.cpp=%.d) $(LIBSRCS:%.cpp=%.d)
OBJS :=$(BINSRCS:%.cpp=%.o)
LIBOBJS :=$(LIBSRCS:%.cpp=%.o)
BINS :=$(BINSRCS:%.cpp=%)

ifeq ($(lib),so)
LIBFILES = liblcpp.so
libcmd=$(C++)  -shared -o $@ $^ ; rm -f liblcpp.a
else
LIBFILES = liblcpp.a
libcmd=$(AR) rsv  $@ $^ ; rm -f liblcpp.so
endif



.PHONY:all clean
all:$(BINS) $(LIBFILES)

$(BINS):$(LIBFILES)

$(LIBFILES):$(LIBOBJS)
$(libcmd)
clean:
rm -f $(OBJS) $(BINS) $(LIBOBJS) $(LIBFILES) core.[0-9]*  


ifneq ($(MAKECMDGOALS),clean)
-include $(DEPENDS)
endif

#21


难道只能将文件名都打上吗?
不能用"*.c"这类的语法?

#22


可以用,记得有一个gmake 的函数,能获得指定目录下的文件名,
但我记不得是什么名字了,
可是,这样一来,
想区分输出成.o的文件或输出成可执行文件文件名就得多作些工作了



#23


还有没有高手来指导一下啊?

#24


.c.o:
        gcc -c $< -o output/$@

就可以了呀!

对于每个.c都执行 gcc 1.c -o output/1.o

#25


duchuanying() 
.c.o:
        gcc -c $< -o output/$@

就可以了呀!

对于每个.c都执行 gcc 1.c -o output/1.o

----------------------------

即使这样写,好像也要先把文件名一个个打上吧···

例如:
OBJECTS=1.o 2.o 3.o
.SUFFIXES: .o .c
.c.o:
        gcc -c $< -o $(OUTDIR)/$@
all: $(OBJECTS)
1.o : 1.c
2.o : 2.c
3.o : 3.c

#26


SOURCES = $(wildcard *.c)

OBJS = $(patsubst %.c,%.o,$(SOURCES))

#27


lk_517(风雷,http://likunarmstrong.googlepages.com/home) ( ) 
SOURCES = $(wildcard *.c)

OBJS = $(patsubst %.c,%.o,$(SOURCES))
---------------------------------------------------------
这样怎么设定编译的语句?
难道这样:
gcc -c $(SOURCES) -o $(OBJS)
好像不通啊?

#28


?

#29


写MAKEFILE文件

#30


该回复被版主删除

#31


to leehq


用makefile阿

#32


lk_517(风雷,http://likunarmstrong.googlepages.com/home) 
------------------------------------------------------------
你没看贴?

#33


当然看了,晕

在makefile里面写

SOURCES = $(wildcard *.c)

OBJS = $(patsubst %.c,%.o,$(SOURCES))

然后就把.c和.o对应起来了阿,你就不用管具体文件名了阿

#34


lk_517(风雷,http://likunarmstrong.googlepages.com/home) 

当然看了,晕

在makefile里面写

SOURCES = $(wildcard *.c)

OBJS = $(patsubst %.c,%.o,$(SOURCES))

然后就把.c和.o对应起来了阿,你就不用管具体文件名了阿
------------------------------------------------------------
这样写我也会,问题是你如何编译?
难道这样:
gcc $(SOURCES) -o $(OBJS)

好像不行啊????????

#35


多看点有关文档,呵呵

#36


还有没有高手来指点一下?

#37


leehq:

为什么不行?错误信息是什么

#38


一个适合中小规模的makefile模版,基本上自己按照实际情况指定一下 源文件,目标文件,头文件目录,以及源文件后缀就行了。

# ---------------------------------------------------------------------------
#                   commands
# ---------------------------------------------------------------------------
CC := gcc
LINK := gcc
RM := rm -rf
MV := mv
TAR := tar
MKDIR := mkdir


# ---------------------------------------------------------------------------
#                   settings
# ---------------------------------------------------------------------------
SRC_SUFFIX := .c
OBJ_SUFFIX := .o
LIB_SUFFIX := .a
BIN_SUFFIX := .exe
DLL_SUFFIX := .so

INC_PREFIX := -I
LIB_PREFIX := -L

OPT_C := -c
OPT_OUT := -o 
OPT_LINKOUT := -o 

CFLAGS := $(OPT_C)
LIBFLAGS := -Debug


# ---------------------------------------------------------------------------
#                   directories
# ---------------------------------------------------------------------------
SRC_DIR := ./src
OBJ_DIR := ./obj
INC_DIR := ./inc
LIB_DIR := ./lib /usr/local/lib /lib /usr/lib


# ---------------------------------------------------------------------------
#                   common settings
# ---------------------------------------------------------------------------
SRCS := $(wildcard $(SRC_DIR)/*$(SRC_SUFFIX))
OBJS  := $(patsubst $(SRC_DIR)/%$(SRC_SUFFIX),$(OBJ_DIR)/%$(OBJ_SUFFIX),$(SRCS)) 
INCS := $(addprefix $(INC_PREFIX), $(INC_DIR))
LIBS := $(addprefix $(LIB_PREFIX), $(LIB_DIR)) $(LIBFLAGS)
TEMPFILES  := core core.* *$(OBJ_SUFFIX) temp.* *.out typescript*


# ---------------------------------------------------------------------------
#                   make rule
# ---------------------------------------------------------------------------
TARGET := loader

.PHONY: all clean

all: $(TARGET)

clean:
$(RM) $(TARGET)$(BIN_SUFFIX) $(OBJS)

$(TARGET):$(OBJS)
$(LINK) $(OPT_LINKOUT)$(TARGET)$(BIN_SUFFIX) $(LIBS) $(OBJS)

$(OBJS):$(OBJ_DIR)/%$(OBJ_SUFFIX):$(SRC_DIR)/%$(SRC_SUFFIX)
$(CC) $(CFLAGS) $(INCS) $(OPT_OUT)$@ $<

#39


该回复被版主删除

#40


lk_517(风雷,http://likunarmstrong.googlepages.com/home) 
 
   leehq:

为什么不行?错误信息是什么
-----------------------------------------------------
下面这样的语法能够运行? 
gcc $(SOURCES) -o $(OBJS)

你自己看看:
gcc 1.c 2.c -o 1.o 2.o
这样还不错?

#41


chb79(哈哈镜)

你真是神了!
多谢多谢!

#42


OBJS = $(patsubst %.c,%.o,$(SOURCES))

然后就把.c和.o对应起来了阿,你就不用管具体文件名了阿

然后gcc $(AppName) -o $(OBJS)

晕,这个自己试一下就行了阿

怎么会出现gcc $(SOURCES) -o $(OBJS)这种写法?

虽然现在有万能文件,不过建议你还是看看makefile写法

#43


leehq(没有读过高中的人) ( ) 信誉:99    Blog  2007-01-10 14:06:00  得分: 0  
 
下面这样的语法能够运行? 
gcc $(SOURCES) -o $(OBJS)

你自己看看:
gcc 1.c 2.c -o 1.o 2.o
这样还不错?
-----------------------------------------------------

To leehq(没有读过高中的人):
定义了$(SOURCES), $(OBJS)之后,命令行不是像你说的那样
gcc $(SOURCES) -o $(OBJS)
而应该是:
$(OBJS): output/%.o:%.c
gcc -c $<  -o $@

至于为什么这样,这就是makefile的自动变量: %,@,< 的神奇之处啦:)

你可以google一下makefile,自己在研究研究。

下面这个是一个完整的makefile,功能简单,就是将obj放到 output下,你好好研究研究

SRCS := $(wildcard *.c)
OBJS  := $(patsubst %.c,output/%.o,$(SRCS)) 

TARGET := hello

all: $(TARGET)

clean:
rm -f $(TARGET) $(OBJS)

$(TARGET):$(OBJS)
gcc -o $(TARGET) $(OBJS)

$(OBJS):output/%.o:%.c
gcc -c $<  -o $@



 

#44


我还不知道makefile里的目标名可以带两个冒号。

多谢
chb79(哈哈镜) 
!!!!!!!!!!!!!!!1