/
gen-deps-windows.go
151 lines (124 loc) · 3.45 KB
/
gen-deps-windows.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package generator
import (
"bufio"
"bytes"
"fmt"
"os"
"os/exec"
fp "path/filepath"
"runtime"
"strings"
"github.com/RadhiFadlillah/qamel/qamel/config"
)
// copyWindowsPlugins copies Windows plugins to output directory
func copyWindowsPlugins(qmakeVars map[string]string, outputDir string) error {
qtPluginsDir := qmakeVars["QT_INSTALL_PLUGINS"]
plugins := []string{
"platforms/qwindows.dll",
"imageformats",
"iconengines/qsvgicon.dll"}
for _, plugin := range plugins {
srcPath := fp.Join(qtPluginsDir, plugin)
dstPath := fp.Join(outputDir, plugin)
if !fileDirExists(srcPath) {
continue
}
err := copyFileDir(srcPath, dstPath, func(path string, info os.FileInfo) bool {
if strings.HasSuffix(info.Name(), "d.dll") {
tmpPath := strings.TrimSuffix(path, "d.dll")
tmpPath += ".dll"
if fileExists(tmpPath) {
return true
}
}
return false
})
if err != nil {
return err
}
}
return nil
}
// copyWindowsLibs copies Windows libraries to output directory
func copyWindowsLibs(qmakeVars map[string]string, profile config.Profile, outputPath string) error {
// Get list of files to check.
// The first one is the output binary file
filesToCheck := []string{outputPath}
// The plugins library (*.dll) must be checked as well
outputDir := fp.Dir(outputPath)
if dirExists(outputDir) {
fp.Walk(outputDir, func(path string, info os.FileInfo, err error) error {
if info.IsDir() {
return nil
}
if fp.Ext(info.Name()) == ".dll" {
filesToCheck = append(filesToCheck, path)
}
return nil
})
}
// Get directory of Qt and Gcc libs
qtLibsDir := fp.Dir(profile.Qmake)
gccLibsDir := fp.Dir(profile.Gcc)
if runtime.GOOS != "windows" {
// If it's not Windows, it must be using MXE,
// so find GCC using relative path from qmake location
gccLibsDir = fp.Join(qtLibsDir, "..", "..", "bin")
}
// Get list of dependency of the files
mapDependencies := map[string]string{}
filesAlreadyChecked := map[string]struct{}{}
for {
// Keep checking until there are no file left
if len(filesToCheck) == 0 {
break
}
fileName := filesToCheck[0]
// If this file has been checked before, skip
if _, checked := filesAlreadyChecked[fileName]; checked {
filesToCheck = filesToCheck[1:]
continue
}
// Fetch dependencies using objdump
cmdObjdump := exec.Command(profile.Objdump, "-p", fileName)
objdumpResult, err := cmdObjdump.CombinedOutput()
if err != nil {
return fmt.Errorf("%v: %s", err, objdumpResult)
}
// Parse objdump results
buffer := bytes.NewBuffer(objdumpResult)
scanner := bufio.NewScanner(buffer)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if !strings.HasPrefix(line, "DLL Name:") {
continue
}
libName := strings.TrimPrefix(line, "DLL Name:")
libName = strings.TrimSpace(libName)
if libName == "" {
continue
}
libPath := fp.Join(qtLibsDir, libName)
if !fileExists(libPath) {
libPath = fp.Join(gccLibsDir, libName)
if !fileExists(libPath) {
continue
}
}
filesToCheck = append(filesToCheck, libPath)
mapDependencies[libName] = libPath
}
// Save this files as been already checked, then move to next
filesAlreadyChecked[fileName] = struct{}{}
filesToCheck = filesToCheck[1:]
}
// Copy all dependency libs to output dir
var err error
for libName, libPath := range mapDependencies {
err = copyFile(libPath, fp.Join(outputDir, libName))
if err != nil {
return err
}
}
return nil
}