Make 中的 C 编译错误,但不是 GCC/G++

标签 c gcc makefile

我刚刚开始尝试使用 C,但在使用 Make(在 Ubuntu 14.04.2 上)从命令行编译一个简单的单文件应用程序时遇到了问题。我已经包括了 math.h,但是像 ceilsqrt 这样的方法在使用 Make 时是“未定义的”。似乎 Make 无法链接 math.h 库,但 GCC/G++ 似乎做得很好。这是怎么回事?

C 代码在 sample-fail.c 中:

#include <stdio.h>
#include <math.h>
#include <limits.h>

double sqrt(double x);
double ceil(double x);

//Checks if an array contains any values that evenly divide 'val'
int array_contains_divisor(int arr[], int len, int val)
{
    int i;

    for(i = 0; i < len; i++)
    {
        if(val % arr[i] == 0)
        {
            return 1;
        }
    }

    return 0;
}

//Finds the largest prime factor of 'value'. Returns -1 if the number is
//prime, 0 if invalid
int largest_prime_factor(long value)
{
    //1 and 0 are not prime, this function does not expect negatives
    //so anything less than 1 is an invalid value
    if( value <= 1L )
    {
        return 0;
    }

    double val = (double)value;

    double d_max = ceil( sqrt( val ) );

    if( d_max > INT_MAX )
    {
        //value is invalid because its square root exceeds the maximum 
        //capacity of an int (defined in limits.h)
        return 0;
    }

    int max = (int)d_max;

    int prime_len = (int)( d_max / 2 ) + 1;

    int primes[prime_len];

    int primes_curr_pos = 0;

    int i;

    for(i = 9; i < max; i+=2)
    {
        //check if it's a factor
        if( value % i != 0 )
        {
            continue;
        }

        //basic prime check - should be no need to check 2 because we
        //are skipping all the even numbers
        if( i % 3 == 0 || i % 5 == 0 || i % 7 == 0 )
        {
            continue;
        }

        //complete prime check (not including 2, 3, 5 and 7)
        if( array_contains_divisor( primes, primes_curr_pos, i ) )
        {
            continue;
        }

        primes[primes_curr_pos++] = i;
    }

    //if we've found no prime divisors, check the remaining primes
    //we skipped earlier.
    if( primes_curr_pos <= 0 )
    {
        if( value % 7 == 0)
        {
            primes[primes_curr_pos++] = 7;
        }
        else if( value % 5 == 0 )
        {
            primes[primes_curr_pos++] = 5;
        }
        else if( value % 3 == 0 )
        {
            primes[primes_curr_pos++] = 3;
        }
        else if( value % 2 == 0 )
        {
            primes[primes_curr_pos++] = 3;
        }
    }

    if( primes_curr_pos <= 0 )
    {
        //the value is prime, return -1;
        return -1;
    }
    else
    {
        return primes[primes_curr_pos - 1];
    }
}

int main(int argc, char *argv[])
{
    printf("The largest prime factor of 600851475143 is %d\n", 
        largest_prime_factor(600851475143));

    return 0;
}

这是尝试使用 Make 编译 sample_fail.c,然后使用 GCC/G++ 的终端输出(我只是复制了我看到 Code::Blocks 构建器为 GCC/G++ 命令执行的步骤):

x@x-desktop:~/Documents/Random Scripts$ ./sample_fail
bash: ./sample_fail: No such file or directory
x@x-desktop:~/Documents/Random Scripts$ make sample_fail
cc     sample_fail.c   -o sample_fail
/tmp/ccGCCT0E.o: In function `largest_prime_factor':
sample_fail.c:(.text+0x98): undefined reference to `sqrt'
sample_fail.c:(.text+0xaf): undefined reference to `ceil'
collect2: error: ld returned 1 exit status
make: *** [sample_fail] Error 1
x@x-desktop:~/Documents/Random Scripts$ gcc -Wall -c sample_fail.c
x@x-desktop:~/Documents/Random Scripts$ g++ -o ./sample_fail ./sample_fail.o
x@x-desktop:~/Documents/Random Scripts$ ./sample_fail
The largest prime factor of 600851475143 is 6857
x@x-desktop:~/Documents/Random Scripts$ 

在此先感谢您对这位 C 语言新手的帮助。

解决方案(由 user3629249 和 Useless 提供):

将我的 Makefile 更新为:

CFLAGS=-Wall -g
CC=gcc

sample_fail: sample_fail.c
    gcc -o sample_fail sample_fail.c -lm

clean:
    rm -f sample_fail

make sample_fail 现在可以在终端上运行。

最佳答案

编译/链接序列的链接步骤需要被告知'-lm'(小写'L')时

#include <math.h> 

在源代码中。

注意 ceil() 和 sqrt() 原型(prototype)是在 math.h 中定义的,因此不应在源代码中覆盖这些原型(prototype)。

关于Make 中的 C 编译错误,但不是 GCC/G++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30074834/

相关文章:

c++ - 在使用 git 的企业 C++ 项目中管理 Makefile

可以让 "target"带参数吗?

CHAR_WIDTH 未声明

c - 我自己写了一个http服务器,我想通过这个服务器执行一个cgi脚本。但我不知道该怎么做

c - C99 标准是否允许编译器转换代码,以便在满足某些推导条件后不再评估相同的表达式?

C 编译器 : "Types ' char *' and ' int' are not assignment-compatible"- but there's no int?

c - 如何在编译器中添加新的头文件位置

c++ - 使用 gcc 进行自动矢量化?

static - 根据目标依赖关系使目标包含子目录

c - 确保在编译时初始化固定大小数组的所有元素