Go не пов’язує мою збірку: undefined external function


82

Я намагаюся написати деякі SIMD в основному для навчальних цілей. Я знаю, що Go може пов’язати збірку, але я не можу змусити її працювати належним чином.

Ось найменший приклад, який я можу зробити (векторне множення по елементах):

vec_amd64.s (примітка: фактичний файл має пробіл під рядком, RETоскільки в іншому випадку він викликає помилки)

// func mul(v1, v2 Vec4) Vec4
TEXT .mul(SB),4,$0-48
    MOVUPS v1+0(FP),  X0
    MOVUPS v2+16(FP), X1
    MULPS  X1, X0
    // also tried ret+32 since I've seen some places do that
    MOVUPS X0, toReturn+32(FP)
    RET

vec.go

package simd

type Vec4 [4]float32

func (v1 Vec4) Mul(v2 Vec4) Vec4 {
    return Vec4{v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2], v1[3] * v2[3]}
}

func mul(v1, v2 Vec4) Vec4

simd_test.go

package simd

import (
    "testing"
)

func TestMul(t *testing.T) {
    v1 := Vec4{1, 2, 3, 4}
    v2 := Vec4{5, 6, 7, 8}

    res := v1.Mul(v2)
    res2 := mul(v1, v2)

    // Placeholder until I get it to compile
    if res != res2 {
        t.Fatalf("Expected %v; got %v", res, res2)
    }
}

Коли я намагаюся запустити, go testя отримую помилку:

# testmain
simd.TestMul: call to external function simd.mul
simd.TestMul: undefined: simd.mul

go envКоманда моїх звітів GOHOSTARCHбути amd64і моя Go версія буде 1.3. Щоб підтвердити, що проблема не в архітектурі, я знайшов інший пакет, який використовує збірку, і видалив усі файли збірки, крім _amd64.sодного, і його тести пройшли нормально.

Я також спробував змінити його на експортований ідентифікатор на випадок, якщо це викликало дивацтво, але без кубиків. Думаю, я досить уважно стежив за шаблоном у пакунках, наприклад math/big, тому, сподіваюся, це щось просте і очевидне, чого мені не вистачає.

Я знаю, що Go принаймні намагається використовувати збірку, тому що якщо я введу синтаксичну помилку у файл .s, інструмент побудови скаржиться на це.

Редагувати:

Щоб бути зрозумілим, go buildбуде компілювати чисто, але go testспричинить появу помилки.


go buildзакінчив чисто, go testне вдається.
LinearZoetrope

1
Як складаєш? Ви не відповіли на запитання.
fuz

1
Які команди ви ввели з якого каталогу щодо вам вихідних файлів? Я компілюю за допомогою goінструмента побудови. дуже розмито. Це може означати що завгодно.
fuz

1
Існує різниця між дзвінком go buildі go build foo.goт. Д. Також може бути можливо, що у вас є прикольні налаштування $GOPATHтощо. Чим більше ви пишете про те, що саме зробили, тим простіше вам допомогти. Найкраще - розміщувати стенограми сеансів оболонки замість prosa.
fuz

12
Мова Go справді має фетиш до символу середньої крапки. Пов’язане: Коса риса та крапки в іменах функцій та прототипах?
Коді Грей

Відповіді:


96

Ви використовуєте неправильну крапку. замість

TEXT .mul(SB),4,$0-48

писати

TEXT ·mul(SB),4,$0-48

і все працює просто чудово.


11
Ну ЦЕ було витончено, я не помітив, що це середина крапки. Дякую.
LinearZoetrope

13
Як люди друкують це на американській клавіатурі QWERTY? Або це не типовий випадок використання, коли ви можете просто погуглити символ за необхідності?
Сейрія

9
Ось так . ОС, які не смоктать (тобто не Windows), відображають невикористані шари макета QWERTY, щоб можна було вводити такі символи, як інтерпункт.
fuz

7
@FUZxxl FYI Alt-0183 (за допомогою цифрової клавіатури) все ще працює для Windows. Не настільки приємно і зазвичай важко на ноутбуках, але це працює.
Intermernet

4
На Linux (принаймні Ubuntu), якщо у вас увімкнено клавішу створення : <compose> ^ .=·
Izkata
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.