引入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
相关产品推荐
相关产品推荐

