相关资料:

实践记录:

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的更多相关文章

  1. Linux 编程学习笔记----动笔makefile档

    Befroe Beginning. 在设置暑假的plan ,关于Linux的书籍如今在看的是ALP和Linux高级程序设计(杨宗德)第三版.在计划中的是Linux高级环境编程. 如今開始关于Linux ...

  2. 《笨办法学C》笔记之Makefile

    使用gcc编译C语言源码 在Linux系统中,C语言源码需要用gcc编译为二进制可执行文件,才能够运行. $ gcc test.c -o test 这句命令就将test.c文件编译为test二进制可执 ...

  3. [国嵌笔记][017][Makefile工程管理]

    Makefile的用途 1.make能够使整个程序的编译.链接只需一个命令就可以完成 2.make的工作主要依赖于Makefile的文件.Makefile文件描述了整个程序的编译.链接等规则,使之自动 ...

  4. makefile笔记9 - makefile隐含规则

    在我们使用 Makefile 时,有一些我们会经常使用,而且使用频率非常高的东西,比如,我们编译C/C++的源程序为中间目标文件(Unix 下是[.o]文件,Windows 下是[.obj]文件). ...

  5. makefile笔记10 - makefile 函数库文件

    函数库文件也就是对 Object 文件(程序编译的中间文件)的打包文件.在 Unix 下,一般是由命令"ar"来完成打包工作. 一.函数库文件的成员 一个函数库文件由多个文件组成. ...

  6. makefile笔记7 - makefile函数

    在 Makefile 中可以使用函数来处理变量,从而让我们的命令或是规则更为的灵活和具有智能. make 所支持的函数也不算很多,不过已经足够我们的操作了.函数调用后,函数的返回值可以当做变量来使用. ...

  7. makefile笔记6 - makefile条件判断

    使用条件判断,可以让 make 根据运行时的不同情况选择不同的执行分支.条件表达式可以是比较变量的值,或是变量和常量的值. 一.示例 下面的例子,判断\(\$\)(CC)变量是否"gcc&q ...

  8. makefile笔记5 - makefile变量

    在 Makefile 中的定义的变量,就像是 C/C++语言中的宏一样,他代表了一个文本字串,在 Makefile 中执行的时候其会自动原模原样地展开在所使用的地方.其与 C/C++所不同的是,你可以 ...

  9. makefile笔记4 - makefile命令

    每条规则中的命令和操作系统 Shell 的命令行是一致的. make 会一按顺序一条一条的执行命令,每条命令的开头必须以[Tab]键开头,除非,命令是紧跟在依赖规则后面的分号后的. 在命令行之间中的空 ...

随机推荐

  1. [CentOS_7.4]Linux安装与网络配置

    一 安装 官网下载ISO安装文件:https://www.centos.org/download/ 然后自行安装. 二 配置网络 a.配置动态ip 1 2 3 1)# vi /etc/sysconfi ...

  2. 2018C语言第二次作业

    一.学习内容总结 1.指针是一种数据类型,同样占有空间,其存储的是内存地址: 2.定义指针变量要在变量名之前加“*”字符表示: 3.“&”是取地址运算符,“*”是间接运算符: (注:声名和使用 ...

  3. 每日定时收集MySQL日志并发送邮件

    本次脚本系统版本 MySQL日常运行产生的慢查询日志收集并且发送邮件 vim mysql-slow-log.sh # 这是一个收集慢查询的脚本,每天收集MySQL慢查询日志并且发送邮件#!/bin/b ...

  4. Docker 学习应用篇之二: Docker的介绍和安装

    之前说过Docker的好处,Docker可以集装箱化的部署应用程序.那么Docker是通过什么实现的呢.要理解Docker内部构建,需要先理解Docker的四种部件 1)images:镜像,docke ...

  5. ubuntu下安装opencv3.1.0

    ubuntu14.04安装opencv3.1 1.下载opencv3.1源码http://opencv.org/releases.html 2.安装opencv3 2.1安装opencv3的依赖 1 ...

  6. 推荐系统之余弦相似度的Spark实现

    推荐系统之余弦相似度的Spark实现 (1)原理分析    余弦相似度度量是相似度度量中最常用的度量关系,从程序分析中, 第一步是数据的输入, 其次是使用相似性度量公式 最后是对不同用户的递归计算. ...

  7. codeforces 355C - Vasya and Robot

    因为在允许的情况下,必然是左右手交替进行,这样不会增加多余的无谓的能量. 然后根据不同的分界点,肯定会产生左手或右手重复使用的情况,这是就要加上Qr/Ql * 次数. 一开始的想法,很直接,枚举每个分 ...

  8. POJ - 1088 滑雪 dp

    http://bailian.openjudge.cn/practice/1088?lang=en_US 题解: 设一个dp[N][N]数组代表从(i,j)坐标开始能滑到的最远距离.更新的方法为 遍历 ...

  9. Why should we typedef a struct so often in C? - Stack Overflow

    https://stackoverflow.com/questions/252780/why-should-we-typedef-a-struct-so-often-in-c As Greg Hewg ...

  10. Databases: MySQL tRIGger--chinese character-set php

    DELIMITER |create TRIGGER tr_calllog_insert after insert on messagescalllog for each row beginIF mes ...