From 5a3d642cdcfe87ba7b28f8538192b25e2cfba506 Mon Sep 17 00:00:00 2001 From: Bimal Jha Date: Tue, 10 Dec 2024 13:27:18 +0530 Subject: [PATCH] fea: add support for Macos AMR64 platform --- INSTALL.md | 63 ++++++++------------- README.md | 13 +++-- installer/setup.go | 133 ++++++++++++++++++++++++++++----------------- 3 files changed, 114 insertions(+), 95 deletions(-) diff --git a/INSTALL.md b/INSTALL.md index a9abcb4..16dacb3 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -107,7 +107,7 @@ export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$IBM_DB_HOME/lib cd .../go_ibm_db/installer source setenv.sh ``` -## 3. Go_ibm_db Installation on MacOS. +## 3. Go_ibm_db Installation on MacOS x64 and arm64 Systems ### 3.1 Install GoLang for Mac @@ -133,14 +133,23 @@ It's Done. 1. mkdir goapp 2. cd goapp 3. git clone https://github.com/ibmdb/go_ibm_db/ +4. cd go_ibm_db/installer +5. go run setup.go ``` ### 3.3 Download clidriver -Download clidriver in your system, use below command: -go to installer folder where go_ibm_db is downloaded in your system +To download clidriver in your system, use below command: +Cd to installer folder where go_ibm_db is downloaded in your system (Example: /home/uname/go/src/github.com/ibmdb/go_ibm_db/installer or /home/uname/goapp/go_ibm_db/installer -where uname is the username) and run setup.go file (go run setup.go) +where uname is the username) and run setup.go file (`go run setup.go`) + +#### 3.3.1 downloaded driver version + +* Latest version of clidriver available for MacOS x64 system is: v11.5.9 +* By default on Intel Chip Macos, clidriver of v11.5.9 will get downloaded. +* First version of clidriver supported on MacOS ARM64 system is: v12.1.0 +* On MacOS M1/M2/M3 Chip system, by default clidriver of v12.1.0 will get downloaded. ### 3.4 Set environment variables to clidriver directory path @@ -162,6 +171,16 @@ cd .../go_ibm_db/installer source setenv.sh ``` +#### 3.4.3 Disable SIP or create symlink of libdb2 on MacARM64 sysem + +* New MacOS systems comes with System Integrity Protection(SIP) enabled which discards setting of DYLD_LIBRARY_PATH env variable +* Disable SIP if your Go app gives error that: file `libdb2.dylib` not found. +* If you can not disable SIP, create softlink of `.../clidriver/lib/libdb2.dylib` file under your applications home directory. +``` + ln -s .../clidriver/lib/libdb2.dylib libdb2.dylib +``` +* If you see `libdb2.dylib` file under `go_ibm_db` directory, you can copy it too in your app root directory. + ## 4. Go_ibm_db Installation on Windows. ### 4.1 Install GoLang for Windows @@ -216,39 +235,3 @@ It's Done. 4. Download platform specific clidriver from https://public.dhe.ibm.com/ibmdl/export/pub/software/data/db2/drivers/odbc_cli/ , untar/unzip it and set `IBM_DB_HOME` environmental variable to full path of extracted 'clidriver' directory, for example if clidriver is extracted as: `/home/mysystem/clidriver`, then set system level environment variable `IBM_DB_HOME=/home/mysystem/clidriver`. - - -## 5. Steps to install ibm_db on MacOS M1/M2 Chip system (arm64 architecture) -**Warning:** If you use the ARM version of homebrew (as recommended for M1/M2 chip systems) you will get the following error message: -``` -$ brew install gcc-12 -Error: Cannot install in Homebrew on ARM processor in Intel default prefix (/usr/local)! -Please create a new installation in /opt/homebrew using one of the -"Alternative Installs" from: - https://docs.brew.sh/Installation -You can migrate your previously installed formula list with: - brew bundle dump -``` -Install `gcc@12` using homebrew `(note: the x86_64 version of homebrew is needed for this, not the recommended ARM based homebrew)`. The clearest instructions on how to install and use the `x86_64` version of `homebrew` is by following below steps: -* My arm64/M1 brew is installed here: -``` - $ which brew - /opt/homebrew/bin/brew -``` -* Step 1. Install x86_64 brew under /usr/local/bin/brew - `arch -x86_64 /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"` -* Step 2. Create an alias for the x86_64 brew - I added this to my ~/.bashrc as below: -``` - # brew hack for x86_64 - alias brew64='arch -x86_64 /usr/local/bin/brew' -``` -* Then install gcc@12 using the x86_64 homebrew: -``` - brew64 install gcc@12 -``` -* Now find location of `lib/gcc/12/libstdc++.6.dylib` file in your system. It should be inside `/usr/local/homebrew/lib/gcc/12` or `/usr/local/lib/gcc/12` or `/usr/local/homebrew/Cellar/gcc@12/12.2.0/lib/gcc/12` or something similar. You need to find the correct path. -Suppose path of gcc lib is `/usr/local/homebrew/lib/gcc/12`. Then update your .bashrc/.zshrc file with below line -``` -export DYLD_LIBRARY_PATH=/usr/local/homebrew/lib/gcc/12:$DYLD_LIBRARY_PATH -``` diff --git a/README.md b/README.md index 7c23bc4..a58f328 100644 --- a/README.md +++ b/README.md @@ -23,6 +23,9 @@ yum install go git tar libpam * **SQL1598N Error** - It is expected in absence of valid db2connect license. Please click [here](#Licenserequirements) and read instructions about license requirement and how to apply the license. +* go_ibm_db@v0.5.1 is the last version to download v11.5.9 clidriver by defualt and first version to support MacOS arm64 platform using v12.1.0 clidriver. +* There is no MacOS Intel Chip clidriver from v12.1.0 onwards. + ## How to Install in Windows - You may install go_ibm_db using either of below commands @@ -30,7 +33,7 @@ yum install go git tar libpam ``` go get -d github.com/ibmdb/go_ibm_db go install github.com/ibmdb/go_ibm_db/installer@latest -go install github.com/ibmdb/go_ibm_db/installer@v0.5.0 +go install github.com/ibmdb/go_ibm_db/installer@v0.5.1 ``` - You can optionally specify a specific cli driver by setting the IBM_DB_DOWNLOAD_URL environment variable @@ -74,7 +77,7 @@ setenvwin.bat ``` go get -d github.com/ibmdb/go_ibm_db go install github.com/ibmdb/go_ibm_db/installer@latest -go install github.com/ibmdb/go_ibm_db/installer@v0.5.0 +go install github.com/ibmdb/go_ibm_db/installer@v0.5.1 ``` - You can optionally specify a specific cli driver by setting the IBM_DB_DOWNLOAD_URL environment @@ -127,15 +130,15 @@ source setenv.sh ``` yum install -y gcc git go wget tar xz make gcc-c++ cd /root -curl -OL https://golang.org/dl/go1.23.1.linux-amd64.tar.gz -tar -C /usr/local -xzf go1.23.1.linux-amd64.tar.gz +curl -OL https://golang.org/dl/go1.23.4.linux-amd64.tar.gz +tar -C /usr/local -xzf go1.23.4.linux-amd64.tar.gz rm /usr/bin/go rm /usr/bin/gofmt cp /usr/local/go/bin/go /usr/bin/ cp /usr/local/go/bin/gofmt /usr/bin/ -go install github.com/ibmdb/go_ibm_db/installer@v0.5.0 +go install github.com/ibmdb/go_ibm_db/installer@v0.5.1 or go install github.com/ibmdb/go_ibm_db/installer@latest ``` diff --git a/installer/setup.go b/installer/setup.go index ad20d6c..d3fa9d0 100644 --- a/installer/setup.go +++ b/installer/setup.go @@ -66,14 +66,20 @@ func Unzipping(sourcefile string, targetDirectory string) { } func linux_untar(clidriver string, targetDirectory string) error { - fmt.Printf("Extracting with tar -xvzf %s -C %s\n", clidriver, targetDirectory) - out, err := exec.Command("tar", "xvzf", "./../../"+clidriver, "-C", targetDirectory).Output() + fmt.Printf("Extracting with tar -xzf %s -C %s\n", clidriver, targetDirectory) + out, err := exec.Command("tar", "xzf", "./../../" + clidriver, "-C", targetDirectory).Output() fmt.Println(string(out)) if err != nil { fmt.Println("Error while running tar: " + err.Error()) return err } + if runtime.GOOS == "darwin" { + // Create symlinks for libdb2 + _, _ = exec.Command("ln", "-s", targetDirectory + "/clidriver/lib/libdb2.dylib", targetDirectory + "/libdb2.dylib").Output() + _, _ = exec.Command("ln", "-s", targetDirectory + "/clidriver/lib/libdb2.dylib", targetDirectory + "/go_ibm_db/libdb2.dylib").Output() + _, _ = exec.Command("ln", "-s", targetDirectory + "/clidriver/lib/libdb2.dylib", targetDirectory + "/go_ibm_db/testdata/libdb2.dylib").Output() + } return nil } @@ -134,42 +140,55 @@ func checkincludepath(includepath string) bool { } func main() { - var target, cliFileName string - var unpackageType int - var err11 error - var out []byte + var target, cliFileName string + var unpackageType int + var err11 error + var out []byte - fmt.Println("NOTE: Environment variable DB2HOME name is changed to IBM_DB_HOME.") + fmt.Println("os =",runtime.GOOS, ", processor =", runtime.GOARCH) + path, ok := os.LookupEnv("DB2HOME") + if ok { + fmt.Println("NOTE: Environment variable DB2HOME name is changed to IBM_DB_HOME.") + fmt.Println("DB2HOME environment variable is set to", path) + } - out, err11 = exec.Command("db2cli", "validate").Output() - if err11 != nil { - _, ok := os.LookupEnv("IBM_DB_HOME") - if !ok { - if runtime.GOOS == "windows" { - fmt.Println("Please set IBM_DB_HOME add this path to PATH environment variable after clidriver installed") - } else { - fmt.Println("Please set IBM_DB_HOME, CGO_CFLAGS, CGO_LDFLAGS and LD_LIBRARY_PATH or DYLD_LIBRARY_PATH environment variables after clidriver installed") - } - } - } else { - path, ok := os.LookupEnv("IBM_DB_HOME") - if !ok { - //set IBM_DB_HOME - getinstalledpath(string(out)) - os.Exit(1) - } else { - fmt.Println("clidriver folder exists in the path....", path) - if checkincludepath(path) { - os.Exit(1) - } - } - } + out, err11 = exec.Command("db2cli", "validate").Output() + if err11 != nil { + _, ok := os.LookupEnv("IBM_DB_HOME") + if !ok { + if runtime.GOOS == "windows" { + fmt.Println("Please set IBM_DB_HOME and add %IBM_DB_HOME%/bin to PATH and %IBM_DB_HOME%/lib to LIB environment variables after clidriver installation") + } else if runtime.GOOS == "aix" { + fmt.Println("Please set IBM_DB_HOME, CGO_CFLAGS, CGO_LDFLAGS and LIBPATH environment variables after clidriver installation") + } else if runtime.GOOS == "darwin" { + fmt.Println("Please set IBM_DB_HOME, CGO_CFLAGS, CGO_LDFLAGS and DYLD_LIBRARY_PATH environment variables after clidriver installation") + } else { + fmt.Println("Please set IBM_DB_HOME, CGO_CFLAGS, CGO_LDFLAGS and LD_LIBRARY_PATH environment variables after clidriver installation") + } + } + } else { + path, ok := os.LookupEnv("IBM_DB_HOME") + if !ok { + //set IBM_DB_HOME + getinstalledpath(string(out)) + os.Exit(1) + } else { + fmt.Println("clidriver folder exists in the path....", path) + if checkincludepath(path) { + os.Exit(1) + } + } + } - if len(os.Args) == 2 { - target = os.Args[1] - } else { - target = "./../.." - } + _, setupFile, _, ok := runtime.Caller(0) + if len(os.Args) == 2 { + target = os.Args[1] + } else if ok { + target = filepath.Dir(setupFile) + "/../.." + target, _ = filepath.Abs(target) + } else { + target = "./../.." + } if _, err1 := os.Stat(target + "/clidriver"); !os.IsNotExist(err1) { fmt.Println("clidriver folder exists in the path") @@ -196,7 +215,6 @@ func main() { } else { cliFileName = "nt32_odbc_cli.zip" } - fmt.Printf("windows\n") fmt.Println(cliFileName) } else if runtime.GOOS == "linux" { unpackageType = 2 @@ -227,7 +245,6 @@ func main() { cliFileName = "s390_odbc_cli.tar.gz" } } - fmt.Printf("linux\n") fmt.Println(cliFileName) } else if runtime.GOOS == "aix" { unpackageType = 3 @@ -237,7 +254,6 @@ func main() { } else { cliFileName = "aix32_odbc_cli.tar.gz" } - fmt.Printf("aix\n") fmt.Println(cliFileName) } else if runtime.GOOS == "sunos" { unpackageType = 2 @@ -256,19 +272,21 @@ func main() { cliFileName = "sun32_odbc_cli.tar.gz" } } - fmt.Printf("Sunos\n") fmt.Printf(cliFileName) } else if runtime.GOOS == "darwin" { - unpackageType = 2 - const wordsize = 32 << (^uint(0) >> 32 & 1) - if wordsize == 64 { - cliFileName = "macos64_odbc_cli.tar.gz" - } - fmt.Println("darwin") - } else { - fmt.Println("not known platform") - os.Exit(3) - } + unpackageType = 2 + const wordsize = 32 << (^uint(0) >> 32 & 1) + if wordsize == 64 { + if runtime.GOARCH == "arm64" { + cliFileName = "macarm64_odbc_cli.tar.gz" + } else { + cliFileName = "macos64_odbc_cli.tar.gz" + } + } + } else { + fmt.Println("Error: Unsupported platform!") + os.Exit(3) + } fileUrl := downloadUrl(cliFileName) fmt.Println("Downloading " + fileUrl) err := downloadFile(cliFileName, fileUrl) @@ -290,7 +308,22 @@ func main() { func downloadUrl(cliFileName string) string { downloadUrl, downloadUrlFound := os.LookupEnv("IBM_DB_DOWNLOAD_URL") if !downloadUrlFound { - downloadUrl = "https://public.dhe.ibm.com/ibmdl/export/pub/software/data/db2/drivers/odbc_cli/" + cliFileName + clidriverVersion, ok := os.LookupEnv("CLIDRIVER_DOWNLOAD_VERSION") + if ok { + if runtime.GOOS == "darwin" && runtime.GOARCH == "arm64" && strings.HasPrefix(strings.ToLower(clidriverVersion), "v11") { + downloadUrl = "https://public.dhe.ibm.com/ibmdl/export/pub/software/data/db2/drivers/odbc_cli/" + cliFileName + } else if runtime.GOOS == "darwin" && runtime.GOARCH != "arm64" && strings.HasPrefix(strings.ToLower(clidriverVersion), "v12") { + downloadUrl = "https://public.dhe.ibm.com/ibmdl/export/pub/software/data/db2/drivers/odbc_cli/" + cliFileName + } else { + downloadUrl = "https://public.dhe.ibm.com/ibmdl/export/pub/software/data/db2/drivers/odbc_cli/" + clidriverVersion + "/" + cliFileName + } + } else { + if runtime.GOOS == "darwin" { + downloadUrl = "https://public.dhe.ibm.com/ibmdl/export/pub/software/data/db2/drivers/odbc_cli/" + cliFileName + } else { + downloadUrl = "https://public.dhe.ibm.com/ibmdl/export/pub/software/data/db2/drivers/odbc_cli/v11.5.9/" + cliFileName + } + } } return downloadUrl }