2016-05-16 1 views
1

Я пытаюсь извлечь все исходные файлы, которые используются во время компиляции. Функция runtime.Caller() и паника с ее stacktrace показывают эту информацию.golang fetch all all filepathes из скомпилированного файла

мне нужно что-то вроде этого

func fetchUsedFiles() []string { 
    .... 
} 
func main() { 
    log.Println("Used Files",fetchUsedFiles()) 
} 

UPD:

Все, что мне нужно как-то читается "runtime.firstmoduledata" содержимое переменной. Но он не экспортируется переменной.

+1

Я использую 'пойти список -f "{{.ImportPath}} {{.Deps}}" мой/program' чтобы получить все зависимости, и я получаю их во временной подпапке. Я использую это для зависимостей поставщиков: https://gist.github.com/VonC/51fe08c5bd79334b6e1ccdd498d4d2bc. Но это не то, что вам нужно или что означает «выборка всех исходных файлов, которые используются во время компиляции». – VonC

ответ

1

На самом деле я объединил VonC-ответ и мою поддержку времени.

Все необходимые данные хранятся в runtime.firstmoduledata - struct, но они не экспортируются. Чтобы прочитать данные оттуда, я снова прочитал свой исполняемый файл (реализованный только для ELF), найдите этот символ и выполните другую часть, такую ​​как функция runtime.Caller(). Этот метод не является переносимым и может быть нарушен изменениями в библиотеке времени выполнения, но он работает.

selfReflect функция использует копию личных типов от выполнения Lib

https://github.com/martende/restartable/blob/master/restartable.go#L208

func selfReflect(filename string) ([]string,error) { 
    f,err := elf.Open(filename) 
    if err != nil { 
     return nil,err 
    } 
    defer f.Close() 
    syms,err := f.Symbols() 
    if err != nil { 
     return nil,err 
    } 
    var modSym elf.Symbol 
    var modSymFound = false 
    for _,v := range syms { 
     if v.Name == "runtime.firstmoduledata" { 
      modSym = v 
      modSymFound = true 
      break 
     } 
    } 
    if ! modSymFound { 
     return nil,errors.New("elfparse:nosym") 
    } 

    var datap = (*moduledata)(unsafe.Pointer(uintptr(modSym.Value))) 

    files := make([]string,0) 
    for i := range datap.filetab { 
     bp := &datap.pclntable[datap.filetab[i]] 
     file := C.GoString((*C.char) (unsafe.Pointer(bp)) ) 
     if file != "<autogenerated>" && file != "@" { 
      if _, err := os.Stat(file); err == nil { 
       files = append(files ,file) 
      } 
     } 
    } 


    return files,nil 
} 
+0

Nice (upvoted). Я все еще не уверен, что проблема точно решена;) – VonC

+0

@ VonC. Я хочу отслеживать файлы, которые используются во время компиляции, и тихо перекомпилировать и перезапустить сервер. – Oleg

+0

ОК, это яснее сейчас. Вы можете добавить это как описание своего https://github.com/martende/restartable repo. – VonC

 Смежные вопросы

  • Нет связанных вопросов^_^