如何在 Linux 下安装 NiCad 代码查重工具
Pulsar2021 · · 科技·工程
前言
如果在网上查找 “如何安装 NiCad”,我们会发现详细说明的文章极其稀少,甚至搜索引擎第一篇文章是这么说的:
NiCad适用于 Linux, Mac OS X, Cygwin and MinGW 等环境。本人尝试过在VMware中通过Ubuntu来使用NiCad,可是出现了以下错误,无法解决,因此改用在windows安装Cygwin来实现NiCad的使用。
tpc -mUNIX64 -DHUGE -O -A -q4 cloneclasses.t make: tpc: Command not found Makefile:40:recipe for target 'cloneclasses.c' failed make: *** [cloneclasses.c] Error 127[原文如此]
这个说法是不准确的。
因此,这篇文章特来说明如何在 Linux 下安装 NiCad。
本文所有操作均在 WSL Ubuntu 24.04.2 LTS 与 x64 环境下进行,但理论上可以在绝大部分 Linux 发行版中运行。如果报错,请检查是否缺少必要的组件并检查网络环境。
本文假设读者已经掌握基本的 Linux 命令行操作。
安装 FreeTxl
FreeTxl 是 NiCad 编译的必要依赖。
打开 Txl 下载网站,在 “Choose Your Platform” 处选择 “Linux x86 (64 bit) for Ubuntu, Debian, Fedora, Red Hat, CentOS, Mageia gcc 4.8 or later”,并在下方点击 “I Agree”,在跳转的界面点击 “You may begin downloading the software by clicking here” 开始下载,随后将压缩包放置在合适的地方。
以后所有操作均假定读者将所需文件放置在了工作目录下。
执行以下命令:
$ tar xvzf 23567-txl10.8b.linux64.tar.gz
$ cd txl10.8b.linux64
$ sudo ./InstallTxl
Installing TXL 10.8b on your system.
Installing TXL commands into /usr/local/bin
Installing TXL library into /usr/local/lib/txl
Installing TXL manual entries into /usr/local/man/man1
Testing TXL
TXL v10.8b (13.7.22) (c) 1988-2022 Queen's University at Kingston
Compiling question.txl ...
Parsing ultimate.question ...
Transforming ...
42
Done.
压缩包和目录的名称可能不同,请注意辨别。
完成以上操作后,我们成功安装了 Txl。
安装 NiCad
打开 NiCad 下载网站,选择 “NiCad6, v6.2 for Linux, Mac OS X, Cygwin and MinGW”,随后同样点击 “I Agree” 下载并移动至工作目录。
随后执行以下命令:
tar xvzf 7492-NiCad-6.2.tar.gz
cd NiCad-6.2
make
这时可能会出现以下一种情况,也就是前言所述的问题:
$ make # . . . tpc -mUNIX64 -DHUGE -O -A -q4 cloneclasses.t make[1]: tpc: 没有那个文件或目录 make[1]: *** [Makefile:43:cloneclasses.c] 错误 127 # . . . $ ./nicad6 NiCad Clone Detector v6.2 (13.11.20) *** Error: Missing ./tools/clonepairs.x - type 'make' to make the NiCad tools这种情况可能由于两种原因产生:
下载的安装包中没有预先从 Turing Plus 语言编译的 C 语言文件;
在
tools文件夹执行了make reset。你可以尝试重新解压并编译,如果问题仍然出现,请按照以下指示安装 tpc 编译器。
打开
tools/cloneclasses.t,我们可以看到以下文字:% NiCad 3.0 clone pair clustering % J.R. Cordy, January 2012 % Copyright 2012 J.R. Cordy % Version 2.0 (3 Dec 2015) % Changed to n*log n clustering algorithm - JRC 19.11.15 % Updated max clone pairs to handle bigger experiments - JRC 3.12.15 % This program requires the Turing Plus 2009 compiler, % http://research.cs.queensu.ca/~stl/download/pub/tplus/这指引我们安装 tpc 编译器,但是,注释中的网址已经无法打开。
在网上搜索 “Turing Plus 2009 compiler”,可以找到这个仓库。
从这里下载最新 release 并像之前一样解压并进入解压后的文件夹,随后运行
./InstallTplus.sh现在,tpc 编译器已经成功安装,我们重新编译会出现这个错误:
gcc -w -O -I . -o cloneclasses.x main.c TLI.c TLS.c cloneclasses.c cloneclasses.c:1:10: 致命错误:UNIX64/cinterface.h:No such file or directory 1 | #include <UNIX64/cinterface.h> | ^~~~~~~~~~~~~~~~~~~~~ 编译中断。这是因为 UNIX64 文件夹下只有
cinterface文件,没有cinterface.h。我们需要手动为它创建链接:
cd tools/UNIX64 ln -s cinterface cinterface.h cd ../..此时,便可以正常编译。
如此,我们成功编译了 NiCad。
运行 & 测试
我们使用两份测试代码进行查重测试:
第一份:[~/nc-c/1.c]
#include <stdio.h>
void bubble_sort(int arr[], int n) {
for (int i = 0; i < n-1; i++) {
for (int j = 0; j < n-i-1; j++) {
if (arr[j] > arr[j+1]) {
int temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
int binary_search(int arr[], int left, int right, int target) {
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid] == target) return mid;
if (arr[mid] < target) left = mid + 1;
else right = mid - 1;
}
return -1;
}
void print_array(int arr[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
int main() {
int data[] = {64, 34, 25, 12, 22, 11, 90};
int size = sizeof(data)/sizeof(data[0]);
printf("Original array: ");
print_array(data, size);
bubble_sort(data, size);
printf("Sorted array: ");
print_array(data, size);
int target = 22;
int result = binary_search(data, 0, size-1, target);
printf("Element %d is at index %d\n", target, result);
return 0;
}
第二份:[~/nc-t/2.c]
#include <stdio.h>
void sort_array(int numbers[], int count) {
for (int pass = 0; pass < count-1; pass++) {
for (int pos = 0; pos < count-pass-1; pos++) {
if (numbers[pos] > numbers[pos+1]) {
int tmp = numbers[pos];
numbers[pos] = numbers[pos+1];
numbers[pos+1] = tmp;
}
}
}
}
int find_element(int array[], int start, int end, int key) {
while (start <= end) {
int middle = start + (end - start) / 2;
if (array[middle] == key) return middle;
if (array[middle] < key) start = middle + 1;
else end = middle - 1;
}
return -1;
}
void display_array(int values[], int length) {
for (int i = 0; i < length; i++) {
printf("%d ", values[i]);
}
putchar('\n');
}
int main(void) {
int dataset[] = {64, 34, 25, 12, 22, 11, 90};
int n = sizeof(dataset)/sizeof(dataset[0]);
printf("Initial array: ");
display_array(dataset, n);
sort_array(dataset, n);
printf("Array after sorting: ");
display_array(dataset, n);
int search_key = 22;
int index = find_element(dataset, 0, n-1, search_key);
printf("Value %d found at position %d\n", search_key, index);
return 0;
}
我们运行以下命令:
$ ./nicad6 functions c ~/nc-t
# . . .
Done.
Detailed log in /root/nc-t_functions-clones-2025-07-12-14:43:24.log
Results in /root/nc-t_functions-blind-clones/
Report in /root/nc-t_functions-blind-clones/nc-t_functions-blind-clones-0.30-classes-withsource.html
打开 /root/nc-t_functions-blind-clones/nc-t_functions-blind-clones-0.30-classes-withsource.html ,NiCad 成功检测出了 3 个相似点:
PS:如果要再次检测,需要把整个结果文件夹删除后重新运行,否则可能会导致结果不更新。(被这个问题硬控 20 分钟 T_T)
自此,我们成功安装并测试运行了 NiCad 代码查重工具。