0033378: Configuration - Moving ExpToCas into separate module
[occt.git] / adm / scripts / macos_build.sh
1 #!/bin/bash
2
3 # Auxiliary script for semi-automated building of OCCT for macOS platform.
4 # macos_custom.sh should be configured with paths to CMake and other 3rd-parties.
5 # FreeType should be specified as mandatory dependency.
6
7 aScriptDir=${BASH_SOURCE%/*}
8 if [ -d "$aScriptDir" ]; then cd "$aScriptDir"; fi
9 aScriptDir="$PWD"
10
11 aCasSrc=${aScriptDir}/../..
12 aNbJobs="$(getconf _NPROCESSORS_ONLN)"
13
14 export aBuildRoot=work
15
16 # paths to pre-built 3rd-parties
17 export aFreeType=
18 export aFreeImage=
19 export aRapidJson=
20 export aDraco=
21
22 # build stages to perform
23 export isStatic=0
24 export toCMake=1
25 export toClean=1
26 export toMake=1
27 export toInstall=1
28 export toPack=0
29 export toPackFat=0
30 export toDebug=0
31
32 export BUILD_ModelingData=ON
33 export BUILD_ModelingAlgorithms=ON
34 export BUILD_Visualization=ON
35 export BUILD_ApplicationFramework=ON
36 export BUILD_DataExchange=ON
37 export BUILD_DETools=OFF
38 export BUILD_Draw=ON
39
40 export USE_FREETYPE=ON
41 export USE_FREEIMAGE=ON
42 export USE_RAPIDJSON=OFF
43 export USE_DRACO=OFF
44
45 export MACOSX_DEPLOYMENT_TARGET=10.10
46 #export anAbiList="arm64 x86_64"
47 export anAbiList="x86_64"
48 aPlatform="macos"
49
50 if [[ -f "${aScriptDir}/macos_custom.sh" ]]; then
51   source "${aScriptDir}/macos_custom.sh"
52 fi
53
54 anOcctVerSuffix=`grep -e "#define OCC_VERSION_DEVELOPMENT" "$aCasSrc/src/Standard/Standard_Version.hxx" | awk '{print $3}' | xargs`
55 anOcctVersion=`grep -e "#define OCC_VERSION_COMPLETE" "$aCasSrc/src/Standard/Standard_Version.hxx" | awk '{print $3}' | xargs`
56 aGitBranch=`git symbolic-ref --short HEAD`
57
58 YEAR=$(date +"%Y")
59 MONTH=$(date +"%m")
60 DAY=$(date +"%d")
61 aRevision=-${YEAR}-${MONTH}-${DAY}
62 #aRevision=-${aGitBranch}
63
64 set -o pipefail
65
66 aBuildType="Release"
67 aBuildTypePrefix=
68 if [[ $toDebug == 1 ]]; then
69   aBuildType="Debug"
70   aBuildTypePrefix="-debug"
71 fi
72 aLibType="Shared"
73 aLibExt="dylib"
74 if [[ $isStatic == 1 ]]; then
75   aLibType="Static"
76   aLibExt="a"
77 fi
78
79 function buildArch {
80   anAbi=$1
81
82   aPlatformAndCompiler=${aPlatform}-${anAbi}${aBuildTypePrefix}-clang
83
84   aWorkDir="${aCasSrc}/${aBuildRoot}/${aPlatformAndCompiler}-make"
85   aDestDir="${aCasSrc}/${aBuildRoot}/${aPlatformAndCompiler}"
86   aLogFile="${aCasSrc}/${aBuildRoot}/build-${aPlatformAndCompiler}.log"
87
88   if [[ $toCMake == 1 ]] && [[ $toClean == 1 ]]; then
89     rm -r -f "$aWorkDir"
90     rm -r -f "$aDestDir"
91   fi
92   mkdir -p "$aWorkDir"
93   mkdir -p "$aDestDir"
94   rm -f "$aLogFile"
95
96   # include some information about OCCT into archive
97   echo \<pre\>> "${aWorkDir}/VERSION.html"
98   git status >> "${aWorkDir}/VERSION.html"
99   git log -n 100 >> "${aWorkDir}/VERSION.html"
100   echo \</pre\>>> "${aWorkDir}/VERSION.html"
101
102   pushd "$aWorkDir"
103
104   aTimeZERO=$SECONDS
105
106   function logDuration {
107     if [[ $1 == 1 ]]; then
108       aDur=$(($4 - $3))
109       echo $2 time: $aDur sec>> "$aLogFile"
110     fi
111   }
112
113   # (re)generate Make files
114   if [[ $toCMake == 1 ]]; then
115     echo Configuring OCCT for macOS...
116     cmake -G "Unix Makefiles" \
117   -D CMAKE_OSX_ARCHITECTURES:STRING="$anAbi" \
118   -D CMAKE_BUILD_TYPE:STRING="$aBuildType" \
119   -D BUILD_LIBRARY_TYPE:STRING="$aLibType" \
120   -D INSTALL_DIR:PATH="$aDestDir" \
121   -D INSTALL_DIR_INCLUDE:STRING="inc" \
122   -D INSTALL_DIR_LIB:STRING="lib" \
123   -D INSTALL_DIR_RESOURCE:STRING="src" \
124   -D INSTALL_NAME_DIR:STRING="@executable_path/../Frameworks" \
125   -D USE_FREETYPE:BOOL="$USE_FREETYPE" \
126   -D 3RDPARTY_FREETYPE_DIR:PATH="$aFreeType" \
127   -D 3RDPARTY_FREETYPE_INCLUDE_DIR_freetype2:FILEPATH="$aFreeType/include" \
128   -D 3RDPARTY_FREETYPE_INCLUDE_DIR_ft2build:FILEPATH="$aFreeType/include" \
129   -D 3RDPARTY_FREETYPE_LIBRARY_DIR:PATH="$aFreeType/lib" \
130   -D 3RDPARTY_FREETYPE_LIBRARY:FILEPATH="$aFreeType/lib/libfreetype.dylib" \
131   -D USE_RAPIDJSON:BOOL="$USE_RAPIDJSON" \
132   -D 3RDPARTY_RAPIDJSON_DIR:PATH="$aRapidJson" \
133   -D 3RDPARTY_RAPIDJSON_INCLUDE_DIR:PATH="$aRapidJson/include" \
134   -D USE_DRACO:BOOL="$USE_DRACO" \
135   -D 3RDPARTY_DRACO_DIR:PATH="$aDraco" \
136   -D 3RDPARTY_DRACO_INCLUDE_DIR:FILEPATH="$aDraco/include" \
137   -D 3RDPARTY_DRACO_LIBRARY_DIR:PATH="$aDraco/lib" \
138   -D USE_FREEIMAGE:BOOL="$USE_FREEIMAGE" \
139   -D 3RDPARTY_FREEIMAGE_DIR:PATH="$aFreeImage" \
140   -D 3RDPARTY_FREEIMAGE_INCLUDE_DIR:FILEPATH="$aFreeImage/include" \
141   -D 3RDPARTY_FREEIMAGE_LIBRARY_DIR:PATH="$aFreeImage/lib" \
142   -D 3RDPARTY_FREEIMAGE_LIBRARY:FILEPATH="$aFreeImage/lib/libfreeimage.a" \
143   -D BUILD_MODULE_FoundationClasses:BOOL="ON" \
144   -D BUILD_MODULE_ModelingData:BOOL="${BUILD_ModelingData}" \
145   -D BUILD_MODULE_ModelingAlgorithms:BOOL="${BUILD_ModelingAlgorithms}" \
146   -D BUILD_MODULE_Visualization:BOOL="${BUILD_Visualization}" \
147   -D BUILD_MODULE_ApplicationFramework:BOOL="${BUILD_ApplicationFramework}" \
148   -D BUILD_MODULE_DataExchange:BOOL="${BUILD_DataExchange}" \
149   -D BUILD_MODULE_DETools:BOOL="${BUILD_DETools}" \
150   -D BUILD_MODULE_Draw:BOOL="${BUILD_Draw}" \
151   -D BUILD_DOC_Overview:BOOL="OFF" \
152     "$aCasSrc" 2>&1 | tee -a "$aLogFile"
153     aResult=$?; if [[ $aResult != 0 ]]; then exit $aResult; fi
154   fi
155   aTimeGEN=$SECONDS
156   logDuration $toCMake "Generation" $aTimeZERO $aTimeGEN
157
158   # clean up from previous build
159   if [[ $toClean == 1 ]]; then
160     make clean
161   fi
162
163   # build the project
164   if [[ $toMake == 1 ]]; then
165     echo Building OCCT...
166     make -j $aNbJobs 2>&1 | tee -a "$aLogFile"
167     aResult=$?; if [[ $aResult != 0 ]]; then exit $aResult; fi
168   fi
169   aTimeBUILD=$SECONDS
170   logDuration $toMake "Building"       $aTimeGEN  $aTimeBUILD
171   logDuration $toMake "Total building" $aTimeZERO $aTimeBUILD
172
173   # install the project
174   if [[ $toInstall == 1 ]]; then
175     echo Installing OCCT into $aDestDir...
176     make install 2>&1 | tee -a "$aLogFile"
177     cp -f "$aWorkDir/VERSION.html" "$aDestDir/VERSION.html"
178     echo Platform: macOS ABI: ${anAbi} Build: ${aBuildType} MACOSX_DEPLOYMENT_TARGET: ${MACOSX_DEPLOYMENT_TARGET} > "$aDestDir/build_target.txt"
179   fi
180   aTimeINSTALL=$SECONDS
181   logDuration $toInstall "Install" $aTimeBUILD $aTimeINSTALL
182
183   # create an archive
184   if [[ $toPack == 1 ]]; then
185     anArchName=occt-${anOcctVersion}${anOcctVerSuffix}${aRevision}-${aPlatformAndCompiler}.tar.bz2
186     echo Creating an archive ${aCasSrc}/${aBuildRoot}/${anArchName}...
187     rm ${aDestDir}/../${anArchName} &>/dev/null
188     pushd "$aDestDir"
189     tar -jcf ${aDestDir}/../${anArchName} *
190     popd
191   fi
192   aTimePACK=$SECONDS
193   logDuration $toPack "Packing archive" $aTimeINSTALL $aTimePACK
194
195   # finished
196   DURATION=$(($aTimePACK - $aTimeZERO))
197   echo Total time: $DURATION sec
198   logDuration 1 "Total" $aTimeZERO $aTimePACK
199
200   popd
201 }
202
203 for anArchIter in $anAbiList
204 do
205   echo Platform: macOS ABI: ${anArchIter} Build: ${aBuildType}
206   buildArch $anArchIter
207 done
208
209 # create a FAT archive
210 if [[ $toPackFat == 1 ]]; then
211   aSuffixFat=${aPlatform}${aBuildTypePrefix}-clang
212   aFatDir="${aCasSrc}/${aBuildRoot}/${aSuffixFat}"
213
214   # merge per-arch builds into fat builds
215   hasPlatform=0
216   for anArchIter in $anAbiList
217   do
218     aSuffixThin=${aPlatform}-${anArchIter}${aBuildTypePrefix}-clang
219     anArchDir="${aCasSrc}/${aBuildRoot}/${aSuffixThin}"
220     if [[ $hasPlatform == 0 ]]; then
221       hasPlatform=1
222       echo Packing FAT archive
223       rm -r -f "$aFatDir"
224       mkdir -p "$aFatDir"
225       if [[ $isStatic == 1 ]]; then
226         rsync -r -l --exclude '*.a' "$anArchDir/" "$aFatDir"
227       else
228         rsync -r -l --exclude '*.dylib' "$anArchDir/" "$aFatDir"
229       fi
230       rm -f "$aFatDir/build_target.txt"
231
232       if [[ -L "$anArchDir/bin/DRAWEXE" ]]; then
233         aDrawExe=$(readlink "$anArchDir/bin/DRAWEXE")
234         rm $aFatDir/bin/$aDrawExe
235         lipo "$anArchDir/bin/$aDrawExe" -output "$aFatDir/bin/$aDrawExe" -create
236       fi
237
238       for aLibIter in $anArchDir/lib/*.$aLibExt; do
239         aLibName=`basename $aLibIter`
240         if [[ -L "$anArchDir/lib/$aLibName" ]]; then
241           cp -a "$anArchDir/lib/$aLibName" "$aFatDir/lib/"
242         else
243           lipo "$anArchDir/lib/$aLibName" -output "$aFatDir/lib/$aLibName" -create
244         fi
245       done
246     else
247       if [[ -L "$anArchDir/bin/DRAWEXE" ]]; then
248         aDrawExe=$(readlink "$anArchDir/bin/DRAWEXE")
249         lipo "$aFatDir/bin/$aDrawExe" "$anArchDir/bin/$aDrawExe" -output "$aFatDir/bin/$aDrawExe" -create
250       fi
251
252       for aLibIter in $aFatDir/lib/*.$aLibExt; do
253         aLibName=`basename $aLibIter`
254         if [[ ! -L "$anArchDir/lib/$aLibName" ]]; then
255           lipo "$aFatDir/lib/$aLibName" "$anArchDir/lib/$aLibName" -output "$aFatDir/lib/$aLibName" -create
256           #lipo -info "$aFatDir/lib/$aLibName"
257         fi
258       done
259     fi
260     cat "$anArchDir/build_target.txt" >> "$aFatDir/build_target.txt"
261   done
262
263   # create an archive
264   anArchName=occt-${anOcctVersion}${anOcctVerSuffix}${aRevision}-${aSuffixFat}.tar.bz2
265   echo Creating an archive ${aCasSrc}/${aBuildRoot}/${anArchName}...
266   rm ${aFatDir}/../${anArchName} &>/dev/null
267   pushd "$aFatDir"
268   tar -jcf ${aFatDir}/../${anArchName} *
269   popd
270 fi