Good morning, I’ve an issue with my current build, I’m also using Conan 2.2.2 and I’m attempting to use the following cmake command for generating the build:
cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_TOOLCHAIN_FILE="./conan_toolchain.cmake" -DCMAKE_PREFIX_PATH="../build" ..\BIM-ArchiCAD-Plugin\
This after the cona install ...
command that download the recipes and generated the config files that are passed through the conan_toolchain.cmake file.
The issue consists in the fact that the generated VS project is lacking of include directories in all the project/modules it is built.
I’m attempting a porting of these CMakeLists.txt (and the other one in cmake/Archicad.cmake), because they were previously working with Conan 1.60.2, and now I’ve to upgrade Conan to the latest version I’m encountering some errors in the CMake building step.
CMakeLists.txt
cmake_minimum_required(VERSION 3.20)
if(DEFINED ENV{KnaufPlannerSuiteVersion})
message(Use version $ENV{KnaufPlannerSuiteVersion})
project(KnaufPlannerSuite VERSION $ENV{KnaufPlannerSuiteVersion} LANGUAGES CXX)
else()
message(Use version 0.0.0.0)
project(KnaufPlannerSuite VERSION 0.0.0.0 LANGUAGES CXX)
endif()
find_package(Boost REQUIRED COMPONENTS filesystem)
find_package(gsl-lite REQUIRED)
find_package(magic_enum REQUIRED)
find_package(range-v3 REQUIRED)
find_package(spdlog REQUIRED)
find_package(catch2 REQUIRED)
find_package(fakeit REQUIRED)
set(Boost_USE_STATIC_LIBS ON) # We could be header-only on macOS with AC26+
if(NOT LANGUAGE)
message(FATAL_ERROR "LANGUAGE must be set. Check 'language' option in conanfile.py.")
endif()
include(cmake/Archicad.cmake)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
configure_file(PlannerSuite/Resources/RFIX.win/version.rc2.in PSResourceObjects/version.rc2) # copies version.rc2.in and replaces versionstrings from defines or something, seemingly not from the ENV{KnaufPlannerSuiteVersion}) here
add_library(Common OBJECT
Common/ArchicadApi.h
Common/ArchicadApi.cpp
Common/AttributeManager.cpp
Common/AttributeManager.h
Common/ClassificationItem.cpp
Common/ClassificationItem.h
Common/ClassificationSystem.cpp
Common/ClassificationSystem.h
Common/CommandId.cpp
Common/CommandId.h
Common/Element.cpp
Common/Element.h
Common/ElementManager.cpp
Common/ElementManager.h
Common/Favorite.cpp
Common/Favorite.h
Common/Logger.cpp
Common/Logger.h
Common/OperatingSystem.cpp
Common/OperatingSystem.h
Common/Preferences.cpp
Common/Preferences.h
Common/PropertyManager.cpp
Common/PropertyManager.h
Common/PluginIpcCommandTask.cpp
Common/PluginIpcCommandTask.h
Common/Resources.cpp
Common/Resources.h
Common/System.cpp
Common/System.h
Common/SystemUses.cpp
Common/SystemUses.h
Common/TenderingVariable.cpp
Common/TenderingVariable.h
Common/environmentVariable.cpp
Common/environmentVariable.h
Common/graphisoft_error.cpp
Common/graphisoft_error.h
Common/json.cpp
Common/leafErrorHandler.cpp
Common/leafErrorHandler.h
Common/pluginLanguage.cpp
Common/pluginLanguage.h
Common/translate.cpp
Common/translate.h
Common/updatePlugin.cpp
Common/updatePlugin.h
Common/Utilities.h
Common/Utilities.cpp
Common/create.cpp
Common/create.h
)
target_link_libraries(Common PUBLIC
archicad_adk::archicad_adk
gsl::gsl-lite
magic_enum::magic_enum
range-v3::range-v3
spdlog::spdlog_header_only
)
target_include_directories(Common PUBLIC .)
target_compile_definitions(Common PUBLIC
BOOST_ALL_NO_LIB
BOOST_LEAF_NO_THREADS
GSMALLOC_HPP
gsl_CONFIG_NARROW_THROWS_ON_TRUNCATION
)
if(CMAKE_CXX_COMPILER_ID MATCHES "AppleClang|Clang|GNU")
target_compile_options(Common PUBLIC -fvisibility=hidden)
endif()
add_library(${PROJECT_NAME} MODULE
PlannerSuite/Application.cpp
PlannerSuite/Application.h
PlannerSuite/Menu.cpp
PlannerSuite/Menu.h
PlannerSuite/BrowserPluginCommunication.cpp
PlannerSuite/BrowserPluginCommunication.h
PlannerSuite/ExecuteIpcCommand.cpp
PlannerSuite/ExecuteIpcCommand.h
PlannerSuite/TestService.cpp
PlannerSuite/TestService.h
PlannerSuite/main.cpp
$<TARGET_OBJECTS:Common>
)
# sets a #define for VERSION variable and only this cpp I guess
set_source_files_properties(PlannerSuite/Application.cpp PROPERTIES
COMPILE_DEFINITIONS "VERSION=\"${KnaufPlannerSuite_VERSION}\"")
add_library(UnitTests OBJECT
UnitTests/AttributeTests.cpp
UnitTests/ElementTests.cpp
UnitTests/EnvironmentTests.cpp
UnitTests/ErrorTests.cpp
)
target_link_libraries(UnitTests PUBLIC
Common archicad_adk::archicad_adk Catch2::Catch2WithMain fakeit::fakeit)
target_include_directories(UnitTests PUBLIC .)
add_library(KnaufTestRunner MODULE # this add-on runs integration tests on open events
TestRunner/CheckDataTests.cpp
TestRunner/DialogTests.cpp
TestRunner/ImportTests.cpp
TestRunner/JsonTestData.h
TestRunner/Parameters.cpp
TestRunner/Parameters.h
TestRunner/ProjectSettingsTests.cpp
TestRunner/SystemTests.cpp
TestRunner/TenderingTests.cpp
TestRunner/UpdateTests.cpp
TestRunner/VersionsTests.cpp
TestRunner/main.cpp
$<TARGET_OBJECTS:Common>
$<TARGET_OBJECTS:UnitTests>
)
add_executable(runUnitTests
EXCLUDE_FROM_ALL
UnitTests/main.cpp
UnitTests/stubs.cpp
$<TARGET_OBJECTS:Common>
$<TARGET_OBJECTS:UnitTests>
)
# Maybe it's not necessary to enable_testing()/add_test(...) with just one executable.
target_link_libraries(runUnitTests PUBLIC UnitTests)
# PENDING: package {GSRoot,GSUtils,GSXML,GSXMLUtils,GSZLib,InputOutput,Network,ObjectDatabase}.dll
if(WIN32)
if(NOT DEFINED ENV{BUILD_TYPE} AND DEFINED ENV{KNAUFTESTRUNNER_TAGS}) # BUILD_TYPE is only used in CI builds, maybe check for better sign of local execution later
set(TEST_RESULT_NAME archicadIntegrationTest.xml)
add_custom_command(TARGET runUnitTests POST_BUILD
COMMENT "Copy KnaufTestRunner and start integration tests"
COMMAND if exist ${TEST_RESULT_NAME} del ${TEST_RESULT_NAME}
COMMAND xcopy "Debug\\KnaufTestRunner.apx" "C:\\Program Files\\GRAPHISOFT\\ARCHICAD 26\\Add-Ons\\KnaufTestRunner\\" /Y
COMMAND set KNAUF_ARCHICAD_TEST=-o ${TEST_RESULT_NAME} $ENV{KNAUFTESTRUNNER_TAGS}
COMMAND set KNAUF_BIMPLUGIN_URL=invalid:url_for_tests
COMMAND "C:\\Program Files\\OpenCppCoverage\\OpenCppCoverage.exe" --modules *Knauf*.apx --sources *BIM-ArchiCAD-Plugin* -- "C:\\Program Files\\GRAPHISOFT\\ARCHICAD 26\\ARCHICAD.exe" -DEMO "C:\\missing.pln"
)
endif()
endif()
target_link_libraries(Common PUBLIC Boost::filesystem)
target_link_libraries(${PROJECT_NAME} PUBLIC Common)
target_link_libraries(KnaufTestRunner PUBLIC Common Catch2::Catch2WithMain)
set(PS_RESDIR ${CMAKE_CURRENT_BINARY_DIR}/PSResourceObjects)
set(TR_RESDIR ${CMAKE_CURRENT_BINARY_DIR}/TRResourceObjects)
list(GET LANGUAGE 0 LANG_ARCHICAD)
if(APPLE)
set(INFO_PLIST PlannerSuite/Resources/RFIX.mac/Info.plist) # shared with TestRunner
set_target_properties(${PROJECT_NAME} KnaufTestRunner PROPERTIES
BUNDLE TRUE
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_LIST_DIR}/${INFO_PLIST}"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/$<CONFIG>"
)
target_sources(${PROJECT_NAME} PRIVATE ${PS_RESDIR}/Resources.stamp)
target_sources(KnaufTestRunner PRIVATE ${TR_RESDIR}/Resources.stamp)
archicad_compile_py(Common PlannerSuite/Resources
${PROJECT_NAME}.bundle ${PS_RESDIR} ${LANG_ARCHICAD} ${INFO_PLIST})
archicad_compile_py(Common TestRunner/Resources
KnaufTestRunner.bundle ${TR_RESDIR} INT ${INFO_PLIST})
elseif(WIN32)
add_executable(Updater)
target_sources(Updater PUBLIC
Updater/updater.cpp
)
set_target_properties(Updater PROPERTIES LINKER_LANGUAGE CXX)
target_link_libraries(Updater PUBLIC
spdlog::spdlog_header_only
)
# copy updater.exe to the build dir, where it will be picked up from Github actions
add_custom_command(
TARGET Updater
POST_BUILD
COMMAND ${CMAKE_COMMAND}
ARGS -E copy $<TARGET_FILE:Updater> ${CMAKE_CURRENT_BINARY_DIR}
)
set_target_properties(${PROJECT_NAME} PROPERTIES SUFFIX ".bin") # muirct.exe writes .apx
set_target_properties(KnaufTestRunner PROPERTIES SUFFIX ".apx")
archicad_resconv(PlannerSuite/Resources R${LANG_ARCHICAD}/PlannerSuite.grc "${PS_RESDIR}")
archicad_resconv(PlannerSuite/Resources RFIX/PlannerSuiteFix.grc "${PS_RESDIR}") # this contains some value regarding Archicad API handling like a developer ID
archicad_resconv(TestRunner/Resources RFIX/TestRunnerFix.grc "${TR_RESDIR}")
set(ResourceFilePS PlannerSuite/Resources/RFIX.win/PlannerSuite.rc2)
set(ResourceFileTR TestRunner/Resources/RFIX.win/TestRunner.rc2)
target_sources(${PROJECT_NAME} PRIVATE ${ResourceFilePS}
${PS_RESDIR}/PlannerSuite.grc.rc2 ${PS_RESDIR}/PlannerSuiteFix.grc.rc2)
target_sources(KnaufTestRunner PRIVATE ${ResourceFileTR}
${TR_RESDIR}/TestRunnerFix.grc.rc2)
set_source_files_properties(${ResourceFilePS} PROPERTIES
LANGUAGE RC
INCLUDE_DIRECTORIES "${PS_RESDIR};${CMAKE_CURRENT_SOURCE_DIR}/Common"
)
set_source_files_properties(${ResourceFileTR} PROPERTIES
LANGUAGE RC
INCLUDE_DIRECTORIES "${TR_RESDIR};${CMAKE_CURRENT_SOURCE_DIR}/Common"
)
list(GET LANGUAGE 1 LANG_MICROSOFT)
list(GET LANGUAGE 2 LANG_NAME)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
BYPRODUCTS ${PROJECT_NAME}.apx ${LANG_NAME}/${PROJECT_NAME}.apx
)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
BYPRODUCTS ${PROJECT_NAME}.apx ${LANG_NAME}/${PROJECT_NAME}.apx # BYPRODUCTS specifies that the listed files should be there
COMMAND ${CMAKE_COMMAND} -E make_directory ${LANG_NAME}
COMMAND muirct -q ${CMAKE_CURRENT_LIST_DIR}/muirct.xml -x ${LANG_MICROSOFT} -g 0x0409 # -q -x -g specifies the language ID to be included as the ultimate fallback language in the resource configuration data section of the LN fileThe LangID value can be specified in decimal or hexadecimal format. For example -g 0x409 or -g 1033 is English (United States)
"$<TARGET_FILE:KnaufPlannerSuite>" ${PROJECT_NAME}.apx ${LANG_NAME}/${PROJECT_NAME}.apx.mui
MAIN_DEPENDENCY muirct.xml DEPENDS "$<TARGET_FILE:KnaufPlannerSuite>"
VERBATIM
)
if(WIN32)
if(NOT DEFINED ENV{BUILD_TYPE}) # BUILD_TYPE is only used in CI builds, maybe check for better sign of local execution later
add_custom_command(TARGET "KnaufPlannerSuite" POST_BUILD
COMMENT "Copying to default Archicad 26 directory (requires admin rights)..."
COMMAND xcopy KnaufPlannerSuite.apx "C:\\Program Files\\GRAPHISOFT\\ARCHICAD 26\\Add-Ons\\KnaufBimPlugin\\" /Y
)
endif()
endif()
endif()
Archicad.cmake
find_package(archicad_adk REQUIRED)
get_target_property(target_includes archicad_adk::archicad_adk INTERFACE_INCLUDE_DIRECTORIES)
message("Include directory: ${target_includes}")
add_library(archicad_headers INTERFACE IMPORTED)
if(ARCHICAD_VERSION LESS 26)
target_include_directories(archicad_headers SYSTEM AFTER INTERFACE
${archicad_adk_INCLUDE_DIRS}
${archicad_adk_INCLUDE_DIRS}/Archicad
${archicad_adk_INCLUDE_DIRS}/Archicad/GSUtils
${archicad_adk_INCLUDE_DIRS}/Archicad/DGLib
${archicad_adk_INCLUDE_DIRS}/Archicad/ObjectDatabase
${archicad_adk_INCLUDE_DIRS}/Archicad/GSRootc
${archicad_adk_INCLUDE_DIRS}/Archicad/Graphix
${archicad_adk_INCLUDE_DIRS}/Archicad/HTTP
${archicad_adk_INCLUDE_DIRS}/Archicad/InputOutput
${archicad_adk_INCLUDE_DIRS}/Archicad/Network
${archicad_adk_INCLUDE_DIRS}/Archicad/SecureCommunication
${archicad_adk_INCLUDE_DIRS}/Archicad/TextEngine
)
else()
target_include_directories(archicad_headers SYSTEM AFTER INTERFACE
${archicad_adk_INCLUDE_DIRS}
${archicad_adk_INCLUDE_DIRS}/Archicad
${archicad_adk_INCLUDE_DIRS}/Archicad/GSUtils
${archicad_adk_INCLUDE_DIRS}/Archicad/DGLib
# ${archicad_adk_INCLUDE_DIRS}/include/Archicad/ObjectDatabase #is missing since ADK 26
${archicad_adk_INCLUDE_DIRS}/Archicad/GSRoot
${archicad_adk_INCLUDE_DIRS}/Archicad/Graphix
${archicad_adk_INCLUDE_DIRS}/Archicad/HTTP
${archicad_adk_INCLUDE_DIRS}/Archicad/InputOutput
${archicad_adk_INCLUDE_DIRS}/Archicad/Network
${archicad_adk_INCLUDE_DIRS}/Archicad/SecureCommunication
${archicad_adk_INCLUDE_DIRS}/Archicad/TextEngine
)
endif()
target_link_libraries(archicad_adk::archicad_adk INTERFACE archicad_headers)
get_target_property(target_includes archicad_adk::archicad_adk INTERFACE_INCLUDE_DIRECTORIES)
message("Include directory: ${target_includes}")
if(ARCHICAD_VERSION LESS 26)
set(FRAMEWORKS DG Graphix GSRoot GSUtils HTTP InputOutput ObjectDatabase TextEngine JSON)
else()
set(FRAMEWORKS DG Graphix GSRoot GSUtils HTTP InputOutput TextEngine JSON)
endif()
if(NOT ARCHICAD_VERSION LESS 25)
list(APPEND FRAMEWORKS RS)
target_include_directories(archicad_headers SYSTEM AFTER INTERFACE ${archicad_adk_INCLUDE_DIRS}/Archicad/RS)
endif()
if(ARCHICAD_VERSION LESS 24)
list(APPEND FRAMEWORKS VectorImage)
endif()
if(APPLE)
add_library(Archicad::macos INTERFACE IMPORTED)
target_link_options(Archicad::macos INTERFACE
"-Wl,-rpath,${archicad_adk_INCLUDE_DIRS}/lib/Frameworks"
"-F${archicad_adk_INCLUDE_DIRS}/lib/Frameworks")
endif()
foreach(name ${FRAMEWORKS})
if(APPLE)
add_library(Archicad::${name} INTERFACE IMPORTED)
target_link_libraries(Archicad::${name} INTERFACE Archicad::macos)
target_link_options(Archicad::${name} INTERFACE "SHELL:-framework ${name}")
elseif(WIN32)
add_library(Archicad::${name} SHARED IMPORTED)
set_property(TARGET Archicad::${name} PROPERTY IMPORTED_LOCATION
"${archicad_adk_INCLUDE_DIRS}/bin/${name}.dll")
set_property(TARGET Archicad::${name} PROPERTY IMPORTED_IMPLIB
"${archicad_adk_INCLUDE_DIRS}/lib/${name}Imp.LIB")
endif()
target_link_libraries(archicad_adk::archicad_adk INTERFACE Archicad::${name})
endforeach()
if(APPLE)
find_library(CocoaFramework Cocoa)
target_link_libraries(archicad_adk::archicad_adk INTERFACE
${CocoaFramework}
"${archicad_adk_INCLUDE_DIRS}/lib/libACAP_STAT.a")
elseif(WIN32)
target_link_libraries(archicad_adk::archicad_adk INTERFACE
"${archicad_adk_INCLUDE_DIRS}/lib/ACAP_STAT$<$<CONFIG:Debug>:D>.lib")
target_link_options(archicad_adk::archicad_adk INTERFACE
/export:GetExportedFuncAddrs,@1
/export:SetImportedFuncAddrs,@2)
endif()
target_compile_definitions(archicad_headers INTERFACE ACExtension)
if(APPLE)
if(NOT ARCHICAD_VERSION LESS 25)
target_compile_options(archicad_headers INTERFACE -mmacosx-version-min=10.15)
target_link_options(archicad_headers INTERFACE -mmacosx-version-min=10.15)
elseif(NOT ARCHICAD_VERSION LESS 24)
target_compile_options(archicad_headers INTERFACE -mmacosx-version-min=10.14)
target_link_options(archicad_headers INTERFACE -mmacosx-version-min=10.14)
endif()
target_compile_definitions(archicad_headers INTERFACE macintosh)
elseif(WIN32)
# GRAPHISOFT suggests to set /Zc:wchar_t-.
# We need wchar_t for Microsoft's IFileOperation APIs, so we shouldn't try to disable it.
target_compile_options(archicad_headers INTERFACE /Gr) # /Gr := __fastcall
# target_compile_definitions(archicad_headers INTERFACE UNICODE _UNICODE)
# target_compile_definitions(archicad_headers INTERFACE WINDOWS _USRDLL)
endif()
function(archicad_compile_py srcDir resDir macBundleOut outDir language) # depends...
set(depends ${ARGN})
cmake_path(ABSOLUTE_PATH srcDir)
cmake_path(ABSOLUTE_PATH resDir)
set(bundle "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>/${macBundleOut}")
set(result "${bundle}/Contents/Resources")
if(APPLE)
list(APPEND depends "${bundle}/Contents/PkgInfo")
endif()
add_custom_command(
OUTPUT "${bundle}/Contents/PkgInfo"
COMMENT "Writing PkgInfo..."
COMMAND ${CMAKE_COMMAND} -E echo ".APXGSAP" > "${bundle}/Contents/PkgInfo"
)
add_custom_command(
OUTPUT "${outDir}/Resources.stamp"
DEPENDS ${depends}
COMMENT "Compiling resources..."
COMMAND ${CMAKE_COMMAND} -E make_directory "${outDir}/R${language}"
COMMAND python3 "${CMAKE_SOURCE_DIR}/cmake/CompileResources.py" "${language}"
"${archicad_adk_INCLUDE_DIRS}" "${srcDir}" "${resDir}" "${outDir}" "${result}"
COMMAND ${CMAKE_COMMAND} -E touch "${outDir}/Resources.stamp"
)
endfunction()
function(archicad_resconv resDir grc resOutDir)
set(input "${resDir}/${grc}")
cmake_path(GET grc FILENAME name)
set(output "${resOutDir}/${name}.rc2")
cmake_path(ABSOLUTE_PATH input OUTPUT_VARIABLE absInput)
cmake_path(ABSOLUTE_PATH output OUTPUT_VARIABLE absOutput)
cmake_path(ABSOLUTE_PATH resDir OUTPUT_VARIABLE absResDir)
add_custom_command(
OUTPUT "${output}"
DEPENDS "${input}"
COMMENT "Running Archicad ResConv..."
WORKING_DIR ${resOutDir}
COMMAND "${archicad_adk_INCLUDE_DIRS}/bin/ResConv"
-m r -T W -q utf8 1252 -w 2 -p "${absResDir}/RFIX/Images"
-i "${absInput}" -o "${absOutput}"
)
endfunction()
I would really appreciate the help of someone, thanks in advance.
If you want I can give you the files I used in the 1.60.2 versino of Conan, also I tried to manually declare the used include directories in the project, and I can see them in the project and they are correct, but for some reasons they aren’t working as supposed (if I ctrl click on the include it says that it can’t find the file even if the compiler doesn’t highlight as error the path)…