// Copyright 2017 The Wuffs Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // https://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "flag" "fmt" "os" "os/exec" "path/filepath" "strings" cf "github.com/google/wuffs/cmd/commonflags" ) func doGenlib(args []string) error { flags := flag.FlagSet{} ccompilersFlag := flags.String("ccompilers", cf.CcompilersDefault, cf.CcompilersUsage) dstdirFlag := flags.String("dstdir", "", "directory containing the object files ") srcdirFlag := flags.String("srcdir", "", "directory containing the C source files") if err := flags.Parse(args); err != nil { return err } args = flags.Args() filenames := make([]string, len(args)) for i, arg := range args { filenames[i] = "wuffs-" + strings.Replace(filepath.ToSlash(arg), "/", "-", -1) } if *dstdirFlag == "" { return fmt.Errorf("empty -dstdir flag") } if *srcdirFlag == "" { return fmt.Errorf("empty -srcdir flag") } for _, cc := range strings.Split(*ccompilersFlag, ",") { cc = strings.TrimSpace(cc) if cc == "" { continue } for _, dynamism := range []string{"static", "dynamic"} { outDir := filepath.Join(*dstdirFlag, cc+"-"+dynamism) if err := os.MkdirAll(outDir, 0755); err != nil { return err } if err := genObj(outDir, *srcdirFlag, cc, dynamism, filenames); err != nil { return err } if err := genLib(outDir, cc, dynamism, filenames); err != nil { return err } } } return nil } // TODO: are these extensions correct for non-Linux? var ( objExtensions = map[string]string{ "dynamic": ".lo", "static": ".o", } libExtensions = map[string]string{ "dynamic": ".so", "static": ".a", } ) func genObj(outDir string, inDir string, cc string, dynamism string, filenames []string) error { for _, filename := range filenames { in := filepath.Join(inDir, filename+".c") out := genlibOutFilename(outDir, dynamism, filename) args := []string(nil) args = append(args, "-O3", "-std=c99", "-DWUFFS_IMPLEMENTATION") if dynamism == "dynamic" { args = append(args, "-fPIC", "-DPIC") } args = append(args, "-c", "-o", out, in) cmd := exec.Command(cc, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return err } fmt.Printf("genlib: %s\n", out) } return nil } func genLib(outDir string, cc string, dynamism string, filenames []string) error { args := []string(nil) switch dynamism { case "dynamic": // TODO: add a "-Wl,-soname,libwuffs.so.1.2.3" argument? args = append(args, "-shared", "-fPIC", "-o") case "static": cc = "ar" args = append(args, "rc") } out := filepath.Join(outDir, "libwuffs"+libExtensions[dynamism]) args = append(args, out) for _, filename := range filenames { args = append(args, genlibOutFilename(outDir, dynamism, filename)) } cmd := exec.Command(cc, args...) cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { return err } fmt.Printf("genlib: %s\n", out) return nil } func genlibOutFilename(outDir string, dynamism string, filename string) string { return filepath.Join(outDir, filename+objExtensions[dynamism]) }