簡體   English   中英

Meson未定義對用戶定義函數的引用

[英]Meson Undefined reference to user defined function

我試圖使用介子的單元測試,並且得到:

ϰ  ninja
[4/4] Linking target test/crypto/crypto_tests.
FAILED: test/crypto/crypto_tests 
clang++-6.0  -o test/crypto/crypto_tests 'test/crypto/test@crypto@@crypto_tests@exe/.._.._src_platform_encoding_Endian.c.o' 'test/crypto/test@crypto@@crypto_tests@exe/.._.._src_crypto_Sha1.c.o' 'test/crypto/test@crypto@@crypto_tests@exe/Sha1Tests.cpp.o' 'test/crypto/test@crypto@@crypto_tests@exe/.._.._subprojects_googletest-release-1.8.0_googletest_src_gtest-all.cc.o' 'test/crypto/test@crypto@@crypto_tests@exe/.._.._subprojects_googletest-release-1.8.0_googletest_src_gtest_main.cc.o' -Wl,--no-undefined -Wl,--as-needed -pthread  
    test/crypto/test@crypto@@crypto_tests@exe/Sha1Tests.cpp.o: In function `sha_one_hash_simple_Test::TestBody()':
    /home/kfc/molten/magma/builddir/../test/crypto/Sha1Tests.cpp:46: undefined reference to `br_sha1_init(br_sha1_context*)'
    /home/kfc/molten/magma/builddir/../test/crypto/Sha1Tests.cpp:47: undefined reference to `br_sha1_update(br_sha1_context*, void const*, unsigned long)'
    /home/kfc/ecoan/molten/magma/builddir/../test/crypto/Sha1Tests.cpp:48: undefined reference to `br_sha1_out(br_sha1_context const*, void*)'
    clang: error: linker command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.

但是我已經在Sha1.h中定義了這些功能:

#ifndef _CRYPTO_SHA1_H
#define _CRYPTO_SHA1_H

#include <stddef.h>
#include <string.h>

#include "../BuildSwitches.h"
#include "../types/BaseTypes.h"

/**
 * Symbolic identifier for SHA-1.
 */
#define br_sha1_ID     2
/**
 * SHA-1 output size (in bytes).
 */
#define br_sha1_SIZE   20

/**
 * SHA-1 context.
 *
 * Fields are not supposed to be accessed by user code.
 */
typedef struct {
    unsigned char buf[64];
    UINT64 count;
    UINT32 val[5];
} br_sha1_context;

/**
 * SHA-1 context initialisation.
 *
 * This function initialises or resets a context for a new SHA-1
 * computation.
 *
 * ctx:   pointer to the context structure.
 */
void br_sha1_init(br_sha1_context *ctx);

/**
 * Inject some data bytes in a running SHA-1 computation.
 *
 * The provided context is updated with some data bytes. If the number
 * of bytes (`len`) is zero, then the data pointer (`data`) is ignored
 * and may be `NULL`, and this function does nothing.
 *
 * ctx:    pointer to the context structure.
 * data:   pointer to the injected data.
 * len:    injected data length (in bytes).
 */
void br_sha1_update(br_sha1_context *ctx, const void *data, size_t len);

/**
 * Compute SHA-1 output.
 *
 * The SHA-1 output for the concatenation of all bytes injected in the
 * provided context since the last initialisation or reset call, is
 * computed and written in the buffer pointed to by `out`. The context
 * itself is not modified, so extra bytes may be injected afterwards
 * to continue that computation.
 *
 * ctx:   pointer to the context structure.
 * out:   destination buffer for the hash output.
 */
void br_sha1_out(const br_sha1_context *ctx, void *out);

/**
 * Save SHA-1 running state.
 *
 * The running state for SHA-1 (output of the last internal block
 * processing) is written in the buffer pointed to by `out`. The
 * number of bytes injected since the last initialisation or reset
 * call is returned. The context is not modified.
 *
 * ctx:   pointer to the context structure.
 * out:   destination buffer for the running state.
 *
 * returns:  the injected total byte length.
 */
UINT64 br_sha1_state(const br_sha1_context *ctx, void *out);

/**
 * Restore SHA-1 running state.
 *
 * The running state for SHA-1 is set to the provided values.
 *
 * ctx:     pointer to the context structure.
 * stb:     source buffer for the running state.
 * count:   the injected total byte length.
 */
void br_sha1_set_state(br_sha1_context *ctx, const void *stb, UINT64 count);

void br_sha1_round(const unsigned char *buf, UINT32 *val);

extern const UINT32 br_sha1_IV[];

#endif  // _CRYPTO_SHA1_H

這些在Sha1.c中具有相同的定義:

#include "../platform/encoding/Endian.h"

#include "./Sha1.h"

#define F(B, C, D)     ((((C) ^ (D)) & (B)) ^ (D))
#define G(B, C, D)     ((B) ^ (C) ^ (D))
#define H(B, C, D)     (((D) & (C)) | (((D) | (C)) & (B)))
#define I(B, C, D)     G(B, C, D)

#define ROTL(x, n)    (((x) << (n)) | ((x) >> (32 - (n))))

#define K1     ((UINT32)0x5A827999)
#define K2     ((UINT32)0x6ED9EBA1)
#define K3     ((UINT32)0x8F1BBCDC)
#define K4     ((UINT32)0xCA62C1D6)

const UINT32 br_sha1_IV[5] = { 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 };

void br_sha1_round(const unsigned char *buf, UINT32 *val) {
  UINT32 m[80];
    UINT32 a, b, c, d, e;
    int i;

    a = val[0];
    b = val[1];
    c = val[2];
    d = val[3];
    e = val[4];

  br_range_dec32be(m, 16, buf);
    for (i = 16; i < 80; i ++) {
        UINT32 x = m[i - 3] ^ m[i - 8] ^ m[i - 14] ^ m[i - 16];
        m[i] = ROTL(x, 1);
    }

  for (i = 0; i < 20; i += 5) {
        e += ROTL(a, 5) + F(b, c, d) + K1 + m[i + 0]; b = ROTL(b, 30);
        d += ROTL(e, 5) + F(a, b, c) + K1 + m[i + 1]; a = ROTL(a, 30);
        c += ROTL(d, 5) + F(e, a, b) + K1 + m[i + 2]; e = ROTL(e, 30);
        b += ROTL(c, 5) + F(d, e, a) + K1 + m[i + 3]; d = ROTL(d, 30);
        a += ROTL(b, 5) + F(c, d, e) + K1 + m[i + 4]; c = ROTL(c, 30);
    }

    for (i = 20; i < 40; i += 5) {
        e += ROTL(a, 5) + G(b, c, d) + K2 + m[i + 0]; b = ROTL(b, 30);
        d += ROTL(e, 5) + G(a, b, c) + K2 + m[i + 1]; a = ROTL(a, 30);
        c += ROTL(d, 5) + G(e, a, b) + K2 + m[i + 2]; e = ROTL(e, 30);
        b += ROTL(c, 5) + G(d, e, a) + K2 + m[i + 3]; d = ROTL(d, 30);
        a += ROTL(b, 5) + G(c, d, e) + K2 + m[i + 4]; c = ROTL(c, 30);
    }

    for (i = 40; i < 60; i += 5) {
        e += ROTL(a, 5) + H(b, c, d) + K3 + m[i + 0]; b = ROTL(b, 30);
        d += ROTL(e, 5) + H(a, b, c) + K3 + m[i + 1]; a = ROTL(a, 30);
        c += ROTL(d, 5) + H(e, a, b) + K3 + m[i + 2]; e = ROTL(e, 30);
        b += ROTL(c, 5) + H(d, e, a) + K3 + m[i + 3]; d = ROTL(d, 30);
        a += ROTL(b, 5) + H(c, d, e) + K3 + m[i + 4]; c = ROTL(c, 30);
    }

    for (i = 60; i < 80; i += 5) {
        e += ROTL(a, 5) + I(b, c, d) + K4 + m[i + 0]; b = ROTL(b, 30);
        d += ROTL(e, 5) + I(a, b, c) + K4 + m[i + 1]; a = ROTL(a, 30);
        c += ROTL(d, 5) + I(e, a, b) + K4 + m[i + 2]; e = ROTL(e, 30);
        b += ROTL(c, 5) + I(d, e, a) + K4 + m[i + 3]; d = ROTL(d, 30);
        a += ROTL(b, 5) + I(c, d, e) + K4 + m[i + 4]; c = ROTL(c, 30);
    }

    val[0] += a;
    val[1] += b;
    val[2] += c;
    val[3] += d;
    val[4] += e;
}

void br_sha1_init(br_sha1_context *ctx) {
    memcpy(ctx->val, br_sha1_IV, sizeof ctx->val);
    ctx->count = 0;
}

void br_sha1_update(br_sha1_context *cc, const void *data, size_t len) {
    const unsigned char *buf;
    size_t ptr;

    buf = (const unsigned char *) data;
    ptr = (size_t)cc->count & 63;
    while (len > 0) {
        size_t clen;

        clen = 64 - ptr;
        if (clen > len) {
            clen = len;
        }
        memcpy(cc->buf + ptr, buf, clen);
        ptr += clen;
        buf += clen;
        len -= clen;
        cc->count += (UINT64)clen;
        if (ptr == 64) {
            br_sha1_round(cc->buf, cc->val);
            ptr = 0;
        }
    }
}

void br_sha1_out(const br_sha1_context *cc, void *dst) {
    unsigned char buf[64];
    UINT32 val[5];
    size_t ptr;

    ptr = (size_t)cc->count & 63;
    memcpy(buf, cc->buf, ptr);
    memcpy(val, cc->val, sizeof val);
    buf[ptr ++] = 0x80;
    if (ptr > 56) {
        memset(buf + ptr, 0, 64 - ptr);
        br_sha1_round(buf, val);
        memset(buf, 0, 56);
    } else {
        memset(buf + ptr, 0, 56 - ptr);
    }
    br_enc64be(buf + 56, cc->count << 3);
    br_sha1_round(buf, val);
    br_range_enc32be(dst, val, 5);
}

UINT64 br_sha1_state(const br_sha1_context *cc, void *dst) {
    br_range_enc32be(dst, cc->val, 5);
    return cc->count;
}

void br_sha1_set_state(br_sha1_context *cc, const void *stb, UINT64 count) {
    br_range_dec32be(cc->val, 5, stb);
    cc->count = count;
}

然后,我有一個測試文件,然后嘗試測試SHA1函數:

#include <gtest/gtest.h>
#include "../../src/crypto/Sha1.h"

static size_t hextobin(unsigned char *dst, const char *src) {
    size_t num;
    unsigned acc;
    int z;

    num = 0;
    z = 0;
    acc = 0;

    while (*src != 0) {
        int c = *src ++;
        if (c >= '0' && c <= '9') {
            c -= '0';
        } else if (c >= 'A' && c <= 'F') {
            c -= ('A' - 10);
        } else if (c >= 'a' && c <= 'f') {
            c -= ('a' - 10);
        } else {
            continue;
        }
        if (z) {
            *dst ++ = (acc << 4) + c;
            num ++;
        } else {
            acc = c;
        }
        z = !z;
    }

    return num;
}

TEST(sha_one, hash_simple) {
  unsigned char ref[br_sha1_SIZE];
  hextobin(ref, (const char *) "a9993e364706816aba3e25717850c26c9cd0d89d");
  unsigned char res[br_sha1_SIZE];
    const char *data = (const char *)"abc";

    br_sha1_context mc;
  size_t n;

  n = strlen(data);
  br_sha1_init(&mc);
  br_sha1_update(&mc, data, n);
  br_sha1_out(&mc, res);

  ASSERT_EQ(res, ref);
}

但是,當使用類似meson.build的文件時:

crypto_srcs = [
  '../../src/platform/encoding/Endian.c',
  '../../src/crypto/Sha1.c',
  'Sha1Tests.cpp',
]

e = executable('crypto_tests', sources : crypto_srcs, dependencies : gtest_dep)
test('crypto tests', e)

我收到上述錯誤,說它找不到這些函數的引用(但似乎可以解析該頭文件中定義的實際結構了嗎?這讓我更加困惑。因此,我嘗試查看這些符號在目標文件本身上查看功能是否已實際定義:

ϰ  nm ./builddir/src/src@@magmatpm@sta/crypto_Sha1.c.o 
0000000000000dc0 t br_enc32be
0000000000000ce0 t br_enc64be
                 U br_range_dec32be
                 U br_range_enc32be
0000000000000a80 T br_sha1_init
0000000000000000 R br_sha1_IV
0000000000000ba0 T br_sha1_out
0000000000000000 T br_sha1_round
0000000000000d70 T br_sha1_set_state
0000000000000d30 T br_sha1_state
0000000000000ac0 T br_sha1_update
                 U memcpy
                 U memset

該圖顯示了在目標文件中定義的功能。 因此,我對如何獲得此錯誤感到有些困惑。

正如我在評論中指出的:

您使用C編譯器在Sha1.c編譯了代碼; 您顯示的名稱不是C ++編譯器想要的整齊的名稱。 您需要使用C ++編譯器編譯代碼(如果需要,請重命名源代碼),或者您需要告訴C ++代碼,這些函數是在extern "C"定義的。

后者的一種方法是使用:

extern "C" {
#include "Sha1.h"
}

在使用C代碼的C ++代碼中。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM