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

C Compilation error in Make but not GCC/G++

我刚刚开始尝试使用 C,但在使用 Make(在 Ubuntu 14.04.2)从命令行编译一个简单的单文件应用程序时遇到了问题。我已经包含了 math.h,但是使用 Make 时 ceilsqrt 等方法是 'undefined'。似乎 Make 不能 link math.h 库,但 GCC/G++ 似乎做得很好。这是怎么回事?

C代码在示例中-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 现在可以在终端上运行了。

时,compile/link 序列的 link 步骤需要被告知 '-lm'(小写 'L')
#include <math.h> 

在源代码中。

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