添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

参考链接: 链接

适用于:在一个 Project 中,有多个 *.cpp/*.c 文件,多个文件中同时含有 main 函数。处于方便考虑,在 Makefile 文件中,目标可执行文件的依赖项,包含了所有源文件编译生成的 *.o 文件。这样的话,在编译的时候,就会产生 main 函数重复定义的错误。

例如,在一个 Project 中,有 main.cpp test.cpp 两个源代码文件,位于src目录下,每一个文件中都有一个 main 函数,分别用于生成两个不同的目标可执行文件 Main Test 。为了方便,在 Makefile 文件中是这样写的:

1

2

3

4

5

6

7

OBJ=./src/main.o ./src/test.o

Main:${OBJ}

${CXX} ${OBJ} $(LIBS) -o $@

Test:${OBJ}

${CXX} ${OBJ} $(LIBS) -o $@

这样的话,在生成目标可执行文件 Main 或者 Test 时,均会对两个 *.o 文件的内容进行分析、链接,导致产生 main 函数重复定义的错误。

为了解决上述问题,使用了 Makefile 的条件编译功能。

在C/C++源代码中, main 函数用 #ifdef #endif 包含起来,例如:

1

2

3

4

5

6

7

8

9

#ifdef TEST_

int main() {

system ( "/home/xingyu/Desktop/test.sh abc" );

return 0;

}

#endif

上述例子中的宏 "TEST_" ,不在C/C++源代码中定义,而是在调用 GCC/G++ 编译器时,通过参数 "-D TEST_" 定义。对于不同的目标文件,用不同的宏将对应的 main 函数包含起来,再在调用时分别加入不同的 "-D xxxxx" 参数即可。

对于 Makefile 文件,可以用以下方式来处理:

1

2

3

4

5

6

7

8

9

CXXFLAGS = -c -O2 -g -Wall -fmessage-length=0 -I ${INC_DIR}

ifeq ($(TARGET),Test)

CXXFLAGS += -D TEST_

endif

ifeq ($(TARGET),Main)

CXXFLAGS += -D MAIN_

endif

其中 CXXFLAGS GCC/G++ 在编译时的一系列参数, TARGET 可以在执行 make 命令的时候定义。例如,要编译生成目标 "Test" ,可以执行命令 "make TARGET=Test Test "命令,之后通过 Makefile 文件中的 "ifdef" 语句就可以正确的生成 CXXFLAGS

测试Project的目录结构如下:

共有5个文件夹, inc src 中分别是头文件和源代码文件, doc 中是一些说明文档, obj 中是生成的 *.o 文件, bin 中是生成的目标可执行文件。其中, main.cpp test.cpp WaterCurtain.cpp 三个文件中均含有main函数。

Project 的完整 Makefile 文件内容如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

CXXFLAGS = -c -O2 -g -Wall -fmessage-length=0 -I ${INC_DIR}

ifeq ($(TARGET),WaterCurtain)

CXXFLAGS += -D WATERCURTAIN_

endif

ifeq ($(TARGET),Main)

CXXFLAGS += -D MAIN_

endif

ifeq ($(TARGET),Test)

CXXFLAGS += -D TEST_

endif

LIBS =

INC_DIR=./inc

BIN_DIR=./bin

SRC_DIR=./src

OBJ_DIR=./obj

SRC=${wildcard ${SRC_DIR}/*.cpp}

OBJ=${patsubst %.cpp,$(OBJ_DIR)/%.o,${notdir ${SRC}}}

TARGET=WaterCurtain Test Main

BIN_TARGET=${BIN_DIR}/${TARGET}

${BIN_TARGET}:${OBJ}

@echo "building " $@

@${CXX} ${OBJ} $(LIBS) -o ${BIN_TARGET}

@echo "finished " $@

WaterCurtain:${BIN_DIR}/WaterCurtain

Test:${BIN_DIR}/Test

Main:${BIN_DIR}/Main

${OBJ_DIR}/%.o:${SRC_DIR}/%.cpp

@echo "building " $@

@${CXX} ${CXXFLAGS} $< -o $@

@echo "finished " $@

clean_All:

@echo "cleaning......"

@rm -f $(OBJ) $(BIN_TARGET)

@echo "finished cleaning"

clean_obj:

@echo "cleaning obj files......"

@rm -f $(OBJ)

@echo "finished cleaning obj files"

clean_WaterCurtain:

@echo "cleaning WaterCurtain......"

@rm -f ${BIN_DIR}/WaterCurtain

@echo "finished cleaning WaterCurtain"

clean_Test:

@echo "cleaning Test......"

@rm -f ${BIN_DIR}/Test

@echo "finished cleaning Test"

clean_Main:

@echo "cleaning Main......"

@rm -f ${BIN_DIR}/Main

@echo "finished cleaning Main"

#$@:目标的名字

#

#$^:构造所需文件列表所有所有文件的名字

#

#$<:构造所需文件列表的第一个文件的名字

#

#$?:构造所需文件列表中更新过的文件

#$(subst 要被替换的字符串,用来替换的字符串,被处理的字符串):

#

#$(wildcard 寻找的文件):

#

#$(basename 文件名):

#用于查看变量的值

#test:

#   echo $(SRC)

#   echo $(OBJ)


注意:在编译与上一个目标文件不同的目标文件时,需要先删除所有 *.o 文件。

例如,上一次编译的是 Test ,现在想要编译 Main ,则需要先清楚所有的 *.o 文件,否则会导致错误。因为在编译 Test 的时候,由于宏定义的作用,会将 test.cpp 中的 main 函数编译生成 test.o 文件,而 main.cpp 中的 main 函数会被忽略,生成 main.o 文件。在编译新目标文件 Main 时,如果 test.cpp 文件没有发生更改,那么 test.o 文件就不会被重新编译,这样的话 test.o 文件中事实上是包含了 main 函数的,由于没有对 test.cpp 文件进行重新编译,因此在编译 Main 时,声明的宏定义没有起作用。如此一来,就会再次出现 main 函数重复定义的错误。如果不想删除所有的 *.o 文件,则需要确保在编译 Test 之后 Main 之前, test.cpp main.cpp 两个源代码文件均已经进行了修改,这样新的宏定义才会生效。

哪里有看不懂的地方,可以发邮件询问:2509673789@qq.com。

测试基于Ubuntu16.04 Eclipse for C/C++参考链接:链接适用于:在一个Project中,有多个*.cpp/*.c文件,多个文件中同时含有main函数。处于方便考虑,在Makefile文件中,目标可执行文件的依赖项,包含了所有源文件编译生成的*.o文件。这样的话,在编译的时候,就会产生main函数重复定义的错误。例如,在一个Project中,有main...
本资源包含两个样例框架 makefile +C Makefile : 已经写好了初始化的 makefile 和CMakeLists.txt 文件 ,只需要在框架的基础上添加自己的需求就可以了,但是最基础的make和cmake的语法还是需要懂的,才能写好框架,提高自己项目的效率。 希望这两个小框架能对大家有用,后续还会继续更新框架,争取让框架更加的完美。
现在我们讲使用数据库来进行变成,具体的提供了SELECT INSERT UPDATE DELETE等数据库的执行语句,这是在数据库的接口,当在图形下显示数据时需要使用到QSqlTableModel。所以在数据库编程之前需要掌握基础的SQL 命令语句。   数据库驱动层   相关联的类包含了QSqlDriver ,QSqlDriverCreatpor ,QSqlDriverCreatorBase,QSqlDriverPlugin与QSqlResult 。   数据库的应用程序接口层   这些类提供了访问数据库,提出 一个 连接请求,如同 文件 访问一样
Makefile 编写实例: 1.前提是需要安装MInGw——c/ c++ 编译器,不懂的可以私信我哈; 2.本程序是利用bat脚本直接运行 Makefile ,非常方便;直接点击运行“run.bat”即可编译,方便快捷。 3. makefile 为采用通用性规则编写,自动搜索所在目录 的代码,自动编译; 4.适应于编译 C++ /C代码。
去年做项目的时候,由于有需要编译出 多个 可执行 文件 的需求,修改了 Makefile 使其支持生成 多个 结果(编译 多个 含有 main 函数 文件 ),但总觉得自己的实现不够完美。   今年又遇到这样需求的时候,可在网上找了一圈,发现没有找到能够同时编译得到 多个 结果的 Makefile 模板。 可以发现,其 ,seeker.c 以及 main .c 都有 main 函数 ,如果按照以...
多个 Makefile 文件 编译, Makefile 多目标编译和多层次编译README Makefile 多目标编译 Makefile 多层次编译a 文件 夹b 文件 夹include 文件 夹obj 文件 多个 Makefile 文件 编译 README 文件 夹以及 文件 说明。 根 文件 夹为make,实现 多个 Makefile 文件 编译。 make----- /* 一级 文件 夹:多 Makefile 编译 */ |-------a_b /* 二级 文件 夹:多目标编译 */
部分内容见https://blog.csdn.net/guansheng123/article/details/123127925?spm=1001.2014.3001.5501 包括实验目的,实验内容,实验步骤,make编译和运行,实验分析,程序所有功能及使用方法,编译和运行方法,设计文档,用户手册,注意事项。 实验内容: 一、基本任务1:用C/ C++ 编写 一个 简单的shell 程序,实现以下基本的命令。 1) 浏览目录和 文件 的各种属性ls(可以不支持参数) 2) 回显命令 echo 3) 显示 文件 内容 cat 4) 创建目录mkdir 5) 删除 文件 rm 6) 切换目录cd 7) 显示当前目录 pwd 8) 文字统计 wc 二、基本任务2:每一条命令单独对应 一个 源程序 文件 ,不允许所有命令 一个 文件 。 写 一个 makefile 来管理这些源 文件 。 三、基本任务3:写清楚make 编译和运行的过程。 四、选做任务: 1、任何你想实现的其他命令 2、提供友好的人机界面:例如提供命令列表、命令查询、命令帮助等。
近做了一系列的单元测试相关的工作,除了各种规范及测试框架以外,讨论比较多的是关于代码覆盖率的产生,c/ c++ 与其他的一些高级语言或者脚本语言相比较而言,例如 Java、.Net和php/python/perl/shell等,由于没有这些高级语言和脚本语言的反射的特性,其代码覆盖率的产生过程会稍微复杂一些。发现许多同学对 C++ 的覆盖率如何产生在都不太清楚,这里做 一个 简单的介绍。   一、基本使用方法   在 Linux 上的c/ c++ 开发一般都使用gcc/g++作为主要的编译器,如果需要产生覆盖率数据需要在 Makefile 或者Scons 文件 做下面的编译链接设置,   编译的时候,增加
之前的问题描述 在 makefile 加编译参数-pthread也就是由这个问题,让我一步步去学习了 makefile 的使用 makefile 默认只生成第 一个 可执行 文件 ,所以为了同时编译 多个 可执行 文件 ,我们用到了伪可执行 文件 ,make 过程 并不生成 这个伪可执行 文件 ,利用依赖的属性,同时生成三个可执行 文件 源代码功能介绍 编写程序send...
1.写在前面最近弄 Linux 编程,自己写 Makefile 编译代码。产生了2个需求:1. 一个 Makefile 编译链接 多个 .c或.cpp 文件 ,生成 多个 可执行程序;2. 一个 Makefile 编译链接 多个 .c或.cpp 文件 ,只生成 一个 可执行程序。今天只说第1个需求。2. Makefile 网上讲 Makefile 文章很多,我这就不耍大刀了。 直接来Makefiel代码:CC = g++ C_FLAGS = -