How to correctly include header files for compilation of cxx SWIG wrapped files ?

Hi, I’m almost newbie in CMake and SWIG. Currently I’m using CMake 3.23.3 and SWIG 4.0.2. I’m trying to compile the .cxx file wrapped from a C++ project in order to create a Python package. Can you confirm me that the instruction set_property is still valid, or should I use set_target_properties(myProject PROPERTIES SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE) instead ? Here is the current minimum version of my project (GitHub - jsn-inrs/GravForcesProcessor: Python package wrapped from C++ code to implement features about Gravity Forces not available in OpenSim'sPython API). Generation of the Python package with VS2019 fails because an included header file is not found ("Unable to find ‘spdlog\spdlog.h’ ") however the C++ dll and test executable are correctly processed. Would you please help in the jungle of CMake / SWIG ? Thanks in advance…

Is SWIG generating the spdlog.h include? If not, whatever target has the header that does so should PUBLIC or INTERFACE depend on some target that provides spdlog headers or the variable if you’re not using a target.

Thank you very much for the attention you gave to this topic. Unfortunately, I’m not sure to understand the answer correctly. Actually, the “spdlog.h” is not a part of my project, and it is not generated by swig. It’s an external project (GitHub - gabime/spdlog: Fast C++ logging library.) used in my code.
My CMakeLists.txt files contains the following instructions (see https://github.com/jsn-inrs/GravForcesProcessor/blob/main/CMakeLists.txt lines 102+):

set_target_properties(swigGravForcesProcessor PROPERTIES SWIG_USE_TARGET_INCLUDE_DIRECTORIES TRUE)
target_include_directories(swigGravForcesProcessor PUBLIC ${SPDLOG_INCLUDE_DIRS})
target_link_libraries(swigGravForcesProcessor ${SPDLOG_LIBRARIES})
target_compile_definitions(swigGravForcesProcessor PRIVATE ${SPDLOG_COMPILE_DEFINITIONS})

So I think what you’ve highlighted is accounted for, isn’t it ? Thanks in advance

Ah, sorry. By

I meant the #include line, not the file itself.

Yes, that looks fine to me. If you run a verbose build, do you see the include path for spdlog.h there? Does your target compile properly before SWIG tries to wrap it? Can you provide the full error that you get for better context?

I’m not used to this forum (how to attach a file ?). Here after are the last trace lines in “detailed” verbose mode (otherwise it’s far too long for this post). By the way, I’ve jumped to CMake 3.27, I don’t think it matters a lot (same error):

2>  Task "CustomBuild"
2>    setlocal
2>    "C:\Program Files\CMake\bin\cmake.exe" -E make_directory C:/Users/jonathan.savin/Documents/WIP/SwigGravityForcesProcessor/build/CMakeFiles/swigGravForcesProcessor.dir C:/Users/jonathan.savin/Documents/WIP/SwigGravityForcesProcessor/build C:/Users/jonathan.savin/Documents/WIP/SwigGravityForcesProcessor/wrapper
2>    if %errorlevel% neq 0 goto :cmEnd
2>    "C:\Program Files\CMake\bin\cmake.exe" -E env SWIG_LIB=C:/ProgramData/chocolatey/lib/swig/tools/install/swigwin-4.0.2/Lib C:/ProgramData/chocolatey/bin/swig.exe -python -includeall -outdir C:/Users/jonathan.savin/Documents/WIP/SwigGravityForcesProcessor/build -c++ -module GravForcesProcessor -interface _GravForcesProcessor -o C:/Users/jonathan.savin/Documents/WIP/SwigGravityForcesProcessor/wrapper/GravForcesProcessorPYTHON_wrap.cxx C:/Users/jonathan.savin/Documents/WIP/SwigGravityForcesProcessor/GravForcesProcessor.i
2>    if %errorlevel% neq 0 goto :cmEnd
2>    :cmEnd
2>    endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
2>    :cmErrorLevel
2>    exit /b %1
2>    :cmDone
2>    if %errorlevel% neq 0 goto :VCEnd
2>    Swig compile GravForcesProcessor.i for python
2>    C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.h(15): error : Unable to find 'spdlog\spdlog.h'
2>    C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.i(20): error : Unable to find 'spdlog\spdlog.h'
2>    C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.i(23): error : Unable to find 'spdlog\common.h'
2>    C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.i(24): error : Unable to find 'spdlog\logger.h'
2>    C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.i(25): error : Unable to find 'spdlog\sinks\stdout_color_sinks.h'
2>    C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.i(26): error : Unable to find 'spdlog\fmt\ostr.h'
2>    C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(241,5): error MSB8066: Custom build for 'C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.i' exited with code 1.
2>    The command exited with code 1.
2>  Done executing task "CustomBuild" -- FAILED.
2>Done building target "CustomBuild" in project "swigGravForcesProcessor.vcxproj" -- FAILED.
2>
2>Done building project "swigGravForcesProcessor.vcxproj" -- FAILED.
2>
2>Build FAILED.
2>
2>C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.h(15): error : Unable to find 'spdlog\spdlog.h'
2>C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.i(20): error : Unable to find 'spdlog\spdlog.h'
2>C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.i(23): error : Unable to find 'spdlog\common.h'
2>C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.i(24): error : Unable to find 'spdlog\logger.h'
2>C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.i(25): error : Unable to find 'spdlog\sinks\stdout_color_sinks.h'
2>C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.i(26): error : Unable to find 'spdlog\fmt\ostr.h'
2>C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Microsoft\VC\v160\Microsoft.CppCommon.targets(241,5): error MSB8066: Custom build for 'C:\Users\jonathan.savin\Documents\WIP\SwigGravityForcesProcessor\GravForcesProcessor.i' exited with code 1.
2>    0 Warning(s)
2>    7 Error(s)
2>
2>Time Elapsed 00:00:00.58
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

Hmm, it seems that swig is not getting the -I flags at all… I wonder if using an IMPORTED target for spdlog would make this a lot smoother? Anyways, I see that directory properties are used. Maybe:

include_directories(${SPDLOG_INCLUDE_DIRS})

would work in the meantime?

thank you so much for persevering to help me. As a beginner in CMake and SWIG, I’ve tried to piece together snippets of CMake code I’ve found here and there, and I’m progressing a bit blindly. Actually, your advice is already implemented in my CMakeLists.txt, line 20:

include_directories(${SPDLOG_INCLUDE_DIR})

Obviously the final ‘S’ (_DIR or _DIRS) doesn’t matter, the building fails with the same error messages. I feel quite lost… Any idea, advice or explanation will be graetly appreciated ! Thanks in advance.

Hrm. This is outside of my SWIG/CMake knowledge at this point as that looks like it should work. Maybe someone else can help further though.

The next steps for investigating would be to trace how FindSWIG builds up -I flags for swig itself and find a place to add things to one of those sources (--trace-expand to the configure would be the tool I’d start with).