github.com/cellofellow/gopkg@v0.0.0-20140722061823-eec0544a62ad/image/jxr/builder.go (about)

     1  // Copyright 2013 <chaishushan{AT}gmail.com>. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // +build ignore
     6  
     7  //
     8  // build jxr.dll on windows
     9  //
    10  // go run builder.go -win64 -dlldir=abcd
    11  // go run builder.go -win32 -dlldir=${ENV}\bin
    12  //
    13  package main
    14  
    15  import (
    16  	"flag"
    17  	"fmt"
    18  	"io"
    19  	"io/ioutil"
    20  	"log"
    21  	"os"
    22  	"os/exec"
    23  	"strings"
    24  )
    25  
    26  var (
    27  	flagWin64  = flag.Bool("win64", false, "build win64 target")
    28  	flagWin32  = flag.Bool("win32", false, "build win32 target")
    29  	flagDllDir = flag.String("dlldir", "", "copy dll to this dir")
    30  	flagClean  = flag.Bool("clean", false, "make clean")
    31  )
    32  
    33  func main() {
    34  	flag.Parse()
    35  
    36  	// check depend tools
    37  	if _, err := exec.LookPath("devenv"); err != nil {
    38  		log.Fatal("checkDependTools: can't find ", "devenv")
    39  	}
    40  
    41  	if *flagWin64 || *flagWin32 {
    42  		buildTarget()
    43  	}
    44  	if *flagDllDir != "" {
    45  		installDll(*flagDllDir)
    46  	}
    47  	if *flagClean {
    48  		makeClean()
    49  	}
    50  
    51  	fmt.Println("Done.")
    52  }
    53  
    54  func buildTarget() {
    55  	if *flagWin64 {
    56  		fmt.Printf("build win64 jxr.cgo ...\n")
    57  	} else {
    58  		fmt.Printf("build win32 jxr.cgo ...\n")
    59  	}
    60  
    61  	var buildDir, logName string
    62  	if *flagWin64 {
    63  		buildDir = "zz_build_win64_proj_mt_tmp"
    64  		logName = "builder-win64.log"
    65  	} else {
    66  		buildDir = "zz_build_win32_proj_mt_tmp"
    67  		logName = "builder-win32.log"
    68  	}
    69  	os.Mkdir(buildDir, 0666)
    70  
    71  	// generate vc2012 project
    72  	var cmdGenXpProj *exec.Cmd
    73  	if *flagWin64 {
    74  		cmdGenXpProj = exec.Command(
    75  			`cmake`, `..`,
    76  			`-G`, `Visual Studio 11 Win64`,
    77  			`-DCMAKE_BUILD_TYPE=release`,
    78  			`-DCMAKE_INSTALL_PREFIX=..`,
    79  			`-DCMAKE_C_FLAGS_DEBUG=/MTd /Zi /Od /Ob0 /RTC1`,
    80  			`-DCMAKE_CXX_FLAGS_DEBUG=/MTd /Zi /Od /Ob0 /RTC1`,
    81  			`-DCMAKE_C_FLAGS_RELEASE=/MT /O2 /Ob2 /DNDEBUG`,
    82  			`-DCMAKE_CXX_FLAGS_RELEASE=/MT /O2 /Ob2 /DNDEBUG`,
    83  			`-DCMAKE_EXE_LINKER_FLAGS=/MANIFEST:NO`,
    84  		)
    85  	} else {
    86  		cmdGenXpProj = exec.Command(
    87  			`cmake`, `..`,
    88  			`-G`, `Visual Studio 11`,
    89  			`-DCMAKE_GENERATOR_TOOLSET=v110_xp`, // VC2012, support xp
    90  			`-DCMAKE_BUILD_TYPE=release`,
    91  			`-DCMAKE_INSTALL_PREFIX=..`,
    92  			`-DCMAKE_C_FLAGS_DEBUG=/MTd /Zi /Od /Ob0 /RTC1`,
    93  			`-DCMAKE_CXX_FLAGS_DEBUG=/MTd /Zi /Od /Ob0 /RTC1`,
    94  			`-DCMAKE_C_FLAGS_RELEASE=/MT /O2 /Ob2 /DNDEBUG`,
    95  			`-DCMAKE_CXX_FLAGS_RELEASE=/MT /O2 /Ob2 /DNDEBUG`,
    96  			`-DCMAKE_EXE_LINKER_FLAGS=/MANIFEST:NO`,
    97  		)
    98  	}
    99  	cmdGenXpProj.Dir = buildDir
   100  
   101  	// build and install
   102  	var cmdBuildInstall *exec.Cmd
   103  	if *flagWin64 {
   104  		cmdBuildInstall = exec.Command(
   105  			`devenv`, `JXR_LIB.sln`, `/build`, `Release|x64`, `/project`, `INSTALL.vcxproj`,
   106  		)
   107  	} else {
   108  		cmdBuildInstall = exec.Command(
   109  			`devenv`, `JXR_LIB.sln`, `/build`, `Release|Win32`, `/project`, `INSTALL.vcxproj`,
   110  		)
   111  	}
   112  	cmdBuildInstall.Dir = buildDir
   113  
   114  	// dlltool -dllname jxr.dll --def jxr.def --output-lib libjxr.a
   115  	var cmdDll2A *exec.Cmd
   116  	if *flagWin64 {
   117  		cmdDll2A = exec.Command(
   118  			`dlltool`,
   119  			`-dllname`, `jxr-cgo-win64.dll`,
   120  			`--def`, `jxr-cgo-win64.def`,
   121  			`--output-lib`, `libjxr-cgo-win64.a`,
   122  		)
   123  	} else {
   124  		cmdDll2A = exec.Command(
   125  			`dlltool`,
   126  			`-dllname`, `jxr-cgo-win32.dll`,
   127  			`--def`, `jxr-cgo-win32.def`,
   128  			`--output-lib`, `libjxr-cgo-win32.a`,
   129  		)
   130  	}
   131  	cmdDll2A.Dir = "."
   132  
   133  	// run ...
   134  	out, err := cmdGenXpProj.CombinedOutput()
   135  	if err != nil {
   136  		ioutil.WriteFile(logName, out, 0666)
   137  		log.Fatalf("buildTarget: %v, see %s", err, logName)
   138  	}
   139  	out, err = cmdBuildInstall.CombinedOutput()
   140  	if err != nil {
   141  		ioutil.WriteFile(logName, out, 0666)
   142  		log.Fatalf("buildTarget: %v, see %s", err, logName)
   143  	}
   144  	out, err = cmdDll2A.CombinedOutput()
   145  	if err != nil {
   146  		ioutil.WriteFile(logName, out, 0666)
   147  		log.Fatalf("buildTarget: %v, see %s", err, logName)
   148  	}
   149  
   150  	os.Remove(logName)
   151  }
   152  
   153  func installDll(dir_or_env string) {
   154  	if dir := parseDir(dir_or_env); dir != "" {
   155  		fmt.Printf("install dir: %s\n", dir)
   156  		os.MkdirAll(dir, 0666)
   157  		if *flagWin64 {
   158  			cpFile(dir+"/jxr-cgo-win64.dll", "jxr-cgo-win64.dll")
   159  		} else {
   160  			cpFile(dir+"/jxr-cgo-win32.dll", "jxr-cgo-win32.dll")
   161  		}
   162  	}
   163  }
   164  
   165  func makeClean() {
   166  	os.RemoveAll("zz_build_win64_proj_mt_tmp")
   167  	os.RemoveAll("zz_build_win32_proj_mt_tmp")
   168  }
   169  
   170  func parseDir(dir_or_env string) string {
   171  	if dir_or_env == "" {
   172  		return ""
   173  	}
   174  	if !strings.HasPrefix(dir_or_env, "${") {
   175  		return dir_or_env
   176  	}
   177  	if idx := strings.Index(dir_or_env, "}"); idx >= 0 {
   178  		return os.Getenv(dir_or_env[2:idx]) + dir_or_env[idx+1:]
   179  	} else {
   180  		log.Fatalf("parseDir: bad dir %q", dir_or_env)
   181  	}
   182  	return ""
   183  }
   184  
   185  func cpFile(dst, src string) {
   186  	fsrc, err := os.Open(src)
   187  	if err != nil {
   188  		log.Fatal("cpFile: ", err)
   189  	}
   190  	defer fsrc.Close()
   191  
   192  	fdst, err := os.Create(dst)
   193  	if err != nil {
   194  		log.Fatal("cpFile: ", err)
   195  	}
   196  	defer fdst.Close()
   197  	if _, err = io.Copy(fdst, fsrc); err != nil {
   198  		log.Fatal("cpFile: ", err)
   199  	}
   200  }