背景:我正在考虑在 Gentoo Linux 中开发一个类似于 portage 的包管理器(我最终可能会 fork portage)。对于那些对 Gentoo 知之甚少的人来说,它是一个基于源代码的发行版,这意味着所有包都是从源代码编译的。目前可以将程序编译成目标文件,然后编译成可执行文件。
$ gcc -c a.c -o a.o
$ gcc -c b.c -o b.o
$ gcc a.o b.o -o executable
Run Code Online (Sandbox Code Playgroud)
我想对 portage 进行的改进如下。
推理:我是一名 Arch Linux 用户,喜欢基于源代码的发行版的想法,但无法为保持系统最新的艰巨任务而烦恼。我的大部分工作也是在带有小型硬盘驱动器的笔记本电脑上完成的,因此将可执行文件反编译/取消链接到目标文件而不是仅仅保留占用大量空间的目标文件。它还可能减少系统的整体编译时间,因为重新编译大部分源代码的需要将大大减少。它还允许一种简单的方法来更改包上的 USE 标志,而无需完全重新编译。
问题:是否可以将目标文件编译为可执行文件,然后反编译回目标文件。下面是一个例子。
$ gcc -c a.c -o a.o
$ gcc -c b.c -o b.o
$ gcc a.o b.o -o executable
Run Code Online (Sandbox Code Playgroud)
进而
$ SomeCommand executable
output << a.o b.o
Run Code Online (Sandbox Code Playgroud)
如果目前无法做到这一点。是否可以修改 GNU 链接器“ $ld”的一个版本来记录链接目标文件时所做的更改,从而故意使程序“可逆向工程”??? …
考虑下面的代码片段,显示一些简单的算术运算
int result = 0;
result = c * (a + b) + d * (a + b) + e;
Run Code Online (Sandbox Code Playgroud)
要在上面的表达式中获得结果,cpu将需要执行两次整数乘法和三次整数加法.但是在代数上,上面的表达式可以简化为下面的代码.
result = (c + d) * (a + b) + e
Run Code Online (Sandbox Code Playgroud)
这两个表达式在代数上是相同的,但第二个表达式只包含一个乘法和三个加法.gcc(或其他编译器)是否能够自己进行这种简单的优化.
现在假设编译器足够智能以进行这种简单的优化,它是否能够优化更复杂的东西,例如梯形规则(用于数值积分).下面的实施例近似下的面积sin(x),其中0 <= x <= pi与pi/4的(小为简单起见)的一个步长大小.请假设所有文字都是运行时变量.
#include <math.h>
// Please assume all literals are runtime variables. Have done it this way to
// simplify the code.
double integral = 0.5 * ((sin(0) + sin(M_PI/4) * (M_PI/4 - 0) + (sin(M_PI/4) +
sin(M_PI/2)) …Run Code Online (Sandbox Code Playgroud) 我遇到了一个我无法理解的奇怪的编译错误。首先,错误将函数引用为该函数,就好像该函数位于匿名名称空间中一样,但实际上是在内部namespace database。其次,“已使用但从未定义”语句表明编译要求我从头文件中定义函数。该函数实际上是在单独的实现文件中声明的。但是该函数既不是静态的也不是内联的,所以我对为什么它需要在标头中定义感到困惑。这段代码是严格符合要求的,因此我已经使用二者进行了编译-Wall -Werror。我还提供了源代码的简化版本以进行说明。
注意:此问题与此处提出的其他类似问题不同,因为它不涉及静态或内联函数。
错误:
In file included from src/main.cpp:6:0:
include/database.hpp:19:6: error: 'void {anonymous}::SetupSettings()' used but never defined [-Werror]
void SetupSettings();
^
cc1plus.exe: all warnings being treated as errors
Run Code Online (Sandbox Code Playgroud)
main.cpp
#include <iostream>
#include "config.hpp"
#include "database.hpp"
int main() {
database::SetupSettings();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
数据库.hpp
#ifndef database
#define database
#include <iostream>
#include "config.hpp"
#include "sqlite/sqlite3.h"
namespace database {
extern sqlite3* settings_database;
void SetupSettings();
// ^^ Apparent warning here.
} // namespace database
#endif
Run Code Online (Sandbox Code Playgroud)
database.cpp:
#include <iostream> …Run Code Online (Sandbox Code Playgroud)