从上次碰到编译链接带有自定义库的C源文件后,就停止了学习,工作时间瞎忙,这一个多点星期以来,老问题又重新涌上脑际,查阅了好多与 Makefile Gcc 相关的网页资料,终于搞明白了相关的原因,记录下这一过程中遇到的一些困难与问题,以资分享。

GCC 环境变量

在搭建好基本软件后,您还需要注意一些细节问题,重要的是环境变量的设置,用于帮助我们准确找到你的源文件中包括的用户自义函数库,以及头文件。-->头文件.h 库文件.lib .a

  • 环境变量与Gcc编译错误

环境变量中没有定义:

C_INCLUDE_PATH=E:\cs50\include  --->头文件具体位置,所在路径

LIBRARY_PATH=E:\cs50\lib   ---->库文件具体位置,.lib 或者 .a 文件

注意:LIBRARY_PATH  C_INCLUDE_PATH 这两个为GCC编译时使用的.h,.a文件所在目录,名称似乎不能胡乱更改。

假设源文件hi3.c包括了自定义库 libcs50.a 也即 #include “cs50.h”。我们在命令行下可以尝试下——

#=========== 没有C_INCLUDE_PATH ===========

C:\Users\Administrator>gcc hi3.c -o hi3

hi3.c:2:18: fatal error: cs50.h: No such file or directory

compilation terminated.

#=========== 设置好 LIBRARY_PATH  C_INCLUDE_PATH ,但没有指明 -lcs50 ===========

C:\Users\Administrator>gcc hi3.c -o hi3

C:\Users\ADMINI~1\AppData\Local\Temp\ccitQVf8.o:hi3.c:(.text+0x1b): undefined reference to `GetString'

collect2.exe: error: ld returned 1 exit status

#===========  命令中加上 -lcs50 成功 ===========

C:\Users\Administrator>gcc hi3.c -o hi3 -lcs50

C:\Users\Administrator>

# ============================================

可见,在编译与链接过程中,这两个变量将产生实际的影响。当然,您也可以在使用过程中自己指出具体路径

C:\Users\Administrator>gcc hi3.c –IE:\cs50\include –LE:\cs50\lib -o hi3 -lcs50

C:\Users\Administrator>

“-I” 和“-L” 两个分别是编译和链接时,找寻.h文件、.a文件的具体路径

总的来说,只要设置好这两个变量,CS50学习环境下就可以自由地运行GCC了。但我们的目标是,直接“make 目标”  就能生成我们需要的一键编译生成可执行文件。我们目前还是停留在我上一篇的老问题上,如图所示:

如果GCC能正常进行,而make却不能有效工作,我们需要研究makefile文件的编写了!

Makefile 文件的编写

(一)基本规则、命令书写

这是我在office 2013 Word 中截取的图片,其中可以看到TAB键。如果依赖文件比较多,也可以”\””;”处理

2.基本示例及说明:

  • 这个 #  用于注释
  • main 是“目标”;后面 .o 文件是它的依赖文件
  • .o 文件各自又依赖相应的 .c .h 文件
  • clean: 这个目标没有依赖,目的在于执行下面的命令

如果当前文件夹下面存在一个名为clean的文件,这个命令就不会执行了,因为没有依赖,make认为这个clean文件始终是最新的,不符合更新的条件。为了避免这种情况,一般在makefile文件中指定clean为伪目标     .PHONY clean

# ========BASIC VERSION =================
main:main.o add.o sub.o
    gcc main.o add.o sub.o -o main
main.o:main.c add.h sub.h
    gcc -c main.c -o main.o
add.o:add.c add.h
    gcc -c add.c -o add.o
sub.o:sub.c sub.h
    gcc -c sub.c -o sub.o
clean:
    del main.exe main.o add.o sub.o
# ========================================

3.自定义变量与自动化变量

OBJ 是自定义变量,引用变量时用“$(   )”的方式

$@ —— 代表目标
$< —— 当前目标的第一个依赖文件
$^ —— 当前目标的所有依赖文件

# ====== version 1 ======
OBJ=main.o add.o sub.o
main:$(OBJ)
    gcc $(OBJ) -o $@
main.o:main.c add.h sub.h
    gcc -c $< -o $@
add.o:add.c add.h
    gcc -c $< -o $@
sub.o:sub.c sub.h
    gcc -c $< -o $@
clean:
    del *.o *.exe
# =======================

(二)makefile自动推导规则(与C语言相关的)

你可以在命令行下打:"make -p >view.txt” 然后打开view.txt 查看有关内置规则(# Implicit Rule)

%: %.c

# recipe to execute (built-in):

$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@

我想这条就是内置将.c文件生成.exe可执行文件的内置规则

# default

LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

多看看make 的帮助文件,是学习的好途径!由上面我们可以看出,如果在环境变量中设置这些变量的值,我们就可以做到“定制”默认的make方式了,这就可以完成CS50学习环境的设置了!!!将 LINK.c 代入$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@ 扩展开来就像下面这样了:

%: %.c           <====表示直接将.c 源文件编译链接成可执行文件(.exe )

$(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH) $^ $(LOADLIBES) $(LDLIBS) -o $@

如果您的环境变量中没有设置相应的值,make 默认的表现会是:cc hi3.c –o hi3  我们可以利用这一特性,“改变”内置规则的外在表现以符合我们自己的特殊需要。注意:根据上面的扩展可知 $(LDFLAGS)$^$(LDLIBS)-o $@ 这个顺序需要引起高度重视!如果这两个变量弄反了……后果会很严重,嘿嘿。

在这个例子中,$^表示的是hi3.c $@表示的是hi3   -lcs50 在 $^ 前还是后的位置影响编译链接结果!

  • 最初错误的设置,您看出来了么?
  • CS50 学习环境的正确的设置是这样的

CC=gcc

CFLAGS=-ggdb -std=c99 -Wall -Werror -Wformat=0

CPPFLAGS=-IE:\CS50\INCLUDE

LDLIBS=-LE:\CS50\LIB

LDFLAGS=-lcs50 -lm

CC=gcc

CFLAGS=-ggdb -std=c99 -Wall -Werror -Wformat=0

LDLIBS=-lcs50 -lm

CPPFLAGS=-IE:\CS50\INCLUDE

LDFLAGS=-LE:\CS50\LIB

如果环境变量中已经设置了CPPFLAGS=-IE:\CS50\INCLUDE 和LDFLAGS=-LE:\CS50\LIB 那么,makefile 文件里面就可以只设置 CC CFLAGS LDLIBS 三个即可。

CC=gcc

CFLAGS=-ggdb -std=c99 -Wall -Werror -Wformat=0

LDLIBS=-lcs50 -lm

(三)初学者适用的makefile文件

初学者习惯于在一个目录中练习自己编写好的C语言源文件,网上文章中习惯介绍这样一种makefile文件放在练习目录之中:

.PHONY:clean all
CC=gcc
CFLAGS=-g -Wall
BIN=hi1 hi2 hi3

vpath %.h E:\cs50\include
vpath %.a E:\cs50\lib
all:$(BIN)

.c.o:
    $(CC) $(CFLAGS) -c $< -o $@
hi1:hi1.o
    $(CC) $(CFLAGS) $^ -o $@
hi2:hi2.o cs50.h
    $(CC) $(CFLAGS) $^ -o $@
hi3:hi3.o cs50.h -lcs50
    $(CC) $(CFLAGS) $^ -o $@
clean:
    del *.o *.exe

这样的makefile比较清楚,但每次新的测试文件加入后,需要手动添加需要编译的新文件,有点“麻烦”,考虑到这一点,我们可以利用上面makefile的自动推导规则,通过对环境变量的设置,定制“万能”一些的makefile文件:

.PHONY:clean all
CC=gcc
CFLAGS=-ggdb -std=c99 -Wall -Werror -Wformat=0
#CPPFLAGS=-IE:\cs50\include
#LDFLAGS=-LE:\cs50\lib
LDLIBS=-lcs50 -lm
OBJS=$(patsubst %.c,%.o,$(wildcard *.c))
BIN=$(basename $(OBJS))
all:$(BIN)

clean:
    del *.o *.exe

到此,我们可以做到像CS50课堂中那样,make “目标” 就能自动处理了。
环境变量的设置可以做成一个注册个文件,导入一下就行:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Session Manager\Environment]
"C_INCLUDE_PATH"="E:\\cs50\\include"
"CC"="gcc"
"CFLAGS"="-ggdb -std=c99 -Wall -Werror -Wformat=0"
"CPPFLAGS"="-IE:\\cs50\\include"
"LDFLAGS"="-LE:\\cs50\\lib"
"LDLIBS"="-lcs50 -lm"
"LIBRARY_PATH"="E:\\cs50\\lib"

以上内容用记事本保存成 .reg 文件,双击导入即可完成设置,当然您需要根据自己的实际情况加以修改。

GCC –MM 显示的问题

一个遗留问题:hi3.c 源文件中明明引用了cs50.h文件,按理GCC –MM –hi3.c 后,会显示:hi3.o:hi3.c cs50.h  但实际上却只显示 hi3.o:hi3.c ,我不知道这是什么原因:

唉,目前不知道从哪入手来想……以后再说了。

转载于:https://www.cnblogs.com/shudibo/archive/2013/05/29/3105592.html

Win7 命令行下C语言学习环境搭建(三)相关推荐

  1. 计算机辅助语言和计算语言学关系,建构主义理论视角下计算机辅助语言学习环境对留学生学习汉语动机的影响——以广西大学泰国留学生为例-语言学及应用语言学专业论文.docx...

    下,学习动机是否有所提高,还有待进一步的研究.在相关理论和英语实践研究成果的指导之下,笔者通过调查问卷.访 下,学习动机是否有所提高,还有待进一步的研究. 在相关理论和英语实践研究成果的指导之下,笔者 ...

  2. 在win7命令行下编译运行C++程序

    1.安装VS2010,我的系统是64位的,因此安装64位配置环境变量 2.配置环境变量,在系统-属性-高级系统设置里配置环境变量 1)配置cl编译器,在path中添加C:\Program Files  ...

  3. 关于Windows命令行下C语言printf输出中文乱码问题

    1.问题描述 如下图,通过DOS命令行执行test.exe文件,printf内本来写着中文"输入要打开的文件名:"结果显示为乱码 2.问题原因 一般出现这个情况是由于代码编辑器的编 ...

  4. 最新Windows下Go语言开发环境搭建+GoLand配置

    一.下载Go语言开发包 大家可以在Go语言官网(https://golang.google.cn/dl/)下载 Windows 系统下的Go语言开发包,如下图所示. 这里我们下载的是 64 位的开发包 ...

  5. Go语言学习环境搭建

    简介 Go编程语言是一个使得程序员更加有效率的开源项目.Go是有表达力.简洁.清晰和有效率的.它的并行机制使其很容易编写多核和网络应用,而新奇的类型系统允许构建有弹性的模块化程序.Go编译到机器码非常 ...

  6. 在wsl下运行c语言,在Windows10通过WSL架设linux/gcc c语言学习环境

    在Windows10通过WSL架设linux/gcc c语言学习环境 零:简单介绍与先决条件 中国一般的大学C课程中都使用很过时的编译器来进行教授--比如说什么visual studio 6.0啊,d ...

  7. 在linux命令行 下学习编写java

    对于新手来讲, 使用eclipse 等IDE来学习java是最为方便和效率的. 学习Java能令程序猿深刻地理解面向对象的编程思想 . 但Java 是一个跨平台的编程语言. 本文介绍下在命令行下学习j ...

  8. 在Windows和Linux系统上,用C语言实现命令行下输入密码回显星号和完全隐藏密码

    本篇目录 引子 在Windows 上实现 在Linux上实现 回显星号 代码解读 运行 完全隐藏 运行 引子 在Windows系统上,当我们使用命令行和MySQL进行交互时,第一步就是要输入密码: - ...

  9. windows下快速配置C/C++语言学习环境

    1. 喜欢IDE开发模式的同学, 可以直接安装codeblock. 官网 Code::Blocks - Code::Blocks 支持跨平台Linux,Mac,Windows. windows版本按转 ...

最新文章

  1. 坑系列 --- 时间和空间的平衡
  2. 啥?Transformers又来刷CV的榜了?
  3. 【结果很简单,过程很艰辛】记阿里云Ons消息队列服务.NET接口填坑过程
  4. 云原生的浪潮下,为什么运维人员适合学习Go语言?
  5. mysql数据库入门教程(7):库和表的管理
  6. 【转】图文详解YUV420数据格式
  7. asa 防火墙基本配置管理
  8. 透视转换oracle,使用Oracle的行列转化函数实现ASH的数据透视功能
  9. 让fedora满足你的日常办公和影音
  10. sublime text3 中 python3编译出现中文乱码解决方法
  11. k-近邻算法 ---sklearn
  12. ssm毕设项目疫情防控管理系统02vsf(java+VUE+Mybatis+Maven+Mysql+sprnig)
  13. 【名企招聘】4月26日19点,涛思数据带着高薪岗位JD和精美周边来啦~
  14. java碳纤维山地车车架咋样_自行车碳纤维车架值得买吗?它有哪些优缺点?老骑手来给你答案!...
  15. 实现 RecyclerView 上拉加载及自动加载
  16. 手撸架构,Java基础 面试100问
  17. golang实现人民币小写转大写
  18. ROG 幻16无线网卡驱动无法更新
  19. 离散数学班委竞选问题用python程序实现(课本p45.30)
  20. VC2005 如何获取系统时间

热门文章

  1. [转] linux IO
  2. Z 字形变换 C++实现 java实现 leetcode系列(六)
  3. [转]Linux配置防火墙
  4. kubernetes常用命令
  5. js 禁止复制粘贴全选
  6. Linux下出现Read-only file system的解决办法
  7. WCF-学习笔记概述之计算服务(1)
  8. 微信公众平台开发(104) 自定义菜单扫一扫、发图片、发地理位置
  9. 漫水填充算法 - cvFloodFill() 实现
  10. PHP数据库链接类(PDO+Access)