如何在Ubuntu系统上编译面向FreeBSD开发的程序?
Ubuntu环境编译hpsat_generate解决方案
问题根因
- 项目原生面向FreeBSD开发,配套Makefile遵循BSD make语法,Ubuntu默认带的GNU make无法解析该语法,会触发
*** missing separator. Stop.报错 - 代码中调用的
mergesort()是FreeBSD C库内置的扩展函数,Ubuntu默认使用的GNU C库未提供该接口,即使用BSD版本的bmake执行编译,也会触发函数未声明错误
操作步骤(无需额外安装BSD编译链,适配原生GNU编译环境)
- 先安装项目依赖的GMP开发库
sudo apt update && sudo apt install libgmp-dev libgmpxx-dev build-essential
- 在项目根目录新建
mergesort_compat.h头文件,写入mergesort的兼容实现,补全glibc缺失的接口:
#ifndef MERGESORT_COMPAT_H #define MERGESORT_COMPAT_H #include <stdlib.h> #include <string.h> #include <stddef.h> #define min(a,b) ((a)<(b)?(a):(b)) static int mergesort(void *base, size_t nmemb, size_t size, int (*cmp)(const void *, const void *)) { char *tmpbuf, *a, *b, *c, *dst; size_t i, j, k, n; if (nmemb <= 1) return 0; tmpbuf = malloc(nmemb * size); if (!tmpbuf) return -1; for (n = 1; n < nmemb; n *= 2) { for (i = 0; i < nmemb; i += 2*n) { a = (char *)base + i*size; b = (char *)base + (i+n < nmemb ? (i+n)*size : nmemb*size); c = (char *)base + min(i+2*n, nmemb)*size; dst = tmpbuf; j = k = 0; while (a + j*size < b && b + k*size < c) { if (cmp(a + j*size, b + k*size) <= 0) { memcpy(dst, a + j*size, size); j++; } else { memcpy(dst, b + k*size, size); k++; } dst += size; } while (a + j*size < b) { memcpy(dst, a + j*size, size); j++; dst += size; } while (b + k*size < c) { memcpy(dst, b + k*size, size); k++; dst += size; } memcpy(a, tmpbuf, dst - tmpbuf); } } free(tmpbuf); return 0; } #endif
- 打开项目根目录下的
hpsat_generate.cpp,在所有头文件#include语句的最前面添加一行引用兼容头的代码:
#include "mergesort_compat.h"
- 删除原项目自带的BSD格式Makefile,新建GNU make兼容的Makefile,写入以下内容:
CXX ?= g++ PREFIX ?= /usr/local TARGET = hpsat_generate SRCS = hpsat_generate.cpp CXXFLAGS += -I$(PREFIX)/include LDFLAGS += -L$(PREFIX)/lib -lgmp -lgmpxx ifeq ($(HAVE_DEBUG),1) CXXFLAGS += -g -O0 else CXXFLAGS += -O2 endif all: $(TARGET) $(TARGET): $(SRCS) mergesort_compat.h $(CXX) $(CXXFLAGS) $(SRCS) -o $(TARGET) $(LDFLAGS) install: $(TARGET) install -d $(DESTDIR)$(PREFIX)/bin install -m 755 $(TARGET) $(DESTDIR)$(PREFIX)/bin/ clean: rm -f $(TARGET)
注意:Makefile中缩进的行必须使用Tab键缩进,不能用空格,否则会触发分隔符错误
5. 执行编译命令
- 常规发行版编译直接执行
make即可 - 需要编译带调试符号的版本执行
make HAVE_DEBUG=1 - 编译完成后执行
sudo make install即可将二进制安装到/usr/local/bin路径下
内容的提问来源于stack exchange,提问作者matan Pleblist
相关产品推荐
相关产品推荐

