2024-01-25 06:02 PM - last edited on 2024-09-16 02:46 PM by Doreena Deng
AC27 | WIN10 | VS2019, Toolset 142
.
The learning curve is starting to flatten out... but here is something new for me.
I have a project [JHP_Audit] with a folder structure like this:
My CMakeLists.txt file is in the ..\JHP_Audit\ folder and is here:
cmake_minimum_required (VERSION 3.16)
include (Tools/CMakeCommon.cmake)
set (API_DEVKIT_DIR $ENV{AC_API_DEVKIT_DIR} CACHE PATH "API DevKit directory.")
if (GITHUB_BUILD)
include(${CMAKE_BINARY_DIR}/conan_paths.cmake)
set (API_DEVKIT_DIR ${CONAN_ARCHICAD-APIDEVKIT_ROOT}/bin)
endif ()
set_property (GLOBAL PROPERTY USE_FOLDERS ON)
# set (CMAKE_CONFIGURATION_TYPES Debug;Release;RelWithDebInfo)
set (CMAKE_CONFIGURATION_TYPES Release)
set (AC_API_DEVKIT_DIR ${API_DEVKIT_DIR} CACHE PATH "API DevKit directory.")
set (AC_ADDON_NAME "JHP_Audit" CACHE STRING "AddOn Name")
set (AC_ADDON_LANGUAGE "INT" CACHE STRING "Add-On language code.")
project (${AC_ADDON_NAME} CXX)
message( STATUS ">>> AC_API_DEVKIT_DIR: $ENV{AC_API_DEVKIT_DIR}")
DetectACVersion (${AC_API_DEVKIT_DIR} ACVersion)
message (STATUS "Archicad Version: ${ACVersion}")
set (AddOnFolder .)
message (STATUS ">>> AddOnFolder: ${AddOnFolder}")
SetGlobalCompilerDefinitions ()
GenerateAddOnProject (${ACVersion} ${AC_API_DEVKIT_DIR} ${AC_ADDON_NAME} ${AddOnFolder} ${AC_ADDON_LANGUAGE})
set_target_properties(${AC_ADDON_NAME} PROPERTIES LINKER_LANGUAGE CXX)
The main file is JHP_Audit.cpp and in the ..\JHP_Audit\Src\ folder.
I have other *.cpp and *.h files in:
..\JHP_Audit\Src\Audits\
..\JHP_Audit\Src\JHPCommon\
..\JHP_Audit\Src\LiveAudit\
..\JHP_Audit\Src\Report\
I am receiving "error LNK2019: unresolved external symbol" errors when I build and I suspect it is because CMake does not know about these additional files in the folders listed above. Research in that direction reveals target_sources() as the CMake edit to resolve this.
CMake documentation is not clear to me for the exact syntax I should use to accomplish this.
I will try:
..\JHP_Audit\CMakeLists.txt
project(JHP_Audit)
add_executable(JHP_Audit "")
add_subdirectory(./Src/Audits)
add_subdirectory(./Src/JHPCommon)
add_subdirectory(./Src/LiveAudit)
add_subdirectory(./Src/Report)
..\JHP_Audit\Src\<each subdirectory>\CMakeLists.txt. Filenames for .ccp and .h as required.
target_sources(JHP_Audit
PRIVATE
Audits_Beams.cpp
Audits_Beams.h
Audits_Dimensions.cpp
Audits_Dimensions.h
#<all others>.cpp
#<all others>.h
)
target_include_directories(JHP_Audit PUBLIC ${CMAKE_CURRENT_LIST_DIR})
- - I am not clear on my use of JHP_Audit in the code snippets above - - Do I need full path, relative path? Is it a logical name that I have defined earlier? I know files used by target_sources() can stand alone without path
- - My example linked below uses add_library() that I have swapped with add_executable() - - Is that necessary? Is that accurate?
- - I currenlty do not have a definition for CMAKE_CURRENT_LIST_DIR. it is created and appended on the fly with each of the passes through the subdirectory CMakeLists.txt files.
- - Do I need to delete cache and generate CMake cache to load variables for each of the five CMakeLists.txt files?
Source of information:
https://crascit.com/2016/01/31/enhanced-source-file-handling-with-target_sources/
Thanks as always,
chris
2024-01-25 06:43 PM - edited 2024-01-25 06:44 PM
Update a few minutes later:
After implementing the above edits, a build will still generate "error LNK2019: unresolved external symbol" and ultimately "JHP_Audit.apx : fatal error LNK1120: 29 unresolved externals".
But now there are errors associatred with the .ccp files and .h files in the subdirectories. And they seem to relate to missing files that are generic and would have been prior issues in other add-ons.
G:\dev\v27\JHP_Audit\out\build\x64-Release\Release\JHP_Audit.apx : fatal error LNK1120: 29 unresolved externals
Building Custom Rule G:/dev/v27/JHP_Audit/CMakeLists.txt
Audits_Beams.cpp
G:\dev\v27\JHP_Audit\Src\APIEnvir.h(22,11): fatal error C1083: Cannot open include file: 'Win32Interface.hpp': No such file or directory
Audits_Dimensions.cpp
G:\dev\v27\JHP_Audit\Src\APIEnvir.h(22,11): fatal error C1083: Cannot open include file: 'Win32Interface.hpp': No such file or directory
Audits_Generic.cpp
G:\dev\v27\JHP_Audit\Src\APIEnvir.h(22,11): fatal error C1083: Cannot open include file: 'Win32Interface.hpp': No such file or directory
Audits_Railings.cpp
G:\dev\v27\JHP_Audit\Src\APIEnvir.h(22,11): fatal error C1083: Cannot open include file: 'Win32Interface.hpp': No such file or directory
Audits_Walls.cpp
G:\dev\v27\JHP_Audit\Src\APIEnvir.h(22,11): fatal error C1083: Cannot open include file: 'Win32Interface.hpp': No such file or directory
Audits_Windows.cpp
G:\dev\v27\JHP_Audit\Src\APIEnvir.h(22,11): fatal error C1083: Cannot open include file: 'Win32Interface.hpp': No such file or directory
Format.cpp
G:\dev\v27\JHP_Audit\Src\APIEnvir.h(22,11): fatal error C1083: Cannot open include file: 'Win32Interface.hpp': No such file or directory
Math.cpp
G:\dev\v27\JHP_Audit\Src\JHPCommon\Math.h(3,13): fatal error C1083: Cannot open include file: 'ACAPinc.h': No such file or directory
Utilities.cpp
G:\dev\v27\JHP_Audit\Src\JHPCommon\Utilities.h(3,13): fatal error C1083: Cannot open include file: 'ACAPinc.h': No such file or directory
LiveAudit.cpp
G:\dev\v27\JHP_Audit\Src\APIEnvir.h(22,11): fatal error C1083: Cannot open include file: 'Win32Interface.hpp': No such file or directory
LiveAudit_Palette.cpp
G:\dev\v27\JHP_Audit\Src\APIEnvir.h(22,11): fatal error C1083: Cannot open include file: 'Win32Interface.hpp': No such file or directory
AuditReport.cpp
G:\dev\v27\JHP_Audit\Src\APIEnvir.h(22,11): fatal error C1083: Cannot open include file: 'Win32Interface.hpp': No such file or directory
Generating Code...
Build All failed.
Anyways, off to chase that down...
2024-02-06 09:29 PM - edited 2024-02-06 09:31 PM
I have made some progress at this add-on project with source code in various subdirectories and getting my CMakeLists.txt file set with the right commands. I am currently at a roadblock that I cannot resolve.
..\JHP_Audit\CMakeLists.txt
[problem area - line 24]
[complete file]
cmake_minimum_required (VERSION 3.16)
message (STATUS "CMake version >>> " ${CMAKE_VERSION})
include (Tools/CMakeCommon.cmake)
set (API_DEVKIT_DIR $ENV{AC_API_DEVKIT_DIR} CACHE PATH "API DevKit directory.")
set_property (GLOBAL PROPERTY USE_FOLDERS ON)
set (CMAKE_CONFIGURATION_TYPES Debug;Release;RelWithDebInfo)
set (AC_API_DEVKIT_DIR ${API_DEVKIT_DIR} CACHE PATH "API DevKit directory.")
set (AC_ADDON_NAME "JHP_Audit" CACHE STRING "AddOn Name")
set (AC_ADDON_LANGUAGE "INT" CACHE STRING "Add-On language code.")
project (${AC_ADDON_NAME} CXX)
add_subdirectory (Src)
DetectACVersion (${AC_API_DEVKIT_DIR} ACVersion)
add_library(AuditLib STATIC "")
target_include_directories (AuditLib PUBLIC
${AddOnSourcesFolderAbsolute}
${AC_API_DEVKIT_DIR}Support/Inc
${AC_API_DEVKIT_DIR}Support/Modules/GSUtils
${AC_API_DEVKIT_DIR}Support/Modules/GSRoot
)
set (AddOnFolder .)
SetGlobalCompilerDefinitions ()
GenerateAddOnProject (${ACVersion} ${AC_API_DEVKIT_DIR} ${AC_ADDON_NAME} ${AddOnFolder} ${AC_ADDON_LANGUAGE})
set_target_properties(${AC_ADDON_NAME} PROPERTIES LINKER_LANGUAGE CXX)
..\JHP_Audit\Src\CMakeLists.txt
[problem area - line 13]
[complete file]
add_subdirectory(Audits)
add_subdirectory(JHPCommon)
add_subdirectory(LiveAudit)
add_subdirectory(Report)
include_directories(
${AddOnSourcesFolderAbsolute}Audits
${AddOnSourcesFolderAbsolute}JHPCommon
${AddOnSourcesFolderAbsolute}LiveAudit
${AddOnSourcesFolderAbsolute}Report
)
add_executable (AuditLib_Src
${AddOnSourcesFolderAbsolute}JHP_Audit.cpp
${AddOnSourcesFolderAbsolute}Audits/Audits_Beams.cpp
${AddOnSourcesFolderAbsolute}Audits/Audits_Beams.h
${AddOnSourcesFolderAbsolute}Audits/Audits_Dimensions.cpp
${AddOnSourcesFolderAbsolute}Audits/Audits_Dimensions.h
${AddOnSourcesFolderAbsolute}Audits/Audits_Generic.cpp
${AddOnSourcesFolderAbsolute}Audits/Audits_Generic.h
${AddOnSourcesFolderAbsolute}Audits/Audits_Railings.cpp
${AddOnSourcesFolderAbsolute}Audits/Audits_Railings.h
${AddOnSourcesFolderAbsolute}Audits/Audits_Walls.cpp
${AddOnSourcesFolderAbsolute}Audits/Audits_Walls.h
${AddOnSourcesFolderAbsolute}Audits/Audits_Windows.cpp
${AddOnSourcesFolderAbsolute}Audits/Audits_Windows.h
${AddOnSourcesFolderAbsolute}JHPCommon/Format.cpp
${AddOnSourcesFolderAbsolute}JHPCommon/Format.h
${AddOnSourcesFolderAbsolute}JHPCommon/Math.cpp
${AddOnSourcesFolderAbsolute}JHPCommon/Math.h
${AddOnSourcesFolderAbsolute}JHPCommon/Utilities.cpp
${AddOnSourcesFolderAbsolute}JHPCommon/Utilities.h
${AddOnSourcesFolderAbsolute}LiveAudit/LiveAudit.cpp
${AddOnSourcesFolderAbsolute}LiveAudit/LiveAudit.h
${AddOnSourcesFolderAbsolute}LiveAudit/LiveAudit_Palette.cpp
${AddOnSourcesFolderAbsolute}LiveAudit/LiveAudit_Palette.hpp
${AddOnSourcesFolderAbsolute}Report/AuditReport.cpp
${AddOnSourcesFolderAbsolute}Report/AuditReport.h
)
The error message when saving the CMakeLists.txt edits:
[with the logical target names different - AuditLib and AuditLib_Src]
1> [CMake] CMake Error at G:\dev\v27\JHP_Audit\CMakeLists.txt:24 (add_library):
1> [CMake] No SOURCES given to target: AuditLib
1> [CMake]
1> [CMake]
1> [CMake] CMake Generate step failed. Build files cannot be regenerated correctly.
I believe this is because line 24 in the root CMakeLists file uses AuditLib as the logical name for the target and line 13 in the subfolder CMakeLists file uses AutoLib_Src as the logical name for the target.
[with the logical target names the same - AuditLib and AuditLib]
1> [CMake] CMake Error at G:\dev\v27\JHP_Audit\CMakeLists.txt:24 (add_library):
1> [CMake] add_library cannot create target "AuditLib" because another target with the
1> [CMake] same name already exists. The existing target is an executable created in
1> [CMake] source directory "G:/dev/v27/JHP_Audit/Src". See documentation for policy
1> [CMake] CMP0002 for more details.
This is because line 24 in the root CMakeLists file uses AuditLib as the logical name for the target and line 13 in the subfolder CMakeLists file uses AutoLib as the logical name for the target.
It appears the neither one of the options is correct.
Am I understanding this correctly?
Am I missing additional commands that allow one of these options to work?
Am I close to the correct way for doing this?
Has anyone ever used CMake to build a project with source files in multiple directories?
And finally - - Is anyone snow skiing at Lake Tahoe next week? I will gladly buy beer for a rousing discussion of CMake and subdirectories...
All the best - chris
2024-02-20 05:18 PM
My solution - -
Get rid of subdirectories that contain additional source files. All source files are in the single parent directory now and CMakeLists issues seem to have magically vanished.
Tahoe update - - 9" [23 cm] powder day last Thursday was EPIC! And the promise of beer for a rousing discussion of CMake and subdirectories... ...produced zero takers. Oh well.
Chris