Go не связывает мою сборку: неопределенная внешняя функция

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т. Д. Чем больше вы напишете о том, что именно вы сделали, тем легче вам помочь. Лучше всего публиковать стенограммы сеансов оболочки вместо проза.
fuz
12
Кажется, что в языке го действительно есть фетиш для символа середины точки. Связано: косые черты и точки в именах функций и прототипах?
Коди Грей

Ответы:

96

Вы используете неправильную точку. вместо

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

записывать

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

и все работает нормально.

фуз
источник
11
Что ж, ЭТО было тонким, я не заметил, что это была середина точки. Благодарю.
LinearZoetrope
13
Как люди набирают это на американской QWERTY-клавиатуре? Или это не обычный вариант использования, когда вы могли бы просто погуглить символ по мере необходимости?
Seiyria
9
Вот так . Операционные системы, которые не работают (то есть не Windows), отображают неиспользуемые слои макета QWERTY, чтобы можно было вводить такие символы, как интерпункт.
fuz
7
@FUZxxl FYI Alt-0183 (с помощью цифровой клавиатуры) по-прежнему работает в Windows. Не так хорошо и обычно сложно на ноутбуках, но работает.
Intermernet
4
В Linux (по крайней мере, в Ubuntu), если у вас включен ключ создания : <compose> ^ .=·
Izkata