我在这里和其他论坛上看到了很多问题,建议使用-static
或有时甚至使用-static -static-libgcc
以及编译参数。这在Alpine上永远无法使用,但是在Ubuntu和Fedora上可以正常使用。
我用C语言编写了一个简单的hello-world程序,然后将其编译为gcc -static test.c
。并且生成的二进制文件仍然点亮ldd
。看到
$ gcc -s test.c -static
$ ldd ./a.out
/lib/ld-musl-x86_64.so.1 (0x7f043eae8000)
$ file ./a.out
./a.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, stripped
在Ubuntu上运行相同的内容显示:
$ gcc -s test.c -static
$ file ./a.out
./a.out: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=bf6bfa1c78c541ae4e81586bcd050923bca9e34a, stripped
在任何平台上静态链接libc本身的正确且一致的方法是什么?这与GCC本身的编译方式有关吗?
答案 0 :(得分:0)
您的Ubuntu二进制文件未启用PIE。如果您将-no-pie
传递给Alpine上的GCC,则其二进制文件同样不会启用PIE,但随后会根据需要进行静态链接。
答案 1 :(得分:0)
对于那些天真的来到这里搜索static
之类的关键字的人,我在这里回答自己的问题。
如果这是用于MSVC,则唯一的选择是#include <stdio.h>
#include <stdlib.h>
#define ll long long
int main() {
ll int N;
scanf("%lld", &N); /// The plain "%d" format expects an "int" argument - use "%lld" for "long long int"
ll int i, j, a, b;
ll int TOTAL = 0; /// If you don't INITIALIZE "TOTAL" it could start off with ANY value whatsoever!
typedef struct {
ll int flag;
ll int count;
// int fc[N]; // farmer cost OR cost for farmer i
ll int* fc;
} land;
// check whether all of them have been
// initialised to 0
// printf("%d ", arr[2][2].count);
// yes
static land arr[1000][1000]; /// Without "static" this array (~ 24 Megabytes) will overflow the stack!
for (i = 0; i < 1000; i++) {
for (j = 0; j < 1000; j++) {
arr[i][j].fc = (ll int*)calloc(N, sizeof(ll int));
}
}
ll int x1, y1, x2, y2, c;
ll int ta, tb; // temp a // temp b
for (i = 0; i < N; i++) {
scanf("%lld %lld %lld %lld %lld", &x1, &y1, &x2, &y2, &c);
// the array index starts from 0
// so to match the inputs to the correct indices
// the inputs must be reduced by one
for (a = x1; a <= x2; a++) {
for (b = y1; b <= y2; b++) {
ta = a - 1;
tb = b - 1;
arr[ta][tb].count++;
if (arr[ta][tb].count >= 2)
arr[ta][tb].flag = 1;
arr[ta][tb].fc[i] = c;
}
}
}
ll int k;
for (i = 0; i < 1000; i++) {
for (j = 0; j < 1000; j++) {
if (arr[i][j].flag == 1) {
for (k = 0; k < N; k++)
TOTAL += arr[i][j].fc[k];
}
}
}
printf("%lld", TOTAL);
return 0;
}
或static link libc
。但是,如果您是来这里寻找GCC的,欢迎来到位置独立的代码兔子洞。
有一些GCC浮动版本,它们针对特定目标进行了修补,或者只是因为可以被修补。因此,如果您拥有GCC 6.0版,并且希望您的命令行参数生成相同的行为,那么您可能会成为某些不良补丁程序的受害者。
此问题中的某些版本的GCC强制执行位置无关的可执行文件(/MT
),并且无声地忽略了/MTd
选项,如本示例所示。我想知道是否应该向Alpine维护人员报告此错误。要强制其忽略PIE,请将-fPIE -pie
传递到您的GCC。
-static
如果可以的话
-no-pie
有关$ gcc -no-pie -static test.c
和$ file ./a.out
/lib/ld-musl-x86_64.so.1: ./a.out: Not a valid dynamic program
如何从OpenBSD读取这些slides的详细信息。
答案 2 :(得分:0)
您可能构建得很好,它看起来更像是 file
中的错误。请参阅此错误报告:
https://bugs.astron.com/view.php?id=93
摘要:0000093:文件错误地识别了 -static-pie 二进制文件
我在构建 QEMU 时遇到了同样的问题,但我被告知上述内容: https://gitlab.alpinelinux.org/alpine/aports/-/merge_requests/21214#note_156907