misunderstanding interface library?

Hi,

I tried to use interface library definition.

May be my understanding is wrong. I thought, I could use an interface library
as a virtual target which declares include directories and used libraries …
So that a toolkit with several include directories and library entries becomes
a one liner.

I coded in toplevel CMakeLists.txt:

add_library(IFOcct INTERFACE)
target_include_directories(IFOcct
                           INTERFACE /dir0
                           INTERFACE /dir1
                           )
target_link_libraries(IFOcct
                      INTERFACE lib0
                      INTERFACE lib1
                      INTERFACE lib2
                      )

and in my subproject I simply added IFOcct to target_link_libraries
definition.

But after recreating build instructions I get compile errors about unfound
headers and inspecting the compile commandline shows, that none of the include
directories was used.

Is my understanding wrong, or did I make an mistake?

That looks fine assuming that /dir0 is what you want. What actual CMake code you wrote, what command lines were generated, and the error messages that came up (along with where the headers actually live if those aren’t found) would help here.

Ok, first my top level CMakeLists.txt:

cmake_minimum_required(VERSION 3.16)
##################################   TOP   ###################################
project(FalconView     VERSION 0.1)
##############################################################################
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_MODULE_PATH /d/linux/cmake)
include(FalconView RESULT_VARIABLE ConfigBase)
set(CMAKE_PREFIX_PATH "/opt/qt5.15/5.15.2/gcc_64" CACHE PATH "CMake search-path")
set(CMAKE_PREFIX_PATH ${CMAKE_PREFIX_PATH} "/usr/local/lib/cmake/opencascade")
set(OpenCASCADE_DIR   "/usr/local/lib/cmake/opencascade" CACHE PATH "OpenCascade 7.6.0")
set(LinuxCNC_DIR      "/usr/local/src/linuxcnc-deb11" CACHE PATH "LinuxCNC")
set(DistDIR           ${PROJECT_BINARY_DIR}/dist CACHE PATH "build-result")
find_package(Qt5 REQUIRED COMPONENTS
             Gui
             Widgets
             Core
             Sql
             UiTools
             Xml
             LinguistTools
             )
find_package(OpenCASCADE COMPONENTS
             FoundationClasses
             ModelingData
             ModelingAlgorithms
             Visualization
             ApplicationFramework
             Draw
             PATHS ${OpenCASCADE_DIR} NO_DEFAULT_PATH
             )
find_library(LC_LibLC    linuxcnc REQUIRED PATHS ${LinuxCNC_DIR}/lib )
find_library(LC_LibPM    posemath REQUIRED PATHS ${LinuxCNC_DIR}/lib )
find_library(LC_LibNML   nml REQUIRED PATHS ${LinuxCNC_DIR}/lib )
find_library(LC_LibRS274 rs274 REQUIRED PATHS ${LinuxCNC_DIR}/lib )
find_library(LC_LibLCI   linuxcncini REQUIRED PATHS ${LinuxCNC_DIR}/lib )
find_library(LC_LibPP    pyplugin REQUIRED PATHS ${LinuxCNC_DIR}/lib )
find_library(LC_LibHal   linuxcnchal REQUIRED PATHS ${LinuxCNC_DIR}/lib )
find_library(LC_LibTD    tooldata REQUIRED PATHS ${LinuxCNC_DIR}/lib )

add_library(IFlinuxCNC    INTERFACE)
add_library(IFQt          INTERFACE)
add_library(IFOpenCASCADE INTERFACE)
add_library(IFStandard    INTERFACE)
target_include_directories(IFlinuxCNC
                           INTERFACE /usr/include/python3.9
                           INTERFACE ${LinuxCNC_DIR}/include
                           INTERFACE ${LinuxCNC_DIR}/src
                           INTERFACE ${LinuxCNC_DIR}/src/emc/rs274ngc
                           INTERFACE ${LinuxCNC_DIR}/src/emc/tooldata
                           )
target_link_libraries(IFlinuxCNC
                      INTERFACE ${LC_LibLC}
                      INTERFACE ${LC_LibPM}
                      INTERFACE ${LC_LibNML}
                      INTERFACE ${LC_LibRS274}
                      INTERFACE ${LC_LibLCI}
                      INTERFACE ${LC_LibPP}
                      INTERFACE ${LC_LibHal}
                      INTERFACE ${LC_LibTD}
                      )
target_include_directories(IFQt
                           INTERFACE ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
                           )
target_link_libraries(IFQt
                      INTERFACE Qt${QT_VERSION_MAJOR}::Gui
                      INTERFACE Qt${QT_VERSION_MAJOR}::Widgets
                      INTERFACE Qt${QT_VERSION_MAJOR}::Core
                      INTERFACE Qt${QT_VERSION_MAJOR}::Sql
                      INTERFACE Qt${QT_VERSION_MAJOR}::UiTools
                      INTERFACE Qt${QT_VERSION_MAJOR}::Xml
                      )
target_include_directories(IFOpenCASCADE
                           INTERFACE ${OpenCASCADE_INCLUDE_DIR}
                           )
target_link_libraries(IFOpenCASCADE
                      INTERFACE TKernel
                      INTERFACE TKMath
                      INTERFACE TKService
                      INTERFACE TKV3d
                      INTERFACE TKOpenGl
                      INTERFACE TKBRep
                      INTERFACE TKIGES
                      INTERFACE TKSTL
                      INTERFACE TKVRML
                      INTERFACE TKSTEP
                      INTERFACE TKSTEPAttr
                      INTERFACE TKSTEP209
                      INTERFACE TKSTEPBase
                      INTERFACE TKGeomBase
                      INTERFACE TKGeomAlgo
                      INTERFACE TKG3d
                      INTERFACE TKG2d
                      INTERFACE TKXSBase
                      INTERFACE TKShHealing
                      INTERFACE TKHLR
                      INTERFACE TKTopAlgo
                      INTERFACE TKMesh
                      INTERFACE TKPrim
                      INTERFACE TKCDF
                      INTERFACE TKBool
                      INTERFACE TKBO
                      INTERFACE TKFillet
                      INTERFACE TKOffset
                      INTERFACE TKLCAF
                      INTERFACE TKCAF
                      INTERFACE TKVCAF
                      INTERFACE TKBin
                      INTERFACE TKXml
                      )
target_link_libraries(IFStandard
                      INTERFACE m
                      INTERFACE stdc++
                      INTERFACE boost_python39
                      INTERFACE python3.9
                      INTERFACE crypt
                      INTERFACE pthread
                      INTERFACE dl
                      INTERFACE util
                      )
add_subdirectory(src)
add_subdirectory(docs)
add_custom_target(Dummy)
add_dependencies(FalconView HelpFile)
add_dependencies(Dummy FalconView)
add_custom_command(TARGET Dummy POST_BUILD
    COMMAND ${PROJECT_SOURCE_DIR}/buildFinish ${PROJECT_SOURCE_DIR} ${PROJECT_BINARY_DIR}
    DEPENDS $<TARGET_FILE:FalconView>
    COMMENT "finish build"
    )

… and here the CMakeLists.txt from first subproject:

cmake_minimum_required(VERSION 3.16)
#--------------------------------   LIB   ------------------------------------
project(BaseLib LANGUAGES CXX)
#-----------------------------------------------------------------------------
include(FalconView)
add_library(FVBaseLib STATIC
    control/core.cpp
    control/kernel.cpp
    model/configacc.cpp
    model/configmgr.cpp
    model/direntry.cpp
    model/dirmodel.cpp
    model/filemodel.cpp
    model/sysevent.cpp
    model/syseventmodel.cpp
    model/valuemanager.cpp
    model/valuemodel.cpp
    util/dbconnection.cpp
    util/flowlayout.cpp
    util/kernelcreator.cpp
    util/timestamp.cpp
    )
set(TS_FILES
    i18n/baselib_de_DE.ts
    )
target_include_directories(FVBaseLib
                           PUBLIC control
                           PUBLIC model
                           PUBLIC util
                           PUBLIC view
                           )
target_link_libraries(FVBaseLib
                      PRIVATE IFQt
                      PRIVATE IFLinuxCNC
                      PRIVATE IFOpenCASCADE
                      PRIVATE IFStandard
                      )
if(COMMAND qt_create_translation)
    qt_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
else()
    qt5_create_translation(QM_FILES ${CMAKE_SOURCE_DIR} ${TS_FILES})
endif()

the error-message:

/d/PUBLIC/FalconView/src/baselib/control/core.cpp:14:10: fatal error: emc.hh: Datei oder Verzeichnis nicht gefunden

… checking of file existance:

$ find /usr/local/src/linuxcnc-deb11/ -name emc.hh
/usr/local/src/linuxcnc-deb11/include/emc.hh
/usr/local/src/linuxcnc-deb11/src/emc/nml_intf/emc.hh

… my observation:
compiler commandline does not contain any of the include directories of IFlinuxCNC neither added with -I nor added with -isystem

  • so my unqualified suspicion: interface library is not used at all.

Hmm. Can you show the command line for core.cpp and the #include line you have in the source for that header?

Hmm. Can you show the command line for core.cpp and the #include line
you have in the source for that header?

To show what happened, here a diff of CMakeLists.txt:

target_include_directories(FVBaseLib
                            PUBLIC control
                            PUBLIC model
                            PUBLIC util
                            PUBLIC view
-                           PRIVATE ${LinuxCNC_DIR}/include
-                           PRIVATE ${LinuxCNC_DIR}/src
-                           PRIVATE ${LinuxCNC_DIR}/src/emc/rs274ngc
-                           PRIVATE ${LinuxCNC_DIR}/src/emc/tooldata
-                           PRIVATE ${Qt5Gui_PRIVATE_INCLUDE_DIRS}
-                           PRIVATE ${OpenCASCADE_INCLUDE_DIR}
                            )
 target_link_libraries(FVBaseLib
-                      PRIVATE Qt${QT_VERSION_MAJOR}::Gui
-                      PRIVATE Qt${QT_VERSION_MAJOR}::Widgets
-                      PRIVATE Qt${QT_VERSION_MAJOR}::Core
-                      PRIVATE Qt${QT_VERSION_MAJOR}::Sql
-                      PRIVATE Qt${QT_VERSION_MAJOR}::UiTools
-                      PRIVATE Qt${QT_VERSION_MAJOR}::Xml
-                      PRIVATE m stdc++ boost_python39 python3.9 crypt pthread 
dl util
-                      PRIVATE TKernel TKMath TKService TKV3d TKOpenGl
-                      PRIVATE TKBRep TKIGES TKSTL TKVRML TKSTEP TKSTEPAttr 
TKSTEP209
-                      PRIVATE TKSTEPBase TKGeomBase TKGeomAlgo TKG3d TKG2d
-                      PRIVATE TKXSBase TKShHealing TKHLR TKTopAlgo TKMesh 
TKPrim
-                      PRIVATE TKCDF TKBool TKBO TKFillet TKOffset TKLCAF TKCAF 
TKVCAF
-                      PRIVATE TKBin TKXml
+                      PRIVATE IFQt
+                      PRIVATE IFLinuxCNC
+                      PRIVATE IFOpenCASCADE
+                      PRIVATE IFStandard
                       )

and commandline of the old variant:

/usr/bin/c++
    -DQT_CORE_LIB
    -DQT_DISABLE_DEPRECATED_BEFORE=0x060000
    -DQT_GUI_LIB
    -DQT_SQL_LIB
    -DQT_UITOOLS_LIB
    -DQT_USE_QSTRINGBUILDER
    -DQT_WIDGETS_LIB
    -DQT_XML_LIB
    -DUSE_PLUGINS
    -I/d/linux/qt/build-FalconView_Test/src/baselib/FVBaseLib_autogen/include
    -I/d/PUBLIC/FalconView/src/baselib/control
    -I/d/PUBLIC/FalconView/src/baselib/model
    -I/d/PUBLIC/FalconView/src/baselib/util
    -I/d/PUBLIC/FalconView/src/baselib/view
    -I/usr/local/src/linuxcnc-deb11/include
    -I/usr/local/src/linuxcnc-deb11/src
    -I/usr/local/src/linuxcnc-deb11/src/emc/rs274ngc
    -I/usr/local/src/linuxcnc-deb11/src/emc/tooldata
    -I/opt/qt5.15/5.15.2/gcc_64/include/QtGui/5.15.2
    -I/opt/qt5.15/5.15.2/gcc_64/include/QtGui/5.15.2/QtGui
    -I/opt/qt5.15/5.15.2/gcc_64/include/QtCore/5.15.2
    -I/opt/qt5.15/5.15.2/gcc_64/include/QtCore/5.15.2/QtCore
    -I/usr/local/include/opencascade
    -isystem /opt/qt5.15/5.15.2/gcc_64/include
    -isystem /opt/qt5.15/5.15.2/gcc_64/include/QtGui
    -isystem /opt/qt5.15/5.15.2/gcc_64/include/QtCore
    -isystem /opt/qt5.15/5.15.2/gcc_64/./mkspecs/linux-g++
    -isystem /opt/qt5.15/5.15.2/gcc_64/include/QtWidgets
    -isystem /opt/qt5.15/5.15.2/gcc_64/include/QtSql
    -isystem /opt/qt5.15/5.15.2/gcc_64/include/QtUiTools
    -isystem /opt/qt5.15/5.15.2/gcc_64/include/QtXml
    -g
    -fPIC
    -std=gnu++17
    -o
    CMakeFiles/FVBaseLib.dir/control/core.cpp.o
    -c
    /d/PUBLIC/FalconView/src/baselib/control/core.cpp

… and here the variant of the new variant with interface libraries:

/usr/bin/c++
-DQT_CORE_LIB
-DQT_DISABLE_DEPRECATED_BEFORE=0x060000
-DQT_GUI_LIB
-DQT_SQL_LIB
-DQT_UITOOLS_LIB
-DQT_USE_QSTRINGBUILDER
-DQT_WIDGETS_LIB
-DQT_XML_LIB
-DUSE_PLUGINS
-I/d/linux/qt/build-FalconView_Test/src/baselib/FVBaseLib_autogen/include
-I/d/PUBLIC/FalconView/src/baselib/control
-I/d/PUBLIC/FalconView/src/baselib/model
-I/d/PUBLIC/FalconView/src/baselib/util
-I/d/PUBLIC/FalconView/src/baselib/view
-I/opt/qt5.15/5.15.2/gcc_64/include/QtGui/5.15.2
-I/opt/qt5.15/5.15.2/gcc_64/include/QtGui/5.15.2/QtGui
-I/opt/qt5.15/5.15.2/gcc_64/include/QtCore/5.15.2
-I/opt/qt5.15/5.15.2/gcc_64/include/QtCore/5.15.2/QtCore
-I/d/linux/qt/build-FalconView_Test
-I/d/PUBLIC/FalconView
-I/usr/local/include/opencascade
-isystem /opt/qt5.15/5.15.2/gcc_64/include
-isystem /opt/qt5.15/5.15.2/gcc_64/include/QtGui
-isystem /opt/qt5.15/5.15.2/gcc_64/include/QtCore
-isystem /opt/qt5.15/5.15.2/gcc_64/./mkspecs/linux-g++
-isystem /opt/qt5.15/5.15.2/gcc_64/include/QtWidgets
-isystem /opt/qt5.15/5.15.2/gcc_64/include/QtSql
-isystem /opt/qt5.15/5.15.2/gcc_64/include/QtUiTools
-isystem /opt/qt5.15/5.15.2/gcc_64/include/QtXml
-g
-fPIC
-std=gnu++17
-o
CMakeFiles/FVBaseLib.dir/control/core.cpp.o
-c
/d/PUBLIC/FalconView/src/baselib/control/core.cpp

… include statement from core.cpp is:

#include <emc.hh>

Hmm. This does seem quite odd. @brad.king can the file-api help here to poke into what might be wrong with those INTERFACE targets. I don’t see anything amiss here at least.

stupid question: I’m creating IMPORTED libraries for this and set the
respective target properties, and it works for me.
Is there a significant difference between IMPORTED and INTERFACE libraries ?

Thanks
Alex

INTERFACE targets can be exported and installed. IMPORTED targets have already had that happen to them. If you export a target depending on one of these IMPORTED targets, it will need to exist again at find_package() time for those targets to be of any use (basically, recreated in the config file in some way). IMPORTED targets are also scoped (by default) whereas INTERFACE targets are global (since they are “yours”). There are probably some other minor differences that I can’t think of right now.

stupid question: I’m creating IMPORTED libraries for this and set the
respective target properties, and it works for me.

Good hint. I tried that …
changed interface library definition to:

add_library(IFlinuxCNC    STATIC IMPORTED GLOBAL)
add_library(IFQt          STATIC IMPORTED GLOBAL)
add_library(IFOpenCASCADE STATIC IMPORTED GLOBAL)
add_library(IFStandard    STATIC IMPORTED GLOBAL)

that leaded to this compile statement:

/usr/bin/c++
-DQT_DISABLE_DEPRECATED_BEFORE=0x060000
-DQT_USE_QSTRINGBUILDER
-DUSE_PLUGINS
-I/d/linux/qt/build-FalconView_Test/src/baselib/FVBaseLib_autogen/include
-I/d/PUBLIC/FalconView/src/baselib/control
-I/d/PUBLIC/FalconView/src/baselib/model
-I/d/PUBLIC/FalconView/src/baselib/util
-I/d/PUBLIC/FalconView/src/baselib/view
-isystem /opt/qt5.15/5.15.2/gcc_64/include/QtGui/5.15.2
-isystem /opt/qt5.15/5.15.2/gcc_64/include/QtGui/5.15.2/QtGui
-isystem /opt/qt5.15/5.15.2/gcc_64/include/QtCore/5.15.2
-isystem /opt/qt5.15/5.15.2/gcc_64/include/QtCore/5.15.2/QtCore
-isystem /usr/local/include/opencascade
-g
-std=gnu++17
-o
CMakeFiles/FVBaseLib.dir/FVBaseLib_autogen/mocs_compilation.cpp.o
-c
/d/linux/qt/build-FalconView_Test/src/baselib/FVBaseLib_autogen/
mocs_compilation.cpp

with error message

could not find include file "QObject"

apparently all qt include definitions from package have disappeared. Only my
“private” include directory was used.

Interestingly no include definition of “my” IFlinuxCNC definition made it into
compile command line.

So I removed my include definition from IFQt which leaded to this compile
command line:

/usr/bin/c++
-DQT_DISABLE_DEPRECATED_BEFORE=0x060000
-DQT_USE_QSTRINGBUILDER
-DUSE_PLUGINS
-I/d/linux/qt/build-FalconView_Test/src/baselib/FVBaseLib_autogen/include
-I/d/PUBLIC/FalconView/src/baselib/control
-I/d/PUBLIC/FalconView/src/baselib/model
-I/d/PUBLIC/FalconView/src/baselib/util
-I/d/PUBLIC/FalconView/src/baselib/view
-isystem /usr/local/include/opencascade
-g
-std=gnu++17
-o
CMakeFiles/FVBaseLib.dir/FVBaseLib_autogen/mocs_compilation.cpp.o
-c
/d/linux/qt/build-FalconView_Test/src/baselib/FVBaseLib_autogen/
mocs_compilation.cpp

which shows, that now there’s no include definitions for qt-packages any more.

Hm, not what I was looking for.
I wanted to “extend” package definition so that I have to use one target only.
Replacing package definition makes little sense to me.