关键词:
【中文标题】.cpp 和 .c 文件的替换参考 [关闭]【英文标题】:Substitution reference with .cpp and .c files [closed] 【发布时间】:2016-06-29 02:35:25 【问题描述】:我知道有很多关于将 .cpp 和 .c 文件混合到一个 makefile 中的问题,但我还没有看到混合替换引用的问题得到解决。我遇到了问题。
我的makefile是基于this answer的结构:
LIB=mylib.so
CPPSRCS += hello.cpp
CSRCS += goodbye.c
OBJS = $(CSRCS:.c=.o) $(CPPSRCS:.cpp=.o)
# Separate rules for .cpp and .c files, link together to form library.
# All pretty standard stuff and I am sure it will work if we goodbye.o and
# hello.o are present.
这不起作用,我得到了旧的没有规则来制造目标错误。我究竟做错了什么?如何将两种类型的文件的替换引用转换为一个变量?
【问题讨论】:
你得到的错误信息是什么? 您在该 makefile 中没有任何目标 - 您预期会发生什么? @Toby Speight 抱歉不清楚,我的真实 makefile 中确实有 .cpp 和 .c 文件的目标和不同的规则。这只是解决核心问题的一个玩具示例——无法从 .cpp 和 .c 文件正确生成 .o(从一个文件生成很简单)。 【参考方案1】:为了使makefile
同时适用于 C 和 C++,您需要为每种语言设置单独的规则 - 尽管有些规则是相同的。
另一个问题是链接器。仅 C 的项目将使用一个链接器,而不是另一个。
我将我的 makefile 转储到这里(来自this project)。
从这个例子可以看出,有两种不同的构建规则,一种用于使用 C 文件创建的对象,另一种用于使用 C++ 创建的对象。当第一个失败时,会尝试第二个,因此可以共享对象列表。
另外,您可能会注意到 C++ 规则有这一行 $(eval CCL = $(CPP))
,它将链接器变量 (CCL
) 设置为使用 C++ 的项目中的 C++ 链接器。这样,在调用构建规则时,它会使用正确的链接器。
另一件需要关注的是这段代码处理列表和扩展替换的方式。请注意foreach
、addsuffix
和basename
函数的使用...这显然比您建议的$(CSRCS:.c=.o)
更复杂。
我建议您添加一个显示 make 变量的规则,这样您就可以调试任何误入歧途的东西(参见演示),这是学习和解决问题的好方法。
关于makefile
我在这里粘贴的几句警告......
它适用于 C 和 C++(混合)项目,几乎是“即插即用”,但您必须更改文件夹名称和目标文件以适应您的文件夹结构。
另外,请注意它会删除整个项目如果您将临时文件夹定义为项目文件夹(定义为tmp
是有原因的,因为它使清理变得非常容易)。
将来我可能会对其进行更新,以便自动添加任何 src
子文件夹,但目前我需要额外的控制来排除某些文件夹。
这个makefile主要是一个懒惰的工作......我讨厌一直更新makefile,所以我有一个低成本的makefile,它主要计算它自己的一切......除非我改变项目的文件夹结构或需要不同的图书馆。
NAME=demo
OUT_ROOT=./tmp
TMP_ROOT=./tmp
SRC_ROOT=.
SRC_EXTRA_FOLDERS=src src/http
LIBS=-pthread -lssl -lcrypto
INCLUDE=/usr/local/include
CC=@gcc
CPP=@g++
DB=@lldb
OPTIMIZATION=O3
#auto computed values
BIN = $(OUT_ROOT)/$(NAME)
SRCDIR = $(SRC_ROOT) $(foreach dir, $(SRC_EXTRA_FOLDERS), $(addsuffix /,$(basename $(SRC_ROOT)))$(dir))
SRC = $(foreach dir, $(SRCDIR), $(wildcard $(addsuffix /, $(basename $(dir)))*.c*))
BUILDTREE =$(foreach dir, $(SRCDIR), $(addsuffix /, $(basename $(TMP_ROOT)))$(basename $(dir)))
OBJS = $(foreach source, $(SRC), $(addprefix $(TMP_ROOT)/, $(addsuffix .o, $(basename $(source)))))
CCL = $(CC)
# the C flags
CFLAGS=-Wall -g -$(OPTIMIZATION) -std=c11 $(foreach dir,$(INCLUDE),$(addprefix -I, $(dir))) $(foreach dir,$(SRCDIR),$(addprefix -I, $(dir)))
CPPFLAGS= -Wall -$(OPTIMIZATION) -std=c++11 $(foreach dir,$(INCLUDE),$(addprefix -I, $(dir))) $(foreach dir,$(SRCDIR),$(addprefix -I, $(dir)))
$(NAME): build
build: $(OBJS)
$(CCL) -o $(BIN) $^ -$(OPTIMIZATION) $(LIBS)
$(TMP_ROOT)/%.o: %.c
$(CC) -o $@ -c $^ $(CFLAGS)
$(TMP_ROOT)/%.o: %.cpp
$(CPP) -o $@ -c $^ $(CPPFLAGS)
$(eval CCL = $(CPP))
clean:
-@rm $(BIN)
-@rm -R $(TMP_ROOT)
-@mkdir -p $(BUILDTREE)
execute:
@$(BIN)
run: | clean build execute
db: | clean build
$(DB) $(BIN)
vars:
@echo "BIN: $(BIN)"
@echo ""
@echo "SRCDIR: $(SRCDIR)"
@echo ""
@echo "SRC: $(SRC)"
@echo ""
@echo "BUILDTREE: $(BUILDTREE)"
@echo ""
@echo "OBJS: $(OBJS)"
@echo ""
@echo "CFLAGS: $(CFLAGS)"
@echo ""
@echo "CPPFLAGS: $(CPPFLAGS)"
按照 Toby Speight 的建议,我添加了管道符号 (|
) 以将先决条件标记为已订购,以供所有并发人员使用。
【讨论】:
"Here's my makefile" 对 OP 没有太多的教育价值,谁会从 why 你的作品中受益更多,而你的作品却没有。请edit你的回答澄清原件有什么问题以及你做了什么来解决它。 顺便说一句,我注意到规则run: clean build execute
的目标不依赖于顺序,因此多线程 make 可能会在 clean
目标完成之前启动 execute
目标...跨度>
@TobySpeight,感谢您的意见。我没有注意到依赖部分,我会尽快编辑。至于解释,我经常将makefile
视为项目的先决条件,例如编译器,拥有应该做的工作,知道它为什么工作很好但并不重要......但你也是对的。我将添加几句话来说明为什么这允许 C++ 和 C 混合。但是,考虑到没有发布错误数据,我怀疑我会解释 OP 的 makefile 可能存在的问题。
@Myst foreach、basename、addsuffix 的组合正是我想要的......谢谢!linux文件名替换
1、直接用mv移动命令mva**.cppb**.c#移动以a开头.cpp文件并重命名成以b开头.c文件2、用文本处理工具awk操作lsa*.cpp|awk'n=$0;sub(/^a/,"b");sub(/\.cpp$/,".c");system("mv"n""$0)'#ls命令查看所有a开头的.cpp文件,... 查看详情
为啥有头文件和 .cpp 文件? [关闭]
】为啥有头文件和.cpp文件?[关闭]【英文标题】:Whyhaveheaderfilesand.cppfiles?[closed]为什么有头文件和.cpp文件?[关闭]【发布时间】:2008-12-0213:17:55【问题描述】:为什么C++有头文件和.cpp文件?【问题讨论】:相关问题:***.com/questi... 查看详情
C++ 代码文件扩展名? .cc和.cpp有啥区别[关闭]
】C++代码文件扩展名?.cc和.cpp有啥区别[关闭]【英文标题】:C++codefileextension?Whatisthedifferencebetween.ccand.cpp[closed]C++代码文件扩展名?.cc和.cpp有什么区别[关闭]【发布时间】:2010-12-0510:18:36【问题描述】:我看到C++代码同时保存为.... 查看详情
c_cpp替换+ve和-veno.s的数组(代码片段)
C ++标头顺序[关闭]
...osed]【发布时间】:2010-10-1111:42:28【问题描述】:header/cpp文件中的headers应该以什么顺序声明?显然,后续标头所需的那些应该更早,并且特定于类的标头应该在cpp范围内而不是标头范围内,但是是否有固定的顺序约定/最佳实践... 查看详情
c语言:如何将字符串中指定的字符替换为另一个指定字符
...言编译器。1、首先,打开C语言编译器,新建一个初始.cpp文件,例如:test.cpp。2、在test.cpp文件中,输入C语言代码:chara[]="helloworld!",b[20]; strrpl(a,b,sizeof(b),"world","c");puts(a);3、编译器运行test.cpp文件,此... 查看详情
c_cpp通过前一个和下一个的乘法替换每个数组元素(代码片段)
Makefile 编译 c 和 cpp 文件
】Makefile编译c和cpp文件【英文标题】:Makefiletocompilebothcandcppfiles【发布时间】:2016-02-0314:03:07【问题描述】:我想编译我的程序,但这样做有一些问题。我的程序由一个用C编写的main函数组成。其他文件是我没有编写的.h或.cpp文... 查看详情
在工程中包含两个cpp文件(只有一个有main),那这段程序是怎样运行的?
...退出。3、然后,使用命令[ls],可以看到自己刚才写的cpp文件。4、如果之前在Linux下写过C程序,可以知道编译C程序用的命令是[gcchello.c-ohello]。5、然后再用[ls]命令,查看编译出来的可执行文件。6、最后使用命令[./hello],运行程... 查看详情
c语言:如何将字符串中指定的字符替换为另一个指定字符
...言编译器。1、首先,打开C语言编译器,新建一个初始.cpp文件,例如:test.cpp。2、在test.cpp文件中,输入C语言代码:chara[]="helloworld!",b[20];strrpl(a,b,sizeof(b),"world","c");puts(a);3、编译器运行test.cpp文件,此时成... 查看详情
c ++ opengl我如何制作着色器文件并在主cpp中使用它[关闭]
】c++opengl我如何制作着色器文件并在主cpp中使用它[关闭]【英文标题】:c++openglhowcanimakeashaderfileanduseitinmaincpp[closed]【发布时间】:2019-09-0106:27:54【问题描述】:我想让opengl读取着色器文件并在主cpp中使用它我在thechernoproject频道... 查看详情
c语言中的.c和.cpp有啥区别?
参考技术A一、指代不同1、.c:表示C的源程序。2、.cpp:表示C++的源程序。二、变量声明不同1、.c:c中变量声明和代码是分开的,必须在函数开始处声明。2、.cpp:c++变量可以在任意处声明,只要保证先声明后使用就行。三、指... 查看详情
请教如何运行含多个cpp的一个c++项目里面的一个cpp
每一个c++项目中可以包含多个cpp文件和.h文件,不过只能有而且必须有一个cpp文件中包含main函数,否则就会报错。所以在一个c++项目中不能单独运行一个cpp文件,只能运行一个项目。如果你想一个一个的运行cpp文件,请建立多个... 查看详情
visualc++6里创建源文件和头文件有啥区别
本人刚学,头文件和源文件在功能上,用法上,有很大不同头文件最大的特点就是,各种程序都可以包含它,可以起到代码的重用,提高效率,使得要写很多代码的程序直接用饱含头文件的方法就能实现。头文件可以想象成代码... 查看详情
c++头文件和cpp文件的原理(代码片段)
...译模式通常,在一个C++程序中,只包含两类文件——.cpp文件和.h文件。.cpp文件被称作C++源文件,里面放的都是C++的源代码.h文件则被称作C++头文件,里面放的也是C++的源代码,头... 查看详情
没有在 Visual Studio 2019 中运行 .cpp 文件的选项 [关闭]
】没有在VisualStudio2019中运行.cpp文件的选项[关闭]【英文标题】:Nooptiontoruna.cppfileinVisualStudio2019[closed]【发布时间】:2021-02-1006:38:26【问题描述】:我是VisualStudio和C++的新手。我想运行一个简单的C++程序来打印helloworld。但我没有... 查看详情
c中头文件在cpp文件里引用和.h文件引用的思考
我们在编敲代码中头文件是常常使用的。可是头文件是应该包括在.H文件里还是在.cpp文件里。在这个其中有什么样去差别呢。 假如说我们编写了一个a.cpp 。我们将a.cpp文件的变量和函数申明在a.h中。在a.... 查看详情