@@ -37,7 +37,7 @@ import (
37
37
// DefaultGOROOT is the default GOROOT value for builds.
38
38
//
39
39
// It uses the GOPHERJS_GOROOT environment variable if it is set,
40
- // or else the default GOROOT value of the system Go distrubtion .
40
+ // or else the default GOROOT value of the system Go distribution .
41
41
var DefaultGOROOT = func () string {
42
42
if goroot , ok := os .LookupEnv ("GOPHERJS_GOROOT" ); ok {
43
43
// GopherJS-specific GOROOT value takes precedence.
@@ -47,6 +47,8 @@ var DefaultGOROOT = func() string {
47
47
return build .Default .GOROOT
48
48
}()
49
49
50
+ // ImportCError is returned when GopherJS attempts to build a package that uses
51
+ // CGo.
50
52
type ImportCError struct {
51
53
pkgPath string
52
54
}
@@ -115,49 +117,6 @@ func importWithSrcDir(xctx XContext, path string, srcDir string, mode build.Impo
115
117
return nil , err
116
118
}
117
119
118
- switch path {
119
- case "os" :
120
- pkg .GoFiles = excludeExecutable (pkg .GoFiles ) // Need to exclude executable implementation files, because some of them contain package scope variables that perform (indirectly) syscalls on init.
121
- // Prefer the dirent_${GOOS}.go version, to make the build pass on both linux
122
- // and darwin.
123
- // In the long term, our builds should produce the same output regardless
124
- // of the host OS: https://github.com/gopherjs/gopherjs/issues/693.
125
- pkg .GoFiles = exclude (pkg .GoFiles , "dirent_js.go" )
126
- case "runtime" :
127
- pkg .GoFiles = []string {} // Package sources are completely replaced in natives.
128
- case "runtime/internal/sys" :
129
- pkg .GoFiles = []string {fmt .Sprintf ("zgoos_%s.go" , xctx .GOOS ()), "zversion.go" }
130
- case "runtime/pprof" :
131
- pkg .GoFiles = nil
132
- case "internal/poll" :
133
- pkg .GoFiles = exclude (pkg .GoFiles , "fd_poll_runtime.go" )
134
- case "sync" :
135
- // GopherJS completely replaces sync.Pool implementation with a simpler one,
136
- // since it always executes in a single-threaded environment.
137
- pkg .GoFiles = exclude (pkg .GoFiles , "pool.go" )
138
- case "crypto/rand" :
139
- pkg .GoFiles = []string {"rand.go" , "util.go" }
140
- pkg .TestGoFiles = exclude (pkg .TestGoFiles , "rand_linux_test.go" ) // Don't want linux-specific tests (since linux-specific package files are excluded too).
141
- case "crypto/x509" :
142
- // GopherJS doesn't support loading OS root certificates regardless of the
143
- // OS. The substitution below allows to avoid build dependency on Mac OS
144
- // implementation, which won't be used anyway.
145
- //
146
- // Just like above, https://github.com/gopherjs/gopherjs/issues/693 is
147
- // probably the best long-term option.
148
- pkg .GoFiles = include (
149
- exclude (pkg .GoFiles , fmt .Sprintf ("root_%s.go" , xctx .GOOS ())),
150
- "root_unix.go" , "root_js.go" )
151
- case "syscall/js" :
152
- // Reuse upstream tests to ensure conformance, but completely replace
153
- // implementation.
154
- pkg .XTestGoFiles = append (pkg .TestGoFiles , "js_test.go" )
155
- }
156
-
157
- if len (pkg .CgoFiles ) > 0 {
158
- return nil , & ImportCError {path }
159
- }
160
-
161
120
if pkg .IsCommand () {
162
121
pkg .PkgObj = filepath .Join (pkg .BinDir , filepath .Base (pkg .ImportPath )+ ".js" )
163
122
}
@@ -378,6 +337,7 @@ func parseAndAugment(xctx XContext, pkg *PackageData, isTest bool, fileSet *toke
378
337
return files , nil
379
338
}
380
339
340
+ // Options controls build process behavior.
381
341
type Options struct {
382
342
GOROOT string
383
343
GOPATH string
@@ -391,13 +351,15 @@ type Options struct {
391
351
BuildTags []string
392
352
}
393
353
354
+ // PrintError message to the terminal.
394
355
func (o * Options ) PrintError (format string , a ... interface {}) {
395
356
if o .Color {
396
357
format = "\x1B [31m" + format + "\x1B [39m"
397
358
}
398
359
fmt .Fprintf (os .Stderr , format , a ... )
399
360
}
400
361
362
+ // PrintSuccess message to the terminal.
401
363
func (o * Options ) PrintSuccess (format string , a ... interface {}) {
402
364
if o .Color {
403
365
format = "\x1B [32m" + format + "\x1B [39m"
@@ -455,6 +417,10 @@ func (p *PackageData) XTestPackage() *PackageData {
455
417
}
456
418
}
457
419
420
+ // Session manages internal state GopherJS requires to perform a build.
421
+ //
422
+ // This is the main interface to GopherJS build system. Session lifetime is
423
+ // roughly equivalent to a single GopherJS tool invocation.
458
424
type Session struct {
459
425
options * Options
460
426
xctx XContext
@@ -463,6 +429,7 @@ type Session struct {
463
429
Watcher * fsnotify.Watcher
464
430
}
465
431
432
+ // NewSession creates a new GopherJS build session.
466
433
func NewSession (options * Options ) (* Session , error ) {
467
434
if options .GOROOT == "" {
468
435
options .GOROOT = DefaultGOROOT
@@ -499,9 +466,10 @@ func NewSession(options *Options) (*Session, error) {
499
466
return s , nil
500
467
}
501
468
502
- // BuildContext returns the session's build context.
469
+ // XContext returns the session's build context.
503
470
func (s * Session ) XContext () XContext { return s .xctx }
504
471
472
+ // InstallSuffix returns the suffix added to the generated output file.
505
473
func (s * Session ) InstallSuffix () string {
506
474
if s .options .Minify {
507
475
return "min"
@@ -514,30 +482,10 @@ func (s *Session) GoRelease() string {
514
482
return compiler .GoRelease (s .options .GOROOT )
515
483
}
516
484
517
- func (s * Session ) BuildDir (packagePath string , importPath string , pkgObj string ) error {
518
- if s .Watcher != nil {
519
- s .Watcher .Add (packagePath )
520
- }
521
- pkg , err := s .xctx .Import ("." , packagePath , 0 )
522
- if err != nil {
523
- return err
524
- }
525
-
526
- archive , err := s .BuildPackage (pkg )
527
- if err != nil {
528
- return err
529
- }
530
- if pkgObj == "" {
531
- pkgObj = filepath .Base (packagePath ) + ".js"
532
- }
533
- if pkg .IsCommand () && ! pkg .UpToDate {
534
- if err := s .WriteCommandPackage (archive , pkgObj ); err != nil {
535
- return err
536
- }
537
- }
538
- return nil
539
- }
540
-
485
+ // BuildFiles passed to the GopherJS tool as if they were a package.
486
+ //
487
+ // A ephemeral package will be created with only the provided files. This
488
+ // function is intended for use with, for example, `gopherjs run main.go`.
541
489
func (s * Session ) BuildFiles (filenames []string , pkgObj string , packagePath string ) error {
542
490
pkg := & PackageData {
543
491
Package : & build.Package {
@@ -566,11 +514,18 @@ func (s *Session) BuildFiles(filenames []string, pkgObj string, packagePath stri
566
514
return s .WriteCommandPackage (archive , pkgObj )
567
515
}
568
516
517
+ // BuildImportPath loads and compiles package with the given import path.
518
+ //
519
+ // Relative paths are interpreted relative to the current working dir.
569
520
func (s * Session ) BuildImportPath (path string ) (* compiler.Archive , error ) {
570
521
_ , archive , err := s .buildImportPathWithSrcDir (path , "" )
571
522
return archive , err
572
523
}
573
524
525
+ // buildImportPathWithSrcDir builds the package specified by the import path.
526
+ //
527
+ // Relative import paths are interpreted relative to the passed srcDir. If
528
+ // srcDir is empty, current working directory is assumed.
574
529
func (s * Session ) buildImportPathWithSrcDir (path string , srcDir string ) (* PackageData , * compiler.Archive , error ) {
575
530
pkg , err := importWithSrcDir (s .xctx , path , srcDir , 0 , s .InstallSuffix ())
576
531
if s .Watcher != nil && pkg != nil { // add watch even on error
@@ -588,6 +543,7 @@ func (s *Session) buildImportPathWithSrcDir(path string, srcDir string) (*Packag
588
543
return pkg , archive , nil
589
544
}
590
545
546
+ // BuildPackage compiles an already loaded package.
591
547
func (s * Session ) BuildPackage (pkg * PackageData ) (* compiler.Archive , error ) {
592
548
if archive , ok := s .Archives [pkg .ImportPath ]; ok {
593
549
return archive , nil
@@ -608,23 +564,7 @@ func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) {
608
564
}
609
565
610
566
for _ , importedPkgPath := range pkg .Imports {
611
- // Ignore all imports that aren't mentioned in import specs of pkg.
612
- // For example, this ignores imports such as runtime/internal/sys and runtime/internal/atomic.
613
- ignored := true
614
- for _ , pos := range pkg .ImportPos [importedPkgPath ] {
615
- importFile := filepath .Base (pos .Filename )
616
- for _ , file := range pkg .GoFiles {
617
- if importFile == file {
618
- ignored = false
619
- break
620
- }
621
- }
622
- if ! ignored {
623
- break
624
- }
625
- }
626
-
627
- if importedPkgPath == "unsafe" || ignored {
567
+ if importedPkgPath == "unsafe" {
628
568
continue
629
569
}
630
570
importedPkg , _ , err := s .buildImportPathWithSrcDir (importedPkgPath , pkg .Dir )
@@ -732,6 +672,7 @@ func (s *Session) BuildPackage(pkg *PackageData) (*compiler.Archive, error) {
732
672
return archive , nil
733
673
}
734
674
675
+ // writeLibraryPackage writes a compiled package archive to disk at pkgObj path.
735
676
func (s * Session ) writeLibraryPackage (archive * compiler.Archive , pkgObj string ) error {
736
677
if err := os .MkdirAll (filepath .Dir (pkgObj ), 0777 ); err != nil {
737
678
return err
@@ -746,6 +687,7 @@ func (s *Session) writeLibraryPackage(archive *compiler.Archive, pkgObj string)
746
687
return compiler .WriteArchive (archive , objFile )
747
688
}
748
689
690
+ // WriteCommandPackage writes the final JavaScript output file at pkgObj path.
749
691
func (s * Session ) WriteCommandPackage (archive * compiler.Archive , pkgObj string ) error {
750
692
if err := os .MkdirAll (filepath .Dir (pkgObj ), 0777 ); err != nil {
751
693
return err
@@ -786,6 +728,7 @@ func (s *Session) WriteCommandPackage(archive *compiler.Archive, pkgObj string)
786
728
return compiler .WriteProgramCode (deps , sourceMapFilter , s .GoRelease ())
787
729
}
788
730
731
+ // NewMappingCallback creates a new callback for source map generation.
789
732
func NewMappingCallback (m * sourcemap.Map , goroot , gopath string , localMap bool ) func (generatedLine , generatedColumn int , originalPos token.Position ) {
790
733
return func (generatedLine , generatedColumn int , originalPos token.Position ) {
791
734
if ! originalPos .IsValid () {
@@ -810,6 +753,8 @@ func NewMappingCallback(m *sourcemap.Map, goroot, gopath string, localMap bool)
810
753
}
811
754
}
812
755
756
+ // jsFilesFromDir finds and loads any *.inc.js packages in the build context
757
+ // directory.
813
758
func jsFilesFromDir (bctx * build.Context , dir string ) ([]string , error ) {
814
759
files , err := buildutil .ReadDir (bctx , dir )
815
760
if err != nil {
@@ -837,6 +782,8 @@ func hasGopathPrefix(file, gopath string) (hasGopathPrefix bool, prefixLen int)
837
782
return false , 0
838
783
}
839
784
785
+ // WaitForChange watches file system events and returns if either when one of
786
+ // the source files is modified.
840
787
func (s * Session ) WaitForChange () {
841
788
s .options .PrintSuccess ("watching for changes...\n " )
842
789
for {
0 commit comments