MantisBT
Mantis Bug Tracker Workflow

View Revisions: Issue #27344 All Revisions ] Back to Issue ]
Summary 0027344: Configuration, CMake - bugs with detecting third-party products
Revision 2016-04-04 12:05 by vsr
Description Here are some issues revealed during testing of OCCT CMake configuration.

1) Information messages printed when configuring OCCT with CMake are confusing.

For example (on Linux):

[sh%] echo $TCLHOME
/dn47/SALOME/PRODUCTS/8x/opt/CentOS.6.3.64/8.0.0/tcltk-8.6.0

[sh%] cmake -D3RDPARTY_GL2PS_DIR:PATH=${GL2PS_ROOT_DIR} -D3RDPARTY_FREETYPE_DIR:PATH=${FREETYPE_ROOT_DIR} -D3RDPARTY_FREEIMAGE_DIR:PATH=${FREEIMAGE_ROOT_DIR} -D3RDPARTY_TBB_DIR:PATH=${TBB_ROOT_DIR} -D3RDPARTY_TK_DIR:PATH=${TCLHOME} -D3RDPARTY_TCL_DIR:PATH=${TCLHOME} -DUSE_FREEIMAGE:BOOL=ON -DUSE_GL2PS:BOOL=ON -DUSE_TBB:BOOL=ON -DUSE_VTK:BOOL=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/dn25/salome/vsr/PRODUCTS/CR27301

-- Info: TCL is used by OCCT
-- Found Tclsh: /dn47/SALOME/PRODUCTS/8x/opt/CentOS.6.3.64/8.0.0/tcltk-8.6.0/bin/tclsh (found version "8.6")
-- Found TCL: /usr/lib64/libtcl.so
-- Found TCLTK: /usr/lib64/libtcl.so
-- Found TK: /usr/lib64/libtk.so
-- Info: TK is used from TCL folder: /dn47/SALOME/PRODUCTS/8x/opt/CentOS.6.3.64/8.0.0/tcltk-8.6.0
-- Info: TK is used by OCCT
-- Info: Freetype is used by OCCT
...

In fact, when looking into the CMakeCache.txt generated by CMake at the end of configuration process, one can see that tcl and tk are found correctly, i.e. related variables are set properly. However, information messages printed to the terminal confuse the user.

Also, it is not clear, what's the difference between "TCL", "TK" and "TCLTK"?

2) There is a bug in configuration file causing CMake error when detecting OCCT in dependent project.

The following line in OpenCASCADEConfig.cmake is incorrect:

set(OpenCASCADE_CONFIG_TARGETS_FILE "${CMAKE_CURRENT_LIST_FILE}/OpenCASCADETargets.cmake")

It has to be corrected:

set(OpenCASCADE_CONFIG_TARGETS_FILE "${CMAKE_CURRENT_LIST_DIR}/OpenCASCADETargets.cmake")

3) Detection of OCCT does not work on Windows when default layout is used.

While on Linux OpenCASCADE is well detected in CONFIG mode, this does not work on Windows. This is because the config files are put to the <prefix>/win32/vc10/lib directory which is not used as one of locations automatically parsed by CMake. This is well written in the CMake documentation (https://cmake.org/cmake/help/v3.5/command/find_package.html [^]):

<prefix>/ (W)
<prefix>/(cmake|CMake)/ (W)
<prefix>/<name>*/ (W)
<prefix>/<name>*/(cmake|CMake)/ (W)
<prefix>/(lib/<arch>|lib|share)/cmake/<name>*/ (U)
<prefix>/(lib/<arch>|lib|share)/<name>*/ (U)
<prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/ (U)

One can see that on Windows CMake only searches config files in:
<prefix>
<prefix>/cmake
<prefix>/CMake
<prefix>/opencascade/cmake
<prefix>/opencascade/CMake

This should be corrected!

4) Definitions are absent in config file.

Absence of CAS_DEFINITIONS variable in the config file can potentially cause compilation or linkage problem in dependent project – if some defines used during OCCT building are somehow exported into the header files. An example of such behavior is BVH_LinearBuilder.lxx where "#ifdef HAVE_TBB" is extensively used.

For instance, in SALOME, due to absence of a way to know what flags have been used when configuring OCCT, some options were explicitly hardcoded in the detection procedure (it came from very early version of SALOME):

# Definitions:
SET(CAS_DEFINITIONS "-DLIN -DLINTEL -DCSFDB")
SET(CAS_DEFINITIONS "${CAS_DEFINITIONS} -DNo_exception")

# No config.h file in the OPEN CASCADE on WINDOWS platform
IF(NOT WIN32)
SET(CAS_DEFINITIONS "${CAS_DEFINITIONS} -DHAVE_CONFIG_H")
ENDIF()

# Test for 64 bit machine:
IF(CMAKE_SIZEOF_VOID_P STREQUAL 8)
  SET(CAS_DEFINITIONS "${CAS_DEFINITIONS} -D_OCC64")
ENDIF()

It seems that some of these defines are not needed anymore, but as we cannot know this exactly so we keep using them. The reason is that OCCT never exported such defines explicitly, so dependent project needed to set these variables themselves to be able to build with OCCT. Such behavior can lead to different problems with linking of OCCT-based solutions, or problems in runtime (as this can, for instance, cause undefined symbols).

The options (in first turn, definitions) which are used during the configuration of OCCT and which can affect the behavior of included OCCT headers, should be exposed to the OCCT config file, via the OpenCASCADE_DEFINITIONS variable.

Currently OCCT config file exports some variables that come from the configuration procedure:

# OpenCASCADE global configuration options.
set (OpenCASCADE_COMPILER "gcc")
set (OpenCASCADE_BUILD_WITH_DEBUG OFF)
set (OpenCASCADE_BUILD_SHARED_LIBS ON)
set (OpenCASCADE_BUILD_TYPE "Release")

# Use of third-party libraries
set (OpenCASCADE_WITH_TCL ON)
set (OpenCASCADE_WITH_FREETYPE ON)
set (OpenCASCADE_WITH_FREEIMAGE ON)
set (OpenCASCADE_WITH_GL2PS ON)
set (OpenCASCADE_WITH_TBB ON)
set (OpenCASCADE_WITH_VTK OFF)

Judging on the source files (*.cmake, CMakeLists.txt) these variables affect on the build procedure of OCCT by specifying additional defines. So, maybe these defines should be exposed to the config file also?

For example, something like below can be done:

# OpenCASCADE global configuration options.
set (OpenCASCADE_COMPILER "gcc")
set (OpenCASCADE_BUILD_WITH_DEBUG OFF)
if (OpenCASCADE_BUILD_WITH_DEBUG)
  add_definitions (-DOCCT_DEBUG)
endif()
set (OpenCASCADE_BUILD_SHARED_LIBS ON)
set (OpenCASCADE_BUILD_TYPE "Release")

# Use of third-party libraries
set (OpenCASCADE_WITH_TCL ON)
set (OpenCASCADE_WITH_FREETYPE ON)
set (OpenCASCADE_WITH_FREEIMAGE ON)
if (OpenCASCADE_WITH_FREEIMAGE)
  add_definitions (-DHAVE_FREEIMAGE)
endif()
set (OpenCASCADE_WITH_GL2PS ON)
if (OpenCASCADE_WITH_GL2PS)
  add_definitions (-DHAVE_GL2PS)
endif()
set (OpenCASCADE_WITH_TBB ON)
if (OpenCASCADE_WITH_TBB)
  add_definitions (-DHAVE_TBB)
  if (MSVC)
    add_definitions (-D__TBB_NO_IMPLICIT_LINKAGE)
    add_definitions (-D__TBBMALLOC_NO_IMPLICIT_LINKAGE)
  endif()
endif()
set (OpenCASCADE_WITH_VTK OFF)
if (OpenCASCADE_WITH_VTK)
  add_definitions (-DHAVE_VTK)
endif()

if (NOT WIN32)
  add_definitions(-DOCC_CONVERT_SIGNALS)
endif()

if (MINGW)
  add_definitions(-D_WIN32_WINNT=0x0501)
endif()

This should be analyzed and appropriate solution is to be implemented.

5) Bad workaround about VTK's dependency on DirectX libraries on Windows.

a) Probably this dependency is indeed not needed in the VTK config file. Indeed, quick analysis shows that that DirectX features are used internally in a single VTK class which header is not exported. So, d3d9 library is used implicitly and d4d9.lib is not needed at linkage time when you build OCCT. In runtime this works just because most likely DirectX is installed on the workstation, into the Windows system directory. Only if DirectX isn't installed there will be most probably a problem in runtime with loading of related OCCT libraries.

b) On the other hand, hack used by OCCT for VTK detection procedure does not seem good. It supposes that Microsoft SDK was installed to the "C" drive, moreover, into the hardcoded directory. However, it can be installed to another drive and even to another directory. For example, on my workstation I have SDK installed on drive "D". So, if I build VTK on my computer and then give it to somebody else, that "somebody" will not be able to build OCCT, just because above mentioned hack will not work.

c) VTK, depending on the way it is configured, can depend on other third-party products, e.g. hdf5, libxml2, python, freetype, gl2ps. The path to these products can be also hardcoded into the VTK config files. Should we implement similar workaround as for DirectX for these products also?


Revision 2016-04-04 12:04 by vsr
Description Here are some issues revealed during testing of OCCT CMake configuration.

1) Information messages printed when configuring OCCT with CMake are confusing.

For example (on Linux):

[vsr@dobrex: /dn25/salome/vsr/PRODUCTS/CR27301-SRC] echo $TCLHOME
/dn47/SALOME/PRODUCTS/8x/opt/CentOS.6.3.64/8.0.0/tcltk-8.6.0

[vsr@dobrex: /dn25/salome/vsr/PRODUCTS/CR27301-SRC] cmake -D3RDPARTY_GL2PS_DIR:PATH=${GL2PS_ROOT_DIR} -D3RDPARTY_FREETYPE_DIR:PATH=${FREETYPE_ROOT_DIR} -D3RDPARTY_FREEIMAGE_DIR:PATH=${FREEIMAGE_ROOT_DIR} -D3RDPARTY_TBB_DIR:PATH=${TBB_ROOT_DIR} -D3RDPARTY_TK_DIR:PATH=${TCLHOME} -D3RDPARTY_TCL_DIR:PATH=${TCLHOME} -DUSE_FREEIMAGE:BOOL=ON -DUSE_GL2PS:BOOL=ON -DUSE_TBB:BOOL=ON -DUSE_VTK:BOOL=OFF -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/dn25/salome/vsr/PRODUCTS/CR27301

-- Info: TCL is used by OCCT
-- Found Tclsh: /dn47/SALOME/PRODUCTS/8x/opt/CentOS.6.3.64/8.0.0/tcltk-8.6.0/bin/tclsh (found version "8.6")
-- Found TCL: /usr/lib64/libtcl.so
-- Found TCLTK: /usr/lib64/libtcl.so
-- Found TK: /usr/lib64/libtk.so
-- Info: TK is used from TCL folder: /dn47/SALOME/PRODUCTS/8x/opt/CentOS.6.3.64/8.0.0/tcltk-8.6.0
-- Info: TK is used by OCCT
-- Info: Freetype is used by OCCT
...

In fact, when looking into the CMakeCache.txt generated by CMake at the end of configuration process, one can see that tcl and tk are found correctly, i.e. related variables are set properly. However, information messages printed to the terminal confuse the user.

Also, it is not clear, what's the difference between "TCL", "TK" and "TCLTK"?

2) There is a bug in configuration file causing CMake error when detecting OCCT in dependent project.

The following line in OpenCASCADEConfig.cmake is incorrect:

set(OpenCASCADE_CONFIG_TARGETS_FILE "${CMAKE_CURRENT_LIST_FILE}/OpenCASCADETargets.cmake")

It has to be corrected:

set(OpenCASCADE_CONFIG_TARGETS_FILE "${CMAKE_CURRENT_LIST_DIR}/OpenCASCADETargets.cmake")

3) Detection of OCCT does not work on Windows when default layout is used.

While on Linux OpenCASCADE is well detected in CONFIG mode, this does not work on Windows. This is because the config files are put to the <prefix>/win32/vc10/lib directory which is not used as one of locations automatically parsed by CMake. This is well written in the CMake documentation (https://cmake.org/cmake/help/v3.5/command/find_package.html [^]):

<prefix>/ (W)
<prefix>/(cmake|CMake)/ (W)
<prefix>/<name>*/ (W)
<prefix>/<name>*/(cmake|CMake)/ (W)
<prefix>/(lib/<arch>|lib|share)/cmake/<name>*/ (U)
<prefix>/(lib/<arch>|lib|share)/<name>*/ (U)
<prefix>/(lib/<arch>|lib|share)/<name>*/(cmake|CMake)/ (U)

One can see that on Windows CMake only searches config files in:
<prefix>
<prefix>/cmake
<prefix>/CMake
<prefix>/opencascade/cmake
<prefix>/opencascade/CMake

This should be corrected!

4) Definitions are absent in config file.

Absence of CAS_DEFINITIONS variable in the config file can potentially cause compilation or linkage problem in dependent project – if some defines used during OCCT building are somehow exported into the header files. An example of such behavior is BVH_LinearBuilder.lxx where "#ifdef HAVE_TBB" is extensively used.

For instance, in SALOME, due to absence of a way to know what flags have been used when configuring OCCT, some options were explicitly hardcoded in the detection procedure (it came from very early version of SALOME):

# Definitions:
SET(CAS_DEFINITIONS "-DLIN -DLINTEL -DCSFDB")
SET(CAS_DEFINITIONS "${CAS_DEFINITIONS} -DNo_exception")

# No config.h file in the OPEN CASCADE on WINDOWS platform
IF(NOT WIN32)
SET(CAS_DEFINITIONS "${CAS_DEFINITIONS} -DHAVE_CONFIG_H")
ENDIF()

# Test for 64 bit machine:
IF(CMAKE_SIZEOF_VOID_P STREQUAL 8)
  SET(CAS_DEFINITIONS "${CAS_DEFINITIONS} -D_OCC64")
ENDIF()

It seems that some of these defines are not needed anymore, but as we cannot know this exactly so we keep using them. The reason is that OCCT never exported such defines explicitly, so dependent project needed to set these variables themselves to be able to build with OCCT. Such behavior can lead to different problems with linking of OCCT-based solutions, or problems in runtime (as this can, for instance, cause undefined symbols).

The options (in first turn, definitions) which are used during the configuration of OCCT and which can affect the behavior of included OCCT headers, should be exposed to the OCCT config file, via the OpenCASCADE_DEFINITIONS variable.

Currently OCCT config file exports some variables that come from the configuration procedure:

# OpenCASCADE global configuration options.
set (OpenCASCADE_COMPILER "gcc")
set (OpenCASCADE_BUILD_WITH_DEBUG OFF)
set (OpenCASCADE_BUILD_SHARED_LIBS ON)
set (OpenCASCADE_BUILD_TYPE "Release")

# Use of third-party libraries
set (OpenCASCADE_WITH_TCL ON)
set (OpenCASCADE_WITH_FREETYPE ON)
set (OpenCASCADE_WITH_FREEIMAGE ON)
set (OpenCASCADE_WITH_GL2PS ON)
set (OpenCASCADE_WITH_TBB ON)
set (OpenCASCADE_WITH_VTK OFF)

Judging on the source files (*.cmake, CMakeLists.txt) these variables affect on the build procedure of OCCT by specifying additional defines. So, maybe these defines should be exposed to the config file also?

For example, something like below can be done:

# OpenCASCADE global configuration options.
set (OpenCASCADE_COMPILER "gcc")
set (OpenCASCADE_BUILD_WITH_DEBUG OFF)
if (OpenCASCADE_BUILD_WITH_DEBUG)
  add_definitions (-DOCCT_DEBUG)
endif()
set (OpenCASCADE_BUILD_SHARED_LIBS ON)
set (OpenCASCADE_BUILD_TYPE "Release")

# Use of third-party libraries
set (OpenCASCADE_WITH_TCL ON)
set (OpenCASCADE_WITH_FREETYPE ON)
set (OpenCASCADE_WITH_FREEIMAGE ON)
if (OpenCASCADE_WITH_FREEIMAGE)
  add_definitions (-DHAVE_FREEIMAGE)
endif()
set (OpenCASCADE_WITH_GL2PS ON)
if (OpenCASCADE_WITH_GL2PS)
  add_definitions (-DHAVE_GL2PS)
endif()
set (OpenCASCADE_WITH_TBB ON)
if (OpenCASCADE_WITH_TBB)
  add_definitions (-DHAVE_TBB)
  if (MSVC)
    add_definitions (-D__TBB_NO_IMPLICIT_LINKAGE)
    add_definitions (-D__TBBMALLOC_NO_IMPLICIT_LINKAGE)
  endif()
endif()
set (OpenCASCADE_WITH_VTK OFF)
if (OpenCASCADE_WITH_VTK)
  add_definitions (-DHAVE_VTK)
endif()

if (NOT WIN32)
  add_definitions(-DOCC_CONVERT_SIGNALS)
endif()

if (MINGW)
  add_definitions(-D_WIN32_WINNT=0x0501)
endif()

This should be analyzed and appropriate solution is to be implemented.

5) Bad workaround about VTK's dependency on DirectX libraries on Windows.

a) Probably this dependency is indeed not needed in the VTK config file. Indeed, quick analysis shows that that DirectX features are used internally in a single VTK class which header is not exported. So, d3d9 library is used implicitly and d4d9.lib is not needed at linkage time when you build OCCT. In runtime this works just because most likely DirectX is installed on the workstation, into the Windows system directory. Only if DirectX isn't installed there will be most probably a problem in runtime with loading of related OCCT libraries.

b) On the other hand, hack used by OCCT for VTK detection procedure does not seem good. It supposes that Microsoft SDK was installed to the "C" drive, moreover, into the hardcoded directory. However, it can be installed to another drive and even to another directory. For example, on my workstation I have SDK installed on drive "D". So, if I build VTK on my computer and then give it to somebody else, that "somebody" will not be able to build OCCT, just because above mentioned hack will not work.

c) VTK, depending on the way it is configured, can depend on other third-party products, e.g. hdf5, libxml2, python, freetype, gl2ps. The path to these products can be also hardcoded into the VTK config files. Should we implement similar workaround as for DirectX for these products also?




Copyright © 2000 - 2019 MantisBT Team
Powered by Mantis Bugtracker