diff --git a/.gitignore b/.gitignore index 2c5e2e40be..3b83ce65bc 100644 --- a/.gitignore +++ b/.gitignore @@ -3,5 +3,8 @@ /build*/ /install*/ /win/BuildDepsCache*.txt +# IfcExpressParser residue /src/ifcexpressparser/__pycache__ /src/ifcexpressparser/express_parser.py +# Python test residue +/test/__pycache__ diff --git a/README.md b/README.md index 696cd75be4..10d03630a1 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ IfcOpenShell ============ -Open source (LGPL) software library for working with the IFC file format. +Open source (LGPL) software library for working with the IFC ([IFC2x3 TC1] and [IFC4]) file format. [http://ifcopenshell.org](http://ifcopenshell.org) [http://academy.ifcopenshell.org](http://academy.ifcopenshell.org) @@ -8,22 +8,22 @@ Open source (LGPL) software library for working with the IFC file format. Prerequisites ============= -* Git, CMake (2.6 or newer), Visual Studio 2008 or newer (Windows), or GCC (*nix, Clang untested). +* Git, CMake (2.6 or newer), Visual Studio 2008 or newer with C++ toolset (Windows), or GCC (*nix, Clang untested). Dependencies ============ * [Boost](http://www.boost.org/) -* Open Cascade *optional*, but required for building IfcGeom - [Official](http://www.opencascade.org/getocc/download/loadocc/) or [community edition](https://github.com/tpaviot/oce) +* Open Cascade - *optional*, but required for building IfcGeom + ([official](http://www.opencascade.org/getocc/download/loadocc/) or [community edition](https://github.com/tpaviot/oce)) For converting IFC representation items into BRep solids and tesselated meshes -* [ICU](http://site.icu-project.org/) *optional* +* [ICU](http://site.icu-project.org/) - *optional* For handling code pages and Unicode in the parser -* [OpenCOLLADA](https://github.com/khronosGroup/OpenCOLLADA/) *optional* +* [OpenCOLLADA](https://github.com/khronosGroup/OpenCOLLADA/) - *optional* For IfcConvert to be able to write tessellated Collada (.dae) files -* [SWIG](http://www.swig.org/), [Python](https://www.python.org/) libraries *optional* +* [SWIG](http://www.swig.org/), [Python](https://www.python.org/) libraries - *optional* For building the IfcOpenShell Python interface and the Blender add-on -* 3ds Max SDK *optional* +* 3ds Max SDK - *optional* For building the 3ds Max plug-in @@ -92,7 +92,10 @@ To build IfcOpenShell please take the following steps: $ cmake ../ $ make -If all worked out correctly you can now use IfcOpenShell. For example: +If all worked out correctly you can now use IfcOpenShell. See the examples below. + +Usage examples +============== **Invoking IfcConvert from the command line** @@ -101,8 +104,6 @@ If all worked out correctly you can now use IfcOpenShell. For example: $ ./IfcConvert Munkerud_hus6_BE.ifc $ less Munkerud_hus6_BE.obj -Or: - **Using the IfcOpenShell Python interface** $ wget -O duplex.zip http://projects.buildingsmartalliance.org/files/?artifact_id=4278 @@ -164,4 +165,6 @@ Or: >>> # Writing IFC-SPF files to disk: >>> f.write("out.ifc") -[win/readme.md]: https://github.com/IfcOpenShell/IfcOpenShell/tree/master/win/readme.md "win/readme.md" \ No newline at end of file +[win/readme.md]: https://github.com/IfcOpenShell/IfcOpenShell/tree/master/win/readme.md "win/readme.md" +[IFC2x3 TC1]: http://www.buildingsmart-tech.org/specifications/ifc-releases/ifc2x3-tc1-release "IFC2x3 TC1" +[IFC4]: http://www.buildingsmart-tech.org/specifications/ifc-releases/ifc4-release "IFC4" \ No newline at end of file diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index ef6fc19f60..a232058a13 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -28,6 +28,7 @@ OPTION(ENABLE_BUILD_OPTIMIZATIONS "Enable certain compiler and linker optimizati OPTION(USE_IFC4 "Use IFC 4 instead of IFC 2x3 (full rebuild recommended when switching this)" OFF) OPTION(BUILD_IFCPYTHON "Build IfcPython." ON) OPTION(BUILD_EXAMPLES "Build example applications." ON) +OPTION(USE_VLD "Use Visual Leak Detector for debugging memory leaks, MSVC-only." OFF) # TODO QtViewer is deprecated ATM as it uses the 0.4 API # OPTION(BUILD_QTVIEWER "Build IfcOpenShell Qt GUI Viewer (requires Qt 4 framework)." OFF) @@ -237,6 +238,9 @@ if(ENABLE_BUILD_OPTIMIZATIONS) endif() IF(MSVC) + IF(USE_VLD) + ADD_DEFINITIONS(-DUSE_VLD) + ENDIF() # Enforce Unicode for CRT and Win32 API calls ADD_DEFINITIONS(-D_UNICODE -DUNICODE) # Disable warnings about unsafe C functions; we could use the safe C99 & C11 versions if we have no need for supporting old compilers. @@ -272,14 +276,22 @@ endif() IF(USE_IFC4) ADD_DEFINITIONS(-DUSE_IFC4) + SET(IFC_RELEASE_NOT_USED "2x3") ELSE() ADD_DEFINITIONS(-DUSE_IFC2x3) # TODO Make all caps? i.e. USE_IFC2X3 + SET(IFC_RELEASE_NOT_USED "4") ENDIF() # IfcParse file(GLOB CPP_FILES ../src/ifcparse/*.cpp) file(GLOB H_FILES ../src/ifcparse/*.h) set(SOURCE_FILES ${CPP_FILES} ${H_FILES}) +# Remove sources specific to an IFC release we are not using +list(REMOVE_ITEM SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../src/ifcparse/Ifc${IFC_RELEASE_NOT_USED}.h) +list(REMOVE_ITEM SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../src/ifcparse/Ifc${IFC_RELEASE_NOT_USED}enum.h) +list(REMOVE_ITEM SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../src/ifcparse/Ifc${IFC_RELEASE_NOT_USED}-latebound.h) +list(REMOVE_ITEM SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../src/ifcparse/Ifc${IFC_RELEASE_NOT_USED}.cpp) +list(REMOVE_ITEM SOURCE_FILES ${CMAKE_CURRENT_SOURCE_DIR}/../src/ifcparse/Ifc${IFC_RELEASE_NOT_USED}-latebound.cpp) ADD_LIBRARY(IfcParse STATIC ${SOURCE_FILES}) IF(UNICODE_SUPPORT) TARGET_LINK_LIBRARIES(IfcParse ${ICU_LIBRARIES}) diff --git a/src/examples/IfcOpenHouse.cpp b/src/examples/IfcOpenHouse.cpp index af9de2bebe..c7414e76e7 100644 --- a/src/examples/IfcOpenHouse.cpp +++ b/src/examples/IfcOpenHouse.cpp @@ -41,6 +41,10 @@ #include "../ifcparse/IfcHierarchyHelper.h" #include "../ifcgeom/IfcGeom.h" +#if USE_VLD +#include +#endif + // Some convenience typedefs and definitions. typedef std::string S; typedef IfcParse::IfcGlobalId guid; diff --git a/src/examples/IfcParseExamples.cpp b/src/examples/IfcParseExamples.cpp index 342a6e8674..7ae158a67f 100644 --- a/src/examples/IfcParseExamples.cpp +++ b/src/examples/IfcParseExamples.cpp @@ -19,6 +19,10 @@ #include "../ifcparse/IfcFile.h" +#if USE_VLD +#include +#endif + using namespace IfcSchema; int main(int argc, char** argv) { diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index 73ecb1ad95..8f1e285ea8 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -46,6 +46,10 @@ #include #include +#if USE_VLD +#include +#endif + static std::string DEFAULT_EXTENSION = "obj"; void printVersion() { diff --git a/src/ifcgeom/IfcGeomFunctions.cpp b/src/ifcgeom/IfcGeomFunctions.cpp index b70808fc77..1ed8ee1627 100644 --- a/src/ifcgeom/IfcGeomFunctions.cpp +++ b/src/ifcgeom/IfcGeomFunctions.cpp @@ -1275,8 +1275,7 @@ std::pair IfcGeom::Kernel::initializeUnits(IfcSchema::IfcUn } const IfcSchema::IfcRepresentationItem* IfcGeom::Kernel::find_item_carrying_style(const IfcSchema::IfcRepresentationItem* item) { - IfcSchema::IfcStyledItem::list::ptr styles = item->StyledByItem(); - if (styles->size()) { + if (item->StyledByItem()->size()) { return item; } @@ -1284,9 +1283,7 @@ const IfcSchema::IfcRepresentationItem* IfcGeom::Kernel::find_item_carrying_styl // All instantiations of IfcBooleanOperand (type of FirstOperand) are subtypes of // IfcGeometricRepresentationItem item = (IfcSchema::IfcGeometricRepresentationItem*) ((IfcSchema::IfcBooleanClippingResult*) item)->FirstOperand(); - - IfcSchema::IfcStyledItem::list::ptr styles = item->StyledByItem(); - if (styles->size()) { + if (item->StyledByItem()->size()) { return item; } } @@ -1297,4 +1294,4 @@ const IfcSchema::IfcRepresentationItem* IfcGeom::Kernel::find_item_carrying_styl // distinctly styled union operands. return item; -} \ No newline at end of file +} diff --git a/src/ifcgeomserver/IfcGeomServer.cpp b/src/ifcgeomserver/IfcGeomServer.cpp index fa3a356b4d..975c3c471e 100644 --- a/src/ifcgeomserver/IfcGeomServer.cpp +++ b/src/ifcgeomserver/IfcGeomServer.cpp @@ -37,6 +37,10 @@ #include "../ifcgeom/IfcGeomIterator.h" +#if USE_VLD +#include +#endif + using namespace boost; template diff --git a/src/ifcparse/IfcCharacterDecoder.cpp b/src/ifcparse/IfcCharacterDecoder.cpp index a3388e6cc5..f45c941528 100644 --- a/src/ifcparse/IfcCharacterDecoder.cpp +++ b/src/ifcparse/IfcCharacterDecoder.cpp @@ -118,6 +118,7 @@ IfcCharacterDecoder::~IfcCharacterDecoder() { destination = 0; converter = 0; compatibility_converter = 0; + ucnv_flushCache(); #endif } IfcCharacterDecoder::operator std::string() { diff --git a/src/ifcparse/IfcParse.cpp b/src/ifcparse/IfcParse.cpp index 764d5143fb..a32f64baad 100644 --- a/src/ifcparse/IfcParse.cpp +++ b/src/ifcparse/IfcParse.cpp @@ -127,6 +127,11 @@ IfcSpfStream::IfcSpfStream(void* data, int l) { len = l; } +IfcSpfStream::~IfcSpfStream() +{ + Close(); +} + void IfcSpfStream::Close() { #ifdef BUF_SIZE if ( paging ) fclose(stream); diff --git a/src/ifcparse/IfcParse.h b/src/ifcparse/IfcParse.h index 2733f26d83..16907cf786 100644 --- a/src/ifcparse/IfcParse.h +++ b/src/ifcparse/IfcParse.h @@ -248,7 +248,7 @@ namespace IfcParse { unsigned int offset; Entity(unsigned int i, IfcFile* t); Entity(unsigned int i, IfcFile* t, unsigned int o); - ~Entity(); + virtual ~Entity(); IfcEntityList::ptr getInverse(IfcSchema::Type::Enum type, int attribute_index); void Load(std::vector& ids, bool seek=false) const; Argument* getArgument (unsigned int i); diff --git a/src/ifcparse/IfcSpfHeader.h b/src/ifcparse/IfcSpfHeader.h index 0b349003f5..44eb719932 100644 --- a/src/ifcparse/IfcSpfHeader.h +++ b/src/ifcparse/IfcSpfHeader.h @@ -43,7 +43,7 @@ protected: } } - ~HeaderEntity() { + virtual ~HeaderEntity() { delete _list; } @@ -166,7 +166,14 @@ public: _file_name = new FileName(); _file_schema = new FileSchema(); } - + + ~IfcSpfHeader() + { + delete _file_schema; + delete _file_name; + delete _file_description; + } + IfcSpfLexer* lexer() { return _lexer; } void lexer(IfcSpfLexer* l) { _lexer = l; } diff --git a/src/ifcparse/IfcSpfStream.h b/src/ifcparse/IfcSpfStream.h index 9f5799f2a2..a3d947606c 100644 --- a/src/ifcparse/IfcSpfStream.h +++ b/src/ifcparse/IfcSpfStream.h @@ -64,6 +64,7 @@ namespace IfcParse { IfcSpfStream(const std::string& fn); IfcSpfStream(std::istream& f, int len); IfcSpfStream(void* data, int len); + ~IfcSpfStream(); /// Returns the character at the cursor char Peek(); /// Returns the character at specified offset diff --git a/win/build-all.cmd b/win/build-all.cmd new file mode 100644 index 0000000000..4f29f0edd3 --- /dev/null +++ b/win/build-all.cmd @@ -0,0 +1,44 @@ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: :: +:: This file is part of IfcOpenShell. :: +:: :: +:: IfcOpenShell is free software: you can redistribute it and/or modify :: +:: it under the terms of the Lesser GNU General Public License as published by :: +:: the Free Software Foundation, either version 3.0 of the License, or :: +:: (at your option) any later version. :: +:: :: +:: IfcOpenShell is distributed in the hope that it will be useful, :: +:: but WITHOUT ANY WARRANTY; without even the implied warranty of :: +:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the :: +:: Lesser GNU General Public License for more details. :: +:: :: +:: You should have received a copy of the Lesser GNU General Public License :: +:: along with this program. If not, see . :: +:: :: +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +:: The first argument is assumed to be a CMake generator and it is passed for build-deps, run-cmake, build-ifcopenshell, +:: and install-ifcopenshell. The second argument is assumed to be a build configuration type and it is passed for build-deps, +:: build-ifcopenshell and install-ifcopenshell. The rest of the arguments are passed for run-cmake. +:: Usage example for doing an optimized vs2015-x64 build with debug information and using IFC 4: +:: > build-all.cmd vs2015-x64 RelWithDebInfo -DUSE_IFC4=1 -DENABLE_BUILD_OPTIMIZATIONS=1 + +@echo off + +setlocal EnableDelayedExpansion + +call vs-cfg.cmd %1 +if not %ERRORLEVEL%==0 GOTO :Error +:: Use "yes" trick to break the pause in build-deps.cmd +echo y | call .\build-deps %1 %2 +if not %ERRORLEVEL%==0 goto :EOF +:: Same trick as in run-cmake.bat +set ARGUMENTS=%* +if not (%1)==() call set ARGUMENTS=%%ARGUMENTS:%1=%% +if not (%2)==() call set ARGUMENTS=%%ARGUMENTS:%2=%% +call .\run-cmake %1 %ARGUMENTS% +if not %ERRORLEVEL%==0 goto :EOF +call .\build-ifcopenshell %1 %2 +ECHO %ERRORLEVEL% +if not %ERRORLEVEL%==0 goto :EOF +call .\install-ifcopenshell %1 %2 diff --git a/win/build-deps.cmd b/win/build-deps.cmd index 655163ab26..b145347bf9 100644 --- a/win/build-deps.cmd +++ b/win/build-deps.cmd @@ -33,21 +33,25 @@ setlocal EnableDelayedExpansion :: Make sure vcvarsall.bat is called and dev env set is up. IF "%VSINSTALLDIR%"=="" ( - call utils\cecho.cmd 0 12 "Visual Studio environment variables not set - cannot proceed!" + call utils\cecho.cmd 0 12 "Visual Studio environment variables not set- cannot proceed." GOTO :ErrorAndPrintUsage ) +:: Check for cl.exe - at least the "Typical" Visual Studio 2015 installation does not include the C++ toolset by default, +:: http://blogs.msdn.com/b/vcblog/archive/2015/07/24/setup-changes-in-visual-studio-2015-affecting-c-developers.aspx +where cl.exe 2>&1>NUL +if not %ERRORLEVEL%==0 ( + call utils\cecho.cmd 0 12 "%~nx0: cl.exe not in PATH. Make sure to select the C++ toolset when installing Visual Studio- cannot proceed." + GOTO :ErrorAndPrintUsage +) + :: Set up variables depending on the used Visual Studio version -call vs-cfg.cmd %1 %2 +call vs-cfg.cmd %1 +IF NOT %ERRORLEVEL%==0 GOTO :Error +call build-type-cfg.cmd %2 IF NOT %ERRORLEVEL%==0 GOTO :Error set BUILD_TYPE=%3 - -IF %GENERATOR%=="" ( - call cecho.cmd 0 12 "GENERATOR not specified - cannot proceed!" - GOTO :Error -) - IF "%BUILD_TYPE%"=="" set BUILD_TYPE=Build IF NOT "!BUILD_TYPE!"=="Build" IF NOT "!BUILD_TYPE!"=="Rebuild" IF NOT "!BUILD_TYPE!"=="Clean" ( @@ -63,9 +67,9 @@ IF NOT EXIST %INSTALL_DIR%. mkdir %INSTALL_DIR% IF %VS_VER%==2008 set PATH=C:\Windows\Microsoft.NET\Framework\v3.5;%PATH% :: User-configurable build options -IF "%IFCOS_INSTALL_PYTHON%"=="" set IFCOS_INSTALL_PYTHON=TRUE -IF "%IFCOS_USE_PYTHON2%"=="" set IFCOS_USE_PYTHON2=FALSE -IF "%IFCOS_NUM_BUILD_PROCS%"=="" set IFCOS_NUM_BUILD_PROCS=%NUMBER_OF_PROCESSORS% +IF NOT DEFINED IFCOS_INSTALL_PYTHON set IFCOS_INSTALL_PYTHON=TRUE +IF NOT DEFINED IFCOS_USE_PYTHON2 set IFCOS_USE_PYTHON2=FALSE +IF NOT DEFINED IFCOS_NUM_BUILD_PROCS set IFCOS_NUM_BUILD_PROCS=%NUMBER_OF_PROCESSORS% :: For subroutines set MSBUILD_CMD=MSBuild.exe /nologo /m:%IFCOS_NUM_BUILD_PROCS% /t:%BUILD_TYPE% @@ -115,8 +119,13 @@ call cecho.cmd 0 14 "Warning: You will need roughly 8 GB of disk space to procee echo. call cecho.cmd black cyan "If you are not ready with the above, press Ctrl-C to abort!" + pause echo. +set START_TIME=%TIME% +echo Build started at %START_TIME%. +set BUILD_STARTED=TRUE +echo. cd %DEPS_DIR% @@ -297,6 +306,7 @@ IF EXIST "%DEPS_DIR%\swigwin\". robocopy "%DEPS_DIR%\swigwin" "%INSTALL_DIR%\swi :Successful echo. call %~dp0\utils\cecho.cmd 0 10 "%PROJECT_NAME% dependencies built." +set IFCOS_SCRIPT_RET=0 goto :Finish :ErrorAndPrintUsage @@ -305,13 +315,30 @@ call :PrintUsage :Error echo. call %~dp0\utils\cecho.cmd 0 12 "An error occurred! Aborting!" +set IFCOS_SCRIPT_RET=1 goto :Finish :Finish +:: Print end time and elapsed time, http://stackoverflow.com/a/9935540 +if not defined BUILD_STARTED goto :BuildTimeSkipped +set END_TIME=%TIME% +for /F "tokens=1-4 delims=:.," %%a in ("%START_TIME%") do ( + set /A "start=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100" +) +for /F "tokens=1-4 delims=:.," %%a in ("%END_TIME%") do ( + set /A "end=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100" +) +set /A elapsed=end-start +set /A hh=elapsed/(60*60*100), rest=elapsed%%(60*60*100), mm=rest/(60*100), rest%%=60*100, ss=rest/100, cc=rest%%100 +if %mm% lss 10 set mm=0%mm% +if %ss% lss 10 set ss=0%ss% +if %cc% lss 10 set cc=0%cc% +echo. +echo Build ended at %END_TIME%. Time elapsed %hh%:%mm%:%ss%.%cc%. +:BuildTimeSkipped set PATH=%ORIGINAL_PATH% cd %~dp0 -endlocal -goto :EOF +exit /b %IFCOS_SCRIPT_RET% ::::::::::::::::::::::::::::::::::::: Subroutines ::::::::::::::::::::::::::::::::::::: @@ -402,7 +429,7 @@ echo 2. Install Git and make sure 'git' is accessible from PATH. echo - http://code.google.com/p/tortoisegit/ echo 3. Install CMake and make sure 'cmake' is accessible from PATH. echo - http://www.cmake.org/ -echo 4. Visual Studio 2008 or newer (2013 or newer recommended). +echo 4. Visual Studio 2008 or newer (2013 or newer recommended) with C++ toolset. echo - https://www.visualstudio.com/ echo 5. Run this batch script with Visual Studio environment variables set. echo - https://msdn.microsoft.com/en-us/library/ms229859(v=vs.110).aspx diff --git a/win/build-ifcopenshell.cmd b/win/build-ifcopenshell.cmd index c08858ae85..632b768dfd 100644 --- a/win/build-ifcopenshell.cmd +++ b/win/build-ifcopenshell.cmd @@ -27,7 +27,9 @@ echo. :: Enable the delayed environment variable expansion needed in VSConfig.cmd. setlocal EnableDelayedExpansion -call vs-cfg.cmd %1 %2 +call vs-cfg.cmd %1 +IF NOT %ERRORLEVEL%==0 GOTO :Error +call build-type-cfg.cmd %2 IF NOT %ERRORLEVEL%==0 GOTO :Error echo. @@ -42,11 +44,13 @@ IF NOT %ERRORLEVEL%==0 GOTO :Error echo. call cecho.cmd 0 10 "%VS_PLATFORM% %BUILD_CFG% %PROJECT_NAME% build finished." +set IFCOS_SCRIPT_RET=0 goto :End :Error echo. call %~dp0\utils\cecho.cmd 0 12 "%VS_PLATFORM% %BUILD_CFG% %PROJECT_NAME% build failed!" +set IFCOS_SCRIPT_RET=1 :End -endlocal +exit /b %IFCOS_SCRIPT_RET% diff --git a/win/build-type-cfg.cmd b/win/build-type-cfg.cmd new file mode 100644 index 0000000000..acb75d64ad --- /dev/null +++ b/win/build-type-cfg.cmd @@ -0,0 +1,60 @@ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: :: +:: This file is part of IfcOpenShell. :: +:: :: +:: IfcOpenShell is free software: you can redistribute it and/or modify :: +:: it under the terms of the Lesser GNU General Public License as published by :: +:: the Free Software Foundation, either version 3.0 of the License, or :: +:: (at your option) any later version. :: +:: :: +:: IfcOpenShell is distributed in the hope that it will be useful, :: +:: but WITHOUT ANY WARRANTY; without even the implied warranty of :: +:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the :: +:: Lesser GNU General Public License for more details. :: +:: :: +:: You should have received a copy of the Lesser GNU General Public License :: +:: along with this program. If not, see . :: +:: :: +::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::: + +:: This script initializes various CMake build configuration type related variables. +:: This batch file expects CMake build configuration type as %1. + +@echo off + +:: Set up variables depending on the used build configuration type. +set BUILD_CFG=%1 + +:: The default build types provided by CMake +set BUILD_CFG_MINSIZEREL=MinSizeRel +set BUILD_CFG_RELEASE=Release +set BUILD_CFG_RELWITHDEBINFO=RelWithDebInfo +set BUILD_CFG_DEBUG=Debug +set BUILD_CFG_DEFAULT=%BUILD_CFG_RELWITHDEBINFO% + +IF "!BUILD_CFG!"=="" ( + set BUILD_CFG=%BUILD_CFG_DEFAULT% + call utils\cecho.cmd 0 14 "%~nx0: Warning: BUILD_CFG not specified - using the default %BUILD_CFG_DEFAULT%" +) +IF NOT !BUILD_CFG!==%BUILD_CFG_MINSIZEREL% IF NOT !BUILD_CFG!==%BUILD_CFG_RELEASE% ( +IF NOT !BUILD_CFG!==%BUILD_CFG_RELWITHDEBINFO% IF NOT !BUILD_CFG!==%BUILD_CFG_DEBUG% ( + call utils\cecho.cmd 0 12 "%~nx0: Invalid or unsupported CMake build configuration type passed: !BUILD_CFG!. Cannot proceed." + exit /b 1 +)) + +:: DEBUG_OR_RELEASE and DEBUG_OR_RELEASE_LOWERCASE are "Debug" and "debug" for Debug build and "Release" and +:: "release" for all of the Release variants. +:: POSTFIX_D, POSTFIX_UNDERSCORE_D and POSTFIX_UNDERSCORE_DEBUG are helpers for performing file copies and +:: checking for existence of files. In release build these variables are empty. +set DEBUG_OR_RELEASE=Release +set DEBUG_OR_RELEASE_LOWERCASE=release +set POSTFIX_D= +set POSTFIX_UNDERSCORE_D= +set POSTFIX_UNDERSCORE_DEBUG= +IF %BUILD_CFG%==Debug ( + set DEBUG_OR_RELEASE=Debug + set DEBUG_OR_RELEASE_LOWERCASE=debug + set POSTFIX_D=d + set POSTFIX_UNDERSCORE_D=_d + set POSTFIX_UNDERSCORE_DEBUG=_debug +) diff --git a/win/install-ifcopenshell.cmd b/win/install-ifcopenshell.cmd index d112772a90..571461dd2b 100644 --- a/win/install-ifcopenshell.cmd +++ b/win/install-ifcopenshell.cmd @@ -27,7 +27,9 @@ echo. :: Enable the delayed environment variable expansion needed in VSConfig.cmd. setlocal EnableDelayedExpansion -call vs-cfg.cmd %1 %2 +call vs-cfg.cmd %1 +IF NOT %ERRORLEVEL%==0 GOTO :Error +call build-type-cfg.cmd %2 IF NOT %ERRORLEVEL%==0 GOTO :Error echo. @@ -42,11 +44,13 @@ IF NOT %ERRORLEVEL%==0 GOTO :Error echo. call cecho.cmd 0 10 "%VS_PLATFORM% %BUILD_CFG% %PROJECT_NAME% installation finished." +set IFCOS_SCRIPT_RET=0 goto :End :Error echo. call %~dp0\utils\cecho.cmd 0 12 "%VS_PLATFORM% %BUILD_CFG% %PROJECT_NAME% installation failed!" +set IFCOS_SCRIPT_RET=1 :End -endlocal +exit /b %IFCOS_SCRIPT_RET% diff --git a/win/readme.md b/win/readme.md index 89a6922be0..f91e3a7bae 100644 --- a/win/readme.md +++ b/win/readme.md @@ -16,13 +16,19 @@ running the script. `build-deps.cmd` expects a CMake generator as `%1` and a build configuration type (`RelWithDebInfo/Release/MinSizeRel/Debug`, defaults to `RelWithDebInfo`) as `%2`. If the generator is not provided, the generator is deduced from the Visual Studio -environment variables. A build type (`Build/Rebuild/Clean`, defaults to `Build`) can be provided as `%3`. See `vs-cfg.cmd` -if you wish to change the defaults. The batch file will create `deps\` and `deps-vs--installed\` -directories to the project root. Debug and release builds of the depedencies can co-exist by simply running -`build-deps.cmd Debug` and `build-deps.cmd `. +environment variables. User-friendly VS generator shorthands are supported, e.g. `vs2013-x86` or `vs2015-x64`, and these are +converted to the appropriate CMake ones by the scripts. A build type (`Build/Rebuild/Clean`, defaults to `Build`) can be +provided as `%3`. See `vs-cfg.cmd` if you wish to change the defaults. The batch file will create `deps\` and +`deps-vs--installed\` directories to the project root. Debug and release builds of the depedencies +can co-exist by simply running `build-deps.cmd Debug` and `build-deps.cmd `. After the dependencies are build, execute `run-cmake.bat`. The batch file expects always a CMake generator as `%1` (if not provided, the same default value as above is used), and the rest of possible parameters are passed as is. +If passing build options for the script, the generator must be always passed as the first option: +``` +> run-cmake.bat vs2015-x64 -DUSE_IFC4=1 -DBUILD_IFCPYTHON=0 +``` + **If you wish to use any library from a custom location, modify the paths in `run-cmake.bat` accordingly**. The batch script will create a folder of form `build-vs-\` which will contain the solution and project files for Visual Studio. @@ -32,13 +38,30 @@ easily more than 2 GBs of RAM while converting. After this, one can build the project using the `IfcOpenShell.sln` file in the build folder. Build the `INSTALL` project if wanted. Convenience batch files `build-ifcopenshell.cmd` and `install-ifcopenshell.cmd` can also be used. The batch files -expect `%1` and `%2` in same fashion as above and possible extra parameters are passed for the `MSBuild`call. The project will +expect `%1` and `%2` in same fashion as above and possible extra parameters are passed for the `MSBuild` call. The project will be installed to `installed-vs-\` folder in the project's root folder and the required IfcOpenShell-Python parts are deployed to the `\Lib\site-packages\` folder. **Note:** All of the dependencies are build as static libraries against the static run-time allowing the developer to effortlessly deploy standalone IFCOS binaries. +Using an already existing Python installation +--------------------------------------------- + +Let's say you have already installed 64-bit Python 3.5.1 to `C:\Python3`. +Before building the dependencies, disable the script from installing Python: +``` +> set IFCOS_INSTALL_PYTHON=FALSE +> buid-deps.cmd +``` + +After bulding the dependencies, create BuildDepsCache file to `IfcOpenShell\win` which tells the used Python version and intallation directory: +``` +> echo PY_VER_MAJOR_MINOR=35> BuildDepsCache-x64.txt +> echo PYTHONPATH=C:\Python3>> BuildDepsCache-x64.txt +``` + +After this you should be able to run `run-cmake.bat` normally. If using 32-bit Python, the name of the file must be `BuildDepsCache-x86.txt`. Directory Structure ------------------ @@ -49,12 +72,15 @@ Directory Structure +---deps-installed-vs- - Created by build-deps.cmd, for a certain VS version and target architecture +---installed-vs- - Created by building the IFCOS's INSTALL project \---win +| build-all.cmd - Runs all of the build scripts for IFCOS and it dependencies in a row without pauses | build-deps.cmd - Fetches and builds all needed dependencies for IFCOS | BuildDepsCache-.txt - Cache file created by build-deps.cmd | build-ifcopenshell.cmd - Builds IFCOS +| build-type-cfg.cmd - Utility file used by the build scripts | install-ifcopenshell.cmd - Builds IFCOS's INSTALL project | readme.md - This file | run-cmake.bat - Sets environment variables for the dependencies and runs CMake for IFCOS +| set-python-to-path.bat - Utility for setting PYTHONPATH (read from BuildDepsCache-.txt) to PATH | vs-cfg.cmd - Utility file used by the build scripts +---sln - Contains the old Visual Studio solution and project files \---utils - Contains various utilities for the build scripts diff --git a/win/run-cmake.bat b/win/run-cmake.bat index 6594a2812b..d9fb548743 100644 --- a/win/run-cmake.bat +++ b/win/run-cmake.bat @@ -22,11 +22,17 @@ echo. set PROJECT_NAME=IfcOpenShell -:: Enable the delayed environment variable expansion needed in vs-cfg.cmd. setlocal EnableDelayedExpansion -:: TODO Getting warning print in vs-cfg.cmd for missing build type although this script doesn't need it specified + call vs-cfg.cmd %1 IF NOT %ERRORLEVEL%==0 GOTO :Error +:: As CMake options are typically of format -DSOMETHING:BOOL=ON or -DSOMETHING=1, i.e. they contain an equal sign, +:: they will mess up the batch file argument parsing if the arguments are passed on by splitting them %2 %3 %4 %5 +:: %6 %7 %8 %9. Work around that, http://scripts.dragon-it.co.uk/scripts.nsf/docs/batch-search-replace-substitute +if not (%1)==() ( + set ARGUMENTS=%* + call set ARGUMENTS=%%ARGUMENTS:%1=%% +) :: Read Python related variables from BuildDepsCache.txt for /f "delims== tokens=1,2" %%G in (BuildDepsCache-%TARGET_ARCH%.txt) do set %%G=%%H @@ -39,7 +45,6 @@ IF NOT EXIST ..\%BUILD_DIR%. mkdir ..\%BUILD_DIR% pushd ..\%BUILD_DIR% set BOOST_ROOT=%DEPS_DIR%\boost -REM set BOOST_INCLUDEDIR=%DEPS_DIR%\boost set BOOST_LIBRARYDIR=%DEPS_DIR%\boost\stage\vs%VS_VER%-%VS_PLATFORM%\lib set ICU_INCLUDE_DIR=%INSTALL_DIR%\icu\include set ICU_LIBRARY_DIR=%INSTALL_DIR%\icu\lib @@ -47,8 +52,8 @@ set OCC_INCLUDE_DIR=%INSTALL_DIR%\oce\include\oce set OCC_LIBRARY_DIR=%INSTALL_DIR%\oce\Win%ARCH_BITS%\lib set OPENCOLLADA_INCLUDE_DIR=%INSTALL_DIR%\OpenCOLLADA\include\opencollada set OPENCOLLADA_LIBRARY_DIR=%INSTALL_DIR%\OpenCOLLADA\lib\opencollada -if "%PY_VER_MAJOR_MINOR%"=="" set PY_VER_MAJOR_MINOR=34 -if "%PYTHONPATH%"=="" set PYTHONPATH=%INSTALL_DIR%\Python%PY_VER_MAJOR_MINOR% +if not defined PY_VER_MAJOR_MINOR set PY_VER_MAJOR_MINOR=34 +if not defined PYTHONPATH set PYTHONPATH=%INSTALL_DIR%\Python%PY_VER_MAJOR_MINOR% set PYTHON_INCLUDE_DIR=%PYTHONPATH%\include set PYTHON_LIBRARY=%PYTHONPATH%\libs\python%PY_VER_MAJOR_MINOR%.lib set SWIG_DIR=%INSTALL_DIR%\swigwin @@ -57,12 +62,11 @@ set PATH=%PATH%;%SWIG_DIR%;%PYTHONPATH% echo. call cecho.cmd 0 10 "Script configuration:" -echo CMake Generator = %GENERATOR% -echo All arguments = %* +echo Generator = %GENERATOR% +echo Arguments = %ARGUMENTS% echo. call cecho.cmd 0 10 "Dependency Environment Variables for %PROJECT_NAME%:" echo BOOST_ROOT = %BOOST_ROOT% -REM echo BOOST_INCLUDEDIR = %BOOST_INCLUDEDIR% echo BOOST_LIBRARYDIR = %BOOST_LIBRARYDIR% echo ICU_INCLUDE_DIR = %ICU_INCLUDE_DIR% echo ICU_LIBRARY_DIR = %ICU_LIBRARY_DIR% @@ -79,34 +83,23 @@ echo CMAKE_INSTALL_PREFIX = %CMAKE_INSTALL_PREFIX% echo. set CMAKELISTS_DIR=..\cmake -REM IF NOT EXIST %PROJECT_NAME%.sln. ( - IF EXIST CMakeCache.txt. del /Q CMakeCache.txt - call cecho.cmd 0 13 "Running CMake for %PROJECT_NAME%." - IF "%2"=="" ( - REM No extra arguments provided, trust that GENERATOR is set properly. - cmake.exe %CMAKELISTS_DIR% -G %GENERATOR% -DCMAKE_INSTALL_PREFIX="%CMAKE_INSTALL_PREFIX%" - ) ELSE ( - REM Extra arguments has been provided. As CMake options are typically of format -DSOMETHING:BOOL=ON, - REM i.e. they contain an equal sign, they will mess up the batch file argument parsing if the arguments are passed on - REM by splitting them %2 %3 %4 %5 %6 %7 %8 %9. In the extra argument case trust that user has provided the generator - REM as the first argument as pass all arguments as is by using %*. - cmake.exe %CMAKELISTS_DIR% -G %* - ) - IF NOT %ERRORLEVEL%==0 GOTO :Error -REM ) ELSE ( - REM call cecho.cmd 0 10 "%PROJECT_NAME%.sln exists. Skipping CMake call for %PROJECT_NAME%." - REM call cecho.cmd 0 10 "Delete %BUILD_DIR%\%PROJECT_NAME%.sln to trigger a CMake rerun." -REM ) +:: For now clear CMakeCache.txt always in order to assure that when changing build options everything goes smoothly. +IF EXIST CMakeCache.txt. del /Q CMakeCache.txt +call cecho.cmd 0 13 "Running CMake for %PROJECT_NAME%." +cmake.exe %CMAKELISTS_DIR% -G %GENERATOR% -DCMAKE_INSTALL_PREFIX="%CMAKE_INSTALL_PREFIX%" %ARGUMENTS% +IF NOT %ERRORLEVEL%==0 GOTO :Error + echo. +set IFCOS_SCRIPT_RET=0 goto :Finish :Error echo. call %~dp0\utils\cecho.cmd 0 12 "An error occurred! Aborting!" +set IFCOS_SCRIPT_RET=1 goto :Finish :Finish popd -set PATH=%ORIGINAL_PATH% -endlocal +exit /b %IFCOS_SCRIPT_RET% diff --git a/win/set-python-to-path.bat b/win/set-python-to-path.bat new file mode 100644 index 0000000000..613a69c149 --- /dev/null +++ b/win/set-python-to-path.bat @@ -0,0 +1,36 @@ +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +:: :: +:: This file is part of IfcOpenShell. :: +:: :: +:: IfcOpenShell is free software: you can redistribute it and/or modify :: +:: it under the terms of the Lesser GNU General Public License as published by :: +:: the Free Software Foundation, either version 3.0 of the License, or :: +:: (at your option) any later version. :: +:: :: +:: IfcOpenShell is distributed in the hope that it will be useful, :: +:: but WITHOUT ANY WARRANTY; without even the implied warranty of :: +:: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the :: +:: Lesser GNU General Public License for more details. :: +:: :: +:: You should have received a copy of the Lesser GNU General Public License :: +:: along with this program. If not, see . :: +:: :: +::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: + +:: Pass x86 or x64 as %1, if not specified x64 assumed. + +@echo off +set TARGET_ARCH=%1 +if "%TARGET_ARCH%"=="" set TARGET_ARCH=x64 +if not exist BuildDepsCache-%TARGET_ARCH%.txt. ( + echo BuildDepsCache-%TARGET_ARCH%.txt does not exist + goto :EOF +) +for /f "delims== tokens=1,2" %%G in (BuildDepsCache-%TARGET_ARCH%.txt) do set %%G=%%H +if not defined PYTHONPATH ( + echo PYTHONPATH PYTHONPATH not defined + goto :EOF +) + +echo %PYTHONPATH% set to PATH +set PATH=%PYTHONPATH%;%PATH% diff --git a/win/vs-cfg.cmd b/win/vs-cfg.cmd index cf70bb5265..92c0a1217d 100644 --- a/win/vs-cfg.cmd +++ b/win/vs-cfg.cmd @@ -15,11 +15,12 @@ :: You should have received a copy of the Lesser GNU General Public License :: :: along with this program. If not, see . :: :: :: -::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: +::::::::::::::::::::::::::::::::::::::::::::::::::::::: :::::::::::::::::::::::::: -:: This script initializes various Visual Studio -related environment variables needed for building -:: This batch file expects CMake generator as %1 and build configuration type as %2. -:: If %1 is not provided, it is deduced from the VisualStudioVersion environment variable and from the location of cl.exe. +:: This script initializes various Visual Studio related environment variables needed for building. +:: the dependencies. This batch file expects a CMake generator as %1. If %1 is not provided, it is +:: deduced from the VisualStudioVersion environment variable and from the location of cl.exe. +:: User-friendly VS generators are allowed (e.g. "vs2013-x86") and converted to the appropriate CMake ones. :: NOTE This batch file expects the generator string to be CMake 3.0.0 and newer format, i.e. :: "Visual Studio 10 2010" instead of "Visual Studio 10". However, one can use this batch file @@ -31,9 +32,6 @@ set GENERATOR=%1 -:: TODO IDEA: Take more user-friendly VS generators and convert them to the CMake ones? -:: F.ex. "vs2013-32" and/or "vc14-64" - :: Supported Visual Studio versions: set GENERATORS[0]="Visual Studio 9 2008 Win64" set GENERATORS[1]="Visual Studio 9 2008" @@ -47,17 +45,35 @@ set GENERATORS[8]="Visual Studio 14 2015 Win64" set GENERATORS[9]="Visual Studio 14 2015" set LAST_GENERATOR_IDX=9 -REM Deduce desired architecture from the location of cl.exe -where cl.exe | findstr /r /c:"amd64" >nul -set START=%ERRORLEVEL% set STEP=2 +:: Is generator shorthand used? +set GEN_SHORTHAND=!GENERATOR:vs=! +if not "!GEN_SHORTHAND!"=="" if !GEN_SHORTHAND!==!GENERATOR! goto :GeneratorShorthandCheckDone +set START=%LAST_GENERATOR_IDX% +:: "echo if" trick from http://stackoverflow.com/a/8758579 +echo(!GEN_SHORTHAND! | findstr /c:"-x86" >nul && ( set START=1 ) +echo(!GEN_SHORTHAND! | findstr /c:"-x64" >nul && ( set START=0 ) +set VS_VER=!GEN_SHORTHAND:-x86=! +set VS_VER=!VS_VER:-x64=! +echo(!GENERATOR! | findstr /c:"vs20" >nul && ( + for /l %%i in (!START!,!STEP!,%LAST_GENERATOR_IDX%) do ( + echo(!GENERATORS[%%i]! | findstr /c:"!VS_VER!" >nul && ( + set GENERATOR=!GENERATORS[%%i]! + goto :GeneratorShorthandCheckDone + ) + ) +) +:GeneratorShorthandCheckDone + +:: Deduce desired architecture from the location of cl.exe +where cl.exe | findstr /c:"amd64" >nul +set START=%ERRORLEVEL% IF "!GENERATOR!"=="" IF NOT "%VisualStudioVersion%"=="" ( set VC_VER=%VisualStudioVersion:.0=% FOR /l %%i in (%START%,%STEP%,%LAST_GENERATOR_IDX%) DO ( - REM http://stackoverflow.com/a/8758579 REM NOTE add space before VC_VER so that e.g. "12" doesn't match with "2012" - echo(!GENERATORS[%%i]! | findstr /r /c:" !VC_VER!" >nul && ( + echo(!GENERATORS[%%i]! | findstr /c:" !VC_VER!" >nul && ( set GENERATOR=!GENERATORS[%%i]! call utils\cecho.cmd black cyan "Generator not passed, but VisualStudioVersion=%VisualStudioVersion% environment variable detected:" call utils\cecho.cmd black cyan "using '`"!GENERATOR!`'" as the generator." @@ -65,11 +81,18 @@ IF "!GENERATOR!"=="" IF NOT "%VisualStudioVersion%"=="" ( ) ) ) +:: Check that the used CMake version supports the chosen generator +set GENERATOR_CHECK=%GENERATOR: Win64=% +cmake --help | findstr /c:%GENERATOR_CHECK% >nul +if not %ERRORLEVEL%==0 ( +call utils\cecho.cmd 0 12 "%~nx0: The used CMake version does not support '`"!GENERATOR!`'"- cannot proceed." +exit /b 1 +) FOR /l %%i in (0,1,%LAST_GENERATOR_IDX%) DO ( IF !GENERATOR!==!GENERATORS[%%i]! GOTO :GeneratorValid ) -call utils\cecho.cmd 0 12 "%~nx0: Invalid or unsupported CMake generator string passed: '`"!GENERATOR!`'". Cannot proceed, aborting!" +call utils\cecho.cmd 0 12 "%~nx0: Invalid or unsupported CMake generator string passed: '`"!GENERATOR!`'"- cannot proceed." echo Supported CMake generator strings: FOR /l %%i in (0,1,%LAST_GENERATOR_IDX%) DO ( echo !GENERATORS[%%i]! @@ -117,43 +140,6 @@ set GENERATOR=%GENERATOR: 2010=% set VCPROJ_FILE_EXT=vcxproj IF %VS_VER%==2008 set VCPROJ_FILE_EXT=vcproj -:: Set up variables depending on the used build configuration type. -set BUILD_CFG=%2 - -:: The default build types provided by CMake -set BUILD_CFG_MINSIZEREL=MinSizeRel -set BUILD_CFG_RELEASE=Release -set BUILD_CFG_RELWITHDEBINFO=RelWithDebInfo -set BUILD_CFG_DEBUG=Debug -set BUILD_CFG_DEFAULT=%BUILD_CFG_RELWITHDEBINFO% - -IF "!BUILD_CFG!"=="" ( - set BUILD_CFG=%BUILD_CFG_DEFAULT% - call utils\cecho.cmd 0 14 "%~nx0: Warning: BUILD_CFG not specified - using the default %BUILD_CFG_DEFAULT%" -) -IF NOT !BUILD_CFG!==%BUILD_CFG_MINSIZEREL% IF NOT !BUILD_CFG!==%BUILD_CFG_RELEASE% ( -IF NOT !BUILD_CFG!==%BUILD_CFG_RELWITHDEBINFO% IF NOT !BUILD_CFG!==%BUILD_CFG_DEBUG% ( - call utils\cecho.cmd 0 12 "%~nx0: Invalid or unsupported CMake build configuration type passed: !BUILD_CFG!. Cannot proceed, aborting!" - exit /b 1 -)) - -:: DEBUG_OR_RELEASE and DEBUG_OR_RELEASE_LOWERCASE are "Debug" and "debug" for Debug build and "Release" and -:: "release" for all of the Release variants. -:: POSTFIX_D, POSTFIX_UNDERSCORE_D and POSTFIX_UNDERSCORE_DEBUG are helpers for performing file copies and -:: checking for existence of files. In release build these variables are empty. -set DEBUG_OR_RELEASE=Release -set DEBUG_OR_RELEASE_LOWERCASE=release -set POSTFIX_D= -set POSTFIX_UNDERSCORE_D= -set POSTFIX_UNDERSCORE_DEBUG= -IF %BUILD_CFG%==Debug ( - set DEBUG_OR_RELEASE=Debug - set DEBUG_OR_RELEASE_LOWERCASE=debug - set POSTFIX_D=d - set POSTFIX_UNDERSCORE_D=_d - set POSTFIX_UNDERSCORE_DEBUG=_debug -) - :: Add utils to PATH set ORIGINAL_PATH=%PATH% set PATH=%PATH%;%~dp0utils