You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

引入inc子目录rsa.h至src源文件时Make编译报错求助

编译时无法找到头文件rsa.h的问题解决

问题现象

编译src目录下的rsa.c时,出现如下致命错误:

rsa.c:12:10: fatal error: rsa.h: No such file or directory
   12 | #include "rsa.h" /**/
      |          ^~~~~~~
compilation terminated.

当前使用的Makefile

#Compiling instructions
CC = gcc
CFLAGS = -Wall -Werror -ansi -I../inc

#Directories
SRC_DIR = src
OBJ_DIR = build
EXE_DIR = src
TARGET = rsa
SRCS = $(wildcard $(SRC_DIR)/*.c)
OBJS = $(patsubst $(SRC_DIR)/$.c, $S(OBJ_DIR)/%.o, $(SRCS))


$(TARGET): $(OBJS)
$(CC) $(CFLAGS) $^ -O $@

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
    $(CC) $(CFLAGS) -c $< -o $@

$(OBJ_DIR):
    mkdir -p $(OBJ_DIR)

clean:
    rm -rf$(OBJ_DIR) $(TARGET)

rsa.c代码片段

* 09-05-24
*
*/


#include <stdio.h> /*printf(), scanf()*/
#include <stdlib.h> /*srand(), rand()*/
#include <time.h> /*time()*/
#include "rsa.h" /**/


/*Function checks whether num is prime*/
int isprime(int num){
    if (num <= 1){
        /* 0 and 1 are not prime*/
        return 0;
    }
    int i;
    for (i = 2; i * i <= num; i++){
        if (num % i == 0){
            /*For num divisible by any number other than 1 or itself, not prime*/
            return 0;
        }
    }
    return 1;
}

/*Function generates two random primes and return them in an array, p then q*/
int* getpandq(void){
    static int primes[2];
srand(time(NULL));

    int num1, num2;
    do {
        num1 = rand() % 100 + 2;
    } while (!isprime(num1));

    do {
        num2 = rand() % 100 + 2;
    } while (!isprime(num2) || num2 == num1);

    primes[0] = num1;
    primes[1] = num2;

    return primes;

}

/*Calculate the product of two prime nbumbers p and q*/
int getn(int p, int q){
    return p * q;
}

/*Returns the greatest common divisor (gcd) of two integers a and b.
* Function uses the Euclidean algorithm
*/
int gcd(int a, int b){
    int temp;
    while (b != 0){
        temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

/*Calculate the lambda function (LCM of p and q)*/
int getlambda(int p, int q){
    int gcdValue = gcd(p - 1, q - 1);
    int lcmValue = ((p - 1) * (q - 1)) / gcdValue;
    return lcmValue;  
}

/*Set the value of e*/
int gete(int l){
    int e = 17;
    if (gcd(e, l) != 1){
        int i;
        for (i = 2; i < l; i++){
            if (gcd(i, l) == 1){
                e = i;
                break;
            }
        }
    }
    return e;
}

/*Function to calculate the private key d from e and lambda (l) */
int getd(int e, int l){
    int d = 0;
    while (((d * e) % 1) != 1){
        d++;
    }
    return d;
}

/*key generation main function*/
struct KeyPair getkeys(void){
    int* primes = getpandq();
    int p = primes[0];
    int q = primes[1];

    int n = getn(p, q);
    int l = getlambda(p, q);
    int e = gete(l);
    int d = getd(e, l);

    struct KeyPair keys;
    keys.e = e;
    keys.n = n;
    keys.d = d;

    return keys;
}

/*Convert the message M into the "padded" integer*/
int pad(char M[]){
    int i = 0;
    int paddedInt = 0;

    while (M[i] != '\0'){
        paddedInt = (paddedInt << 8) | M[i];
        i++;
    }
    return paddedInt;
}

/*convert integer m into meesage M*/
char unpad(int c){
    int size = sizeof(int);
    int i;
    char *message = malloc(size + 1);
    
    for (i = 0; i < size; i++){
        message[i] = (c >> (8 * (size + 1))) & 0xFF;
    }
    message[size] = '\0';
    
    return message;
}

/*Return the encrypted integer c*/

int enc(int n, char M[], struct KeyPair keys) {
    int paddedInt = pad(M);
    int encrytpedInt = 1;

    int i;
    for (i = 0; i < keys.e; i++){
        encrytpedInt = (encrytpedInt * paddedInt) % n;
    }
    return encrytpedInt;
}

int modExp( int base, int exp, int mod){
    long long result = 1;

    base %= mod;

    if (exp == 0) return 1;

    while (exp > 0){
        if (exp % 2 == 1){
            result = (result * base ) % mod;
        }
        exp /= 2;
        base = (base * base) % mod;
    }

    return (int)((result + mod) % mod);
}

char  dec(int d, int n, int c){
    int decryptedInt = modExp(c, d, n);

    int size = sizeof(int);
    char *message = malloc(size + 1);

    int i;
    for (i = 0; i < size; i++){
        message[i] = (decryptedInt >> (8 * (size - 1 - 1))) & 0xFF;
    } 
    message[size] = '\0';

    return message;
}

之前使用的Makefile版本

# Compiling instructions
CC=gcc
CFLAGS=-Wall -Werror -ansi

# Directories
SRC_DIR=./src/
OBJ_DIR=./build/
EXE_DIR=./build/
SRC_FILE=$(SRC_DIR)main.c
OBJ_FILE=$(OBJ_DIR)$(notdir $(SRC_FILE:.c=.o))
EXE_FILE=$(EXE_DIR)main

# Default target
all: $(OBJ_DIR) $(EXE_FILE)

# Ensure the object directory exists
$(OBJ_DIR):
    mkdir -p $(OBJ_DIR)

# Compilation and Linking rule
$(EXE_FILE): $(OBJ_FILE)
    $(CC) $(CFLAGS) $< -o $@

# Compile to object file
$(OBJ_FILE): $(SRC_FILE)
    $(CC) $(CFLAGS) -c $< -o $@

# Deletes previous build so only current build is accessible
clean:
    rm -rf $(OBJ_DIR)

# Phony targets
.PHONY: all clean

解决步骤

1. 修正头文件搜索路径

先明确项目目录结构:

  • 如果Makefile放在项目根目录(根目录下包含inc/、src/、build/),CFLAGS中的头文件搜索路径应改为-Iinc,而非-I../inc——../inc会指向根目录的上级目录,自然找不到目标文件。
  • 如果Makefile放在src目录下,-I../inc是正确的,但运行make时需确保工作目录为src目录。

2. 修复Makefile中的语法错误

当前Makefile存在3处语法错误:

  • OBJS行中,$(SRC_DIR)/$.c应改为$(SRC_DIR)/%.c,$S(OBJ_DIR)应改为$(OBJ_DIR),正确写法:
    OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRCS))
    
  • 链接规则中的-O是优化参数,此处需用-o指定输出目标文件,正确写法:
    $(TARGET): $(OBJS)
        $(CC) $(CFLAGS) $^ -o $@
    
  • clean规则中rm -rf$(OBJ_DIR)缺少空格,会导致命令执行错误,修正为:
    clean:
        rm -rf $(OBJ_DIR) $(TARGET)
    

3. 修正后的完整Makefile示例(假设Makefile在项目根目录)

# Compiling instructions
CC = gcc
CFLAGS = -Wall -Werror -ansi -Iinc

# Directories
SRC_DIR = src
OBJ_DIR = build
TARGET = rsa
SRCS = $(wildcard $(SRC_DIR)/*.c)
OBJS = $(patsubst $(SRC_DIR)/%.c, $(OBJ_DIR)/%.o, $(SRCS))

$(TARGET): $(OBJS)
	$(CC) $(CFLAGS) $^ -o $@

$(OBJ_DIR)/%.o: $(SRC_DIR)/%.c | $(OBJ_DIR)
	$(CC) $(CFLAGS) -c $< -o $@

$(OBJ_DIR):
	mkdir -p $(OBJ_DIR)

clean:
	rm -rf $(OBJ_DIR) $(TARGET)

.PHONY: clean

4. 额外注意事项

rsa.c中存在类型不匹配问题:unpad和dec函数声明返回char,但实际返回的是char*(动态分配的字符串),这会导致编译警告或错误,建议修正函数返回类型为char*。


内容的提问来源于stack exchange,提问作者9_daytona

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 15:29:49