@@ -168,6 +168,18 @@ func runBuild(mode bind.BuildMode, cfg *BuildCfg) error {
168168 }
169169
170170 } else {
171+ buildLib := buildname + libExt
172+ extext := libExt
173+ if runtime .GOOS == "windows" {
174+ extext = ".pyd"
175+ }
176+ if pycfg .ExtSuffix != "" {
177+ extext = pycfg .ExtSuffix
178+ }
179+ modlib := "_" + cfg .Name + extext
180+
181+ // build the go shared library upfront to generate the header
182+ // needed by our generated cpython code
171183 args := []string {"build" , "-buildmode=c-shared" }
172184 if ! cfg .Symbols {
173185 // These flags will omit the various symbol tables, thereby
@@ -176,15 +188,20 @@ func runBuild(mode bind.BuildMode, cfg *BuildCfg) error {
176188 // -w Omit the DWARF symbol table
177189 args = append (args , "-ldflags=-s -w" )
178190 }
179- args = append (args , "-o" , buildname + libExt , "." )
191+ args = append (args , "-o" , buildLib , "." )
180192 fmt .Printf ("go %v\n " , strings .Join (args , " " ))
181193 cmd = exec .Command ("go" , args ... )
182194 cmdout , err = cmd .CombinedOutput ()
183195 if err != nil {
184196 fmt .Printf ("cmd had error: %v output:\n %v\n " , err , string (cmdout ))
185197 return err
186198 }
199+ // update the output name to the one with the ABI extension
200+ args [len (args )- 2 ] = modlib
201+ // we don't need this initial lib because we are going to relink
202+ os .Remove (buildLib )
187203
204+ // generate c code
188205 fmt .Printf ("%v build.py\n " , cfg .VM )
189206 cmd = exec .Command (cfg .VM , "build.py" )
190207 cmdout , err = cmd .CombinedOutput ()
@@ -193,77 +210,59 @@ func runBuild(mode bind.BuildMode, cfg *BuildCfg) error {
193210 return err
194211 }
195212
213+ // patch c code
196214 if err := patchLeaks (cfg .Name + ".c" ); err != nil {
197215 return err
198216 }
199217
200- fmt .Printf ("go env CC\n " )
201- cmd = exec .Command ("go" , "env" , "CC" )
202- cccmdb , err := cmd .CombinedOutput ()
203- if err != nil {
204- fmt .Printf ("cmd had error: %v output:\n %v\n " , err , string (cccmdb ))
205- return err
206- }
207- cccmd := strings .TrimSpace (string (cccmdb ))
208- // var cflags, ldflags []byte
209- // if runtime.GOOS != "windows" {
210- // fmt.Printf("%v-config --cflags\n", vm)
211- // cmd = exec.Command(vm+"-config", "--cflags") // TODO: need minor version!
212- // cflags, err = cmd.CombinedOutput()
213- // if err != nil {
214- // fmt.Printf("cmd had error: %v output:\n%v\n", err, string(cflags))
215- // return err
216- // }
217- //
218- // fmt.Printf("%v-config --ldflags\n", vm)
219- // cmd = exec.Command(vm+"-config", "--ldflags")
220- // ldflags, err = cmd.CombinedOutput()
221- // if err != nil {
222- // fmt.Printf("cmd had error: %v output:\n%v\n", err, string(ldflags))
223- // return err
224- // }
225- // fmt.Printf("build cmd: %s\nldflags: %s\n", cmd, ldflags)
226- // }
227- extext := libExt
228- if runtime .GOOS == "windows" {
229- extext = ".pyd"
218+ cflags := strings .Fields (strings .TrimSpace (pycfg .CFlags ))
219+ cflags = append (cflags , "-fPIC" , "-Ofast" )
220+ if include , exists := os .LookupEnv ("GOPY_INCLUDE" ); exists {
221+ cflags = append (cflags , "-I" + filepath .ToSlash (include ))
230222 }
231- modlib := "_" + cfg .Name + extext
232- gccargs := []string {cfg .Name + ".c" , extraGccArgs , cfg .Name + "_go" + libExt , "-o" , modlib }
233- gccargs = append (gccargs , strings .Fields (pycfg .AllFlags ())... )
234- gccargs = append (gccargs , "-fPIC" , "--shared" , "-Ofast" )
223+
224+ ldflags := strings .Fields (strings .TrimSpace (pycfg .LdFlags ))
235225 if ! cfg .Symbols {
236- gccargs = append (gccargs , "-s" )
226+ ldflags = append (ldflags , "-s" )
237227 }
238- include , exists := os .LookupEnv ("GOPY_INCLUDE" )
239- if exists {
240- gccargs = append (gccargs , "-I" + filepath .ToSlash (include ))
228+ if lib , exists := os .LookupEnv ("GOPY_LIBDIR" ); exists {
229+ ldflags = append (ldflags , "-L" + filepath .ToSlash (lib ))
241230 }
242- lib , exists := os .LookupEnv ("GOPY_LIBDIR" )
243- if exists {
244- gccargs = append (gccargs , "-L" + filepath .ToSlash (lib ))
245- }
246- libname , exists := os .LookupEnv ("GOPY_PYLIB" )
247- if exists {
248- gccargs = append (gccargs , "-l" + filepath .ToSlash (libname ))
231+ if libname , exists := os .LookupEnv ("GOPY_PYLIB" ); exists {
232+ ldflags = append (ldflags , "-l" + filepath .ToSlash (libname ))
249233 }
250234
251- gccargs = func (vs []string ) []string {
252- o := make ([]string , 0 , len (gccargs ))
253- for _ , v := range vs {
235+ removeEmpty : = func (src []string ) []string {
236+ o := make ([]string , 0 , len (src ))
237+ for _ , v := range src {
254238 if v == "" {
255239 continue
256240 }
257241 o = append (o , v )
258242 }
259243 return o
260- }(gccargs )
244+ }
245+
246+ cflags = removeEmpty (cflags )
247+ ldflags = removeEmpty (ldflags )
261248
262- fmt .Printf ("%s %v\n " , cccmd , strings .Join (gccargs , " " ))
263- cmd = exec .Command (cccmd , gccargs ... )
249+ cflagsEnv := fmt .Sprintf ("CGO_CFLAGS=%s" , strings .Join (cflags , " " ))
250+ ldflagsEnv := fmt .Sprintf ("CGO_LDFLAGS=%s" , strings .Join (ldflags , " " ))
251+
252+ env := os .Environ ()
253+ env = append (env , cflagsEnv )
254+ env = append (env , ldflagsEnv )
255+
256+ fmt .Println (cflagsEnv )
257+ fmt .Println (ldflagsEnv )
258+
259+ // build extension with go + c
260+ fmt .Printf ("go %v\n " , strings .Join (args , " " ))
261+ cmd = exec .Command ("go" , args ... )
262+ cmd .Env = env
264263 cmdout , err = cmd .CombinedOutput ()
265264 if err != nil {
266- fmt .Printf ("cmd had error: %v\n output: %v\n " , err , string (cmdout ))
265+ fmt .Printf ("cmd had error: %v output: \n %v\n " , err , string (cmdout ))
267266 return err
268267 }
269268 }
0 commit comments