C/C++笔记 #035# Makefile
相关资料:
- Understanding roles of CMake, make and GCC
GCC and Make ( A simple tutorial, teaches u how to use gcc and make.)
实践记录:
1、查看 g++ / gcc 的版本:
root@xkfx:~# gcc --version
gcc (Debian 4.9.-) 4.9.
Copyright (C) Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. root@xkfx:~# gcc -v # 详细版本
2、You can get the help manual via the --help
option.
root@xkfx:~# gcc --help
Usage: gcc [options] file...
Options:
-pass-exit-codes Exit with highest error code from a phase
--help Display this information
--target-help Display target specific command line options
--help={common|optimizers|params|target|warnings|[^]{joined|separate|undocumented}}[,...]
Display specific types of command line options
(Use '-v --help' to display command line options of sub-processes)
--version Display compiler version information
-dumpspecs Display all of the built in spec strings
-dumpversion Display the version of the compiler
-dumpmachine Display the compiler's target processor
-print-search-dirs Display the directories in the compiler's search path
-print-libgcc-file-name Display the name of the compiler's companion library
-print-file-name=<lib> Display the full path to library <lib>
-print-prog-name=<prog> Display the full path to compiler component <prog>
-print-multiarch Display the target's normalized GNU triplet, used as
a component in the library path
-print-multi-directory Display the root directory for versions of libgcc
-print-multi-lib Display the mapping between command line options and
multiple library search directories
-print-multi-os-directory Display the relative path to OS libraries
-print-sysroot Display the target libraries directory
-print-sysroot-headers-suffix Display the sysroot suffix used to find headers
-Wa,<options> Pass comma-separated <options> on to the assembler
-Wp,<options> Pass comma-separated <options> on to the preprocessor
-Wl,<options> Pass comma-separated <options> on to the linker
-Xassembler <arg> Pass <arg> on to the assembler
-Xpreprocessor <arg> Pass <arg> on to the preprocessor
-Xlinker <arg> Pass <arg> on to the linker
-save-temps Do not delete intermediate files
-save-temps=<arg> Do not delete intermediate files
-no-canonical-prefixes Do not canonicalize paths when building relative
prefixes to other gcc components
-pipe Use pipes rather than intermediate files
-time Time the execution of each subprocess
-specs=<file> Override built-in specs with the contents of <file>
-std=<standard> Assume that the input sources are for <standard>
--sysroot=<directory> Use <directory> as the root directory for headers
and libraries
-B <directory> Add <directory> to the compiler's search paths
-v Display the programs invoked by the compiler
-### Like -v but options quoted and commands not executed
-E Preprocess only; do not compile, assemble or link
-S Compile only; do not assemble or link
-c Compile and assemble, but do not link
-o <file> Place the output into <file>
-pie Create a position independent executable
-shared Create a shared library
-x <language> Specify the language of the following input files
Permissible languages include: c c++ assembler none
'none' means revert to the default behavior of
guessing the language based on the file's extension Options starting with -g, -f, -m, -O, -W, or --param are automatically
passed on to the various sub-processes invoked by gcc. In order to pass
other options on to these processes the -W<letter> options must be used. For bug reporting instructions, please see:
<file:///usr/share/doc/gcc-4.9/README.Bugs>.
3、You can read the GCC manual pages (or man pages) via the man
utility:
root@xkfx:~# man gcc
No manual entry for gcc
See 'man 7 undocumented' for help when manual pages are not available.
4、More GCC Compiler Options
root@xkfx:~/labs# g++ hello.cpp -Wall -g
-Wall
: prints "all
" warning messages.
-g
: generates additional symbolic debuggging information for use with gdb
debugger.
5、Compile and Link Separately
The above command compile the source file into object file and link
with other object files (system library) into executable in one step. You may separate compile and link in two steps as follows:
root@xkfx:~/labs# ls
hello.cpp root@xkfx:~/labs# g++ hello.cpp -c -Wall -g // Compile-only with -c option
root@xkfx:~/labs# ls
hello.cpp hello.o
root@xkfx:~/labs# g++ hello.o -o hello.exe -g // Link object file(s) into an executable
root@xkfx:~/labs# ls
hello.cpp hello.exe hello.o root@xkfx:~/labs# ./hello.exe
hello,
6、对于多个源文件编译成一个可执行文件,比较好的实践是,分开编译再链接,这样修改一个源文件就不必再编译所有别的源文件:
root@xkfx:~/labs# g++ hello.cpp hello2.cpp -o hello -g
/tmp/ccGNmFaS.o: In function `main':
/root/labs/hello2.cpp:: multiple definition of `main'
/tmp/ccsm0AxM.o:/root/labs/hello.cpp:: first defined here
collect2: error: ld returned exit status
root@xkfx:~/labs# g++ hello.cpp hello2.cpp -o hello
/tmp/cc1ASkoC.o: In function `main':
hello2.cpp:(.text+0x0): multiple definition of `main'
/tmp/cc4ImNYi.o:hello.cpp:(.text+0x0): first defined here
collect2: error: ld returned exit status
上面是错误的示范,顺便可以看到有 -g 和没 -g 的区别,正确姿势:
root@xkfx:~/labs# g++ hello.cpp -c
root@xkfx:~/labs# g++ hello2.cpp -c
root@xkfx:~/labs# g++ hello.o hello2.o -o hello
hello2.o: In function `main':
hello2.cpp:(.text+0x0): multiple definition of `main'
hello.o:hello.cpp:(.text+0x0): first defined here
collect2: error: ld returned exit status
这样一旦修改了 hello.cpp 就只需要再次编译 hello.cpp 然后重新链接就可以了。
7、To compile and link C/C++ program into a shared library (".dll"
in Windows, ".so"
in Unixes), use -shared
option. Read "Java Native Interface" for example.
于是顺手查了下 JNI 是怎么回事:
jNi就是java调用本地方法的技术,最简单的来说,java运行一个程序需要要和不同的系统平台打交道,在windows里就是和windows平台底层打交道,mac就是要和mac打交道,jvm就是通过大量的jni技术使得java能够在不同平台上运行。而使用了这技术的一个标志就是native,如果一个类里的一个方法被native修饰,那就说明这个方法是jni来实现的,他是通过本地系统api里的方法来实现的。当然这个本地方法可能是c或者C++,当然也可能是别的语言。jni是java跨平台的基础,jvm通过在不同系统上调用不同的本地方法使得jvm可以在不同平台间移植。
当前你自己也可以用jni来写一些程序,这种基本上是你以前使用了其他语言完成了一些功能,但是你有要用java来重复这些功能的时候,就可以使用jni来完成了。不过带来的问题就是,如果你的那个本地方法是依托于本地操作系统的话,那就意味着你的java程序也只能在这一个系统上运行了。所以jni就使得java很容易限定在了一个系统平台上,而jdk的作用在于他提供一个规范,这个规范就是包含了很多native方法,这些方法都是要本地操作系统来实现的,而实现了这些本地方法的操作系统就可以移植java平台了。 ------ 来自 baidu daay1986
8、GCC Compilation Process 图片来自相关资料之二:
assembly code 汇编代码
9、You can see the detailed compilation process by enabling -v
(verbose) option. 详细;啰嗦
root@xkfx:~/labs# g++ hello.cpp -v
Using built-in specs.
COLLECT_GCC=g++
COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Debian 4.9.2-10' --with-bugurl=file:///usr/share/doc/gcc-4.9/README.Bugs --enable-languages=c,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.9 --enable-shared --enable-linker-build-id --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.9 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --disable-vtable-verify --enable-plugin --with-system-zlib --disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64/jre --enable-java-home --with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-4.9-amd64 --with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-4.9-amd64 --with-arch-directory=amd64 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --enable-objc-gc --enable-multiarch --with-arch-32=i586 --with-abi=m64 --with-multilib-list=m32,m64,mx32 --enable-multilib --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
Thread model: posix
gcc version 4.9. (Debian 4.9.-)
COLLECT_GCC_OPTIONS='-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/4.9/cc1plus -quiet -v -imultiarch x86_64-linux-gnu -D_GNU_SOURCE hello.cpp -quiet -dumpbase hello.cpp -mtune=generic -march=x86- -auxbase hello -version -o /tmp/ccqPyWpO.s
GNU C++ (Debian 4.9.-) version 4.9. (x86_64-linux-gnu)
compiled by GNU C version 4.9., GMP version 6.0., MPFR version 3.1.-p3, MPC version 1.0.
GGC heuristics: --param ggc-min-expand= --param ggc-min-heapsize=
ignoring duplicate directory "/usr/include/x86_64-linux-gnu/c++/4.9"
ignoring nonexistent directory "/usr/local/include/x86_64-linux-gnu"
ignoring nonexistent directory "/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../x86_64-linux-gnu/include"
#include "..." search starts here:
#include <...> search starts here:
/usr/include/c++/4.9
/usr/include/x86_64-linux-gnu/c++/4.9
/usr/include/c++/4.9/backward
/usr/lib/gcc/x86_64-linux-gnu/4.9/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/4.9/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
GNU C++ (Debian 4.9.-) version 4.9. (x86_64-linux-gnu)
compiled by GNU C version 4.9., GMP version 6.0., MPFR version 3.1.-p3, MPC version 1.0.
GGC heuristics: --param ggc-min-expand= --param ggc-min-heapsize=
Compiler executable checksum: ff85870e740eb08c48a56c2c170390f8
COLLECT_GCC_OPTIONS='-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
as -v -- -o /tmp/cc9l3HyT.o /tmp/ccqPyWpO.s
GNU assembler version 2.25 (x86_64-linux-gnu) using BFD version (GNU Binutils for Debian) 2.25
COMPILER_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.9/:/usr/lib/gcc/x86_64-linux-gnu/4.9/:/usr/lib/gcc/x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.9/:/usr/lib/gcc/x86_64-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/x86_64-linux-gnu/4.9/:/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/:/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib/:/lib/x86_64-linux-gnu/:/lib/../lib/:/usr/lib/x86_64-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-shared-libgcc' '-mtune=generic' '-march=x86-64'
/usr/lib/gcc/x86_64-linux-gnu/4.9/collect2 -plugin /usr/lib/gcc/x86_64-linux-gnu/4.9/liblto_plugin.so -plugin-opt=/usr/lib/gcc/x86_64-linux-gnu/4.9/lto-wrapper -plugin-opt=-fresolution=/tmp/ccVqDgIY.res -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lgcc --sysroot=/ --build-id --eh-frame-hdr -m elf_x86_64 --hash-style=gnu -dynamic-linker /lib64/ld-linux-x86-.so. /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crt1.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crti.o /usr/lib/gcc/x86_64-linux-gnu/4.9/crtbegin.o -L/usr/lib/gcc/x86_64-linux-gnu/4.9 -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../../../lib -L/lib/x86_64-linux-gnu -L/lib/../lib -L/usr/lib/x86_64-linux-gnu -L/usr/lib/../lib -L/usr/lib/gcc/x86_64-linux-gnu/4.9/../../.. /tmp/cc9l3HyT.o -lstdc++ -lm -lgcc_s -lgcc -lc -lgcc_s -lgcc /usr/lib/gcc/x86_64-linux-gnu/4.9/crtend.o /usr/lib/gcc/x86_64-linux-gnu/4.9/../../../x86_64-linux-gnu/crtn.o
10、You can use the -Dname
option to define a macro, or -Dname=value
to define a macro with a value. The value
should be enclosed in double quotes if it contains spaces. 例如说:
#include <iostream>
using namespace std; int main()
{
cout << HELLO << endl;
return ;
}
root@xkfx:~/labs# g++ hello.cpp -DHELLO= -g
root@xkfx:~/labs# ./a.out
11、Static Libraries (.lib, .a) vs. Shared Library (.dll, .so)
前者是直接把外部代码拷贝进你的代码,然后形成可执行文件。
后者则是在你的可执行程序跑起来之前,操作系统加载外部代码给你的程序调用。
因为后者节省空间,内存(好几个程序可以共用一个 share library),GCC 总是会在可能的情况下优先采用动态链接。
12、Searching for Header Files and Libraries (-I, -L and -l)
When compiling the program, the compiler needs the header files to compile the source codes; the linker needs the libraries to resolve external references from other object files or libraries. The compiler and linker will not find the headers/libraries unless you set the appropriate options, which is not obvious for first-time user. For each of the headers used in your source (via #include directives), the compiler searches the so-called include-paths for these headers. The include-paths are specified via -Idir option (or environment variable CPATH). Since the header's filename is known (e.g., iostream.h, stdio.h), the compiler only needs the directories. The linker searches the so-called library-paths for libraries needed to link the program into an executable. The library-path is specified via -Ldir option (uppercase 'L' followed by the directory path) (or environment variable LIBRARY_PATH). In addition, you also have to specify the library name. In Unixes, the library libxxx.a is specified via -lxxx option (lowercase letter 'l', without the prefix "lib" and ".a" extension). In Windows, provide the full name such as -lxxx.lib. The linker needs to know both the directories as well as the library names. Hence, two options need to be specified.
13、尝试通过“cpp -v”列出“GNU C预处理器”使用的系统中的默认 include路径:
root@xkfx:~/labs# cpp -v
// ..........................
#include "..." search starts here:
#include <...> search starts here:
/usr/lib/gcc/x86_64-linux-gnu/4.9/include
/usr/local/include
/usr/lib/gcc/x86_64-linux-gnu/4.9/include-fixed
/usr/include/x86_64-linux-gnu
/usr/include
End of search list.
14、Try running the compilation in verbose mode (-v
) to study the library-paths (-L
) and libraries (-l
) used in your system:
15、通过 file 查看文件类型:
root@xkfx:~/labs# file hello.o
hello.o: ELF -bit LSB relocatable, x86-, version (SYSV), not stripped
root@xkfx:~/labs# file a.out
a.out: ELF -bit LSB executable, x86-, version (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-.so., for GNU/Linux 2.6., BuildID[sha1]=242ba76e8db35435fd054bf0d930f6ed2ca9375c, not stripped
root@xkfx:~/labs# file hello.cpp
hello.cpp: C source, ASCII text
通过 nm 列出特性文件中的符号信息(像是函数啥的), linux中的nm命令简介 这篇文章很生动,。(附带动态链接库、静态链接库怎么操作)
通过 ldd 列出动态链接库,同一位作者 linux中的ldd命令简介
在实际linux开发与调试中, 要经常查看动态库依赖关系, ldd用得还是比较多的, 特别是出现故障的时候。OK, ldd命令就简单介绍到这里了, 虽然简单, 但很实用, 故不可不知。
16、
root@xkfx:~/labs# vim hello.c
root@xkfx:~/labs# vim makefile
root@xkfx:~/labs# ls
hello.c makefile
root@xkfx:~/labs# make
gcc -c hello.c
gcc -o hello.exe hello.o
root@xkfx:~/labs# ls
hello.c hello.exe hello.o makefile
makefile 内容:
all: hello.exe hello.exe: hello.o
gcc -o hello.exe hello.o hello.o: hello.c
gcc -c hello.c clean:
rm hello.o hello.exe
make 指令在没有目标的时候默认就是 make all .
A rule consists of 3 parts: a target, a list of pre-requisites and a command (目标,前提条件,命令), as follows:
target: pre-req- pre-req- ...
command
command 前面必须是 Tab 而不能是 Space
makefile 的内容定义了 make 指令在该目录下的行为,
例如输入 make clean , clean 是目标,没有先决条件,那么就执行命令 rm hello.o hello.exe
输入 make all ,先决条件是 hello.exe 如果没发现,那么就搜索指令去制造它。
在制造 hello.exe 的时候,会检查 hello.o 是不是“新鲜”,(大概是比较创建文档的时间?),如果“新鲜”才会制造,否则的话:
root@xkfx:~/labs# make
make: Nothing to be done for 'all'.
现在想正常跑 make,一个方法是 make clean 一下:
root@xkfx:~/labs# make clean
rm hello.o hello.exe
root@xkfx:~/labs# ls
hello.c makefile
root@xkfx:~/labs# make
gcc -c hello.c
gcc -o hello.exe hello.o
另一个方法就是让 hello.c 变“新鲜”(不用修改,打开后重新 wq保存一下就可以了。):
root@xkfx:~/labs# ls
hello.c hello.exe hello.o makefile
root@xkfx:~/labs# vim hello.c
root@xkfx:~/labs# make
gcc -c hello.c
gcc -o hello.exe hello.o
C/C++笔记 #035# Makefile的更多相关文章
- Linux 编程学习笔记----动笔makefile档
Befroe Beginning. 在设置暑假的plan ,关于Linux的书籍如今在看的是ALP和Linux高级程序设计(杨宗德)第三版.在计划中的是Linux高级环境编程. 如今開始关于Linux ...
- 《笨办法学C》笔记之Makefile
使用gcc编译C语言源码 在Linux系统中,C语言源码需要用gcc编译为二进制可执行文件,才能够运行. $ gcc test.c -o test 这句命令就将test.c文件编译为test二进制可执 ...
- [国嵌笔记][017][Makefile工程管理]
Makefile的用途 1.make能够使整个程序的编译.链接只需一个命令就可以完成 2.make的工作主要依赖于Makefile的文件.Makefile文件描述了整个程序的编译.链接等规则,使之自动 ...
- makefile笔记9 - makefile隐含规则
在我们使用 Makefile 时,有一些我们会经常使用,而且使用频率非常高的东西,比如,我们编译C/C++的源程序为中间目标文件(Unix 下是[.o]文件,Windows 下是[.obj]文件). ...
- makefile笔记10 - makefile 函数库文件
函数库文件也就是对 Object 文件(程序编译的中间文件)的打包文件.在 Unix 下,一般是由命令"ar"来完成打包工作. 一.函数库文件的成员 一个函数库文件由多个文件组成. ...
- makefile笔记7 - makefile函数
在 Makefile 中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智能. make 所支持的函数也不算很多,不过已经足够我们的操作了.函数调用后,函数的返回值可以当做变量来使用. ...
- makefile笔记6 - makefile条件判断
使用条件判断,可以让 make 根据运行时的不同情况选择不同的执行分支.条件表达式可以是比较变量的值,或是变量和常量的值. 一.示例 下面的例子,判断\(\$\)(CC)变量是否"gcc&q ...
- makefile笔记5 - makefile变量
在 Makefile 中的定义的变量,就像是 C/C++语言中的宏一样,他代表了一个文本字串,在 Makefile 中执行的时候其会自动原模原样地展开在所使用的地方.其与 C/C++所不同的是,你可以 ...
- makefile笔记4 - makefile命令
每条规则中的命令和操作系统 Shell 的命令行是一致的. make 会一按顺序一条一条的执行命令,每条命令的开头必须以[Tab]键开头,除非,命令是紧跟在依赖规则后面的分号后的. 在命令行之间中的空 ...
随机推荐
- T49
明天参加媳妇朋友的婚礼.今天晚上的火车,下班后匆忙的打了个的,正好到的哥交接班的时间拦了几辆车都不拉火车站!无奈-五分钟后打上车接上媳妇去火车站!正值五中学生放假路上各种堵!安阳这四线城市什么时候变的 ...
- html 在一个超链接上面,鼠标移动上去时,也显示一串文字,如何实现
a标签的title属性,对title属性赋值即可.例如:<a href="http://www.baidu.com/" title="跳转到百度"> ...
- eclipse 中 大小写切换:ctrl+shift+x 转为大写 ctrl+shift+y 转为小写
...............
- JDBC及Filter
JNDI容器:Java Naming Directory Interface,java命名目录接口EJB:javaEE服务器端组件模型,Enterprise JavaBean,设计目标与核心应用是建立 ...
- mongo_action
https://docs.mongodb.com/manual/introduction/ { name: "sue", age: 3, status: "A" ...
- mybatis联接查询例子
where判断如果放在最外层就是对连接查询后的结果经行筛选. SELECT * from ( and lw_area.area_id like '35%' ) la LEFT JOIN ( selec ...
- matplotlib基本使用方法
[微语]人生有可为之事,也有不可为之事.可为之事,当尽力为之,此谓尽性,不可为之事,当尽心为之,此谓知命. 三人行必有我师 官方参考API:https://matplotlib.org/tutoria ...
- opencv-Python---动态人脸捕捉
本章重点内容: 1.python写人脸识别 2.选择OpenCv框架 案例1 导入图片并打开显示 思路:1.导入库 2.加载图片 3.创建窗口 4.显示图片 5.暂停窗口 6.关闭窗口 #1.导入库 ...
- Git使用常见问题脚本
receive.denyCurrentBranch 这是由于git默认拒绝了push操作,需要进行设置,修改.git/config添加如下代码: [receive] denyCurrentBr ...
- util date 转 sql date
JAVA 处理时间 - java.sql.Date.java.util.Date与数据库中的Date字段的转换方法,以及util包下的Date类与字符串的相互转换在java环境中使用的Date时间类通 ...