codefrog
(Jonathan)
June 24, 2024, 1:53pm
1
I’m just run through Step 10 of the Tutorial, and am trying to use the GenerateExportHeader module.
However, when I build, I get the error:
fatal error: mathfunctions_export.h: No such file or directory
10 | #include "mathfunctions_export.h"
In MathFunctions/CMakeFiles.txt I’ve added:
include(GenerateExportHeader)
generate_export_header(MathFunctions)
I can see the generated file: ‘Step10_build/MathFunctions/mathfunctions_export.h’.
MathFunctions.h includes the new generated file.
What am I missing?
retif
June 24, 2024, 2:00pm
2
Probably missing target_include_directories() or linking to the library target?
I am not familiar with that project, and you haven’t provided what you have.
codefrog
(Jonathan)
June 24, 2024, 2:02pm
3
This is the link to Step 10 of the tutorial: Step 10
MathFunctions/CMakeLists.txt includes:
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
The source code is held at: tutorial archive
This is the contents of my Step10_build/MathFunctions folder
:
CMakeFiles cmake_install.cmake libSqrtLibrary.a Makefile MakeTable mathfunctions_export.h Table.h
The missing line is the following ??:
target_include_directories(MathFunctions PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
This should help:
# cmake-format: off
target_sources(
MathFunctions PUBLIC
FILE_SET HEADERS
BASE_DIRS ${PROJECT_BINARY_DIR}
FILES ${PROJECT_BINARY_DIR}/mathfunctions_export.h
)
# cmake-format: on
codefrog
(Jonathan)
June 24, 2024, 3:06pm
5
Hi, @ClausKlein Is that an alternative to my solution where I set the target_include_directories? Or should I be using ‘target_sources’ instead?
This is the modern way to set the include path and install public headers.
codefrog
(Jonathan)
June 24, 2024, 3:22pm
7
@ClausKlein I’ve updated my MathFunctions/CMakeLists.txt with your change.
Like so:
include(GenerateExportHeader)
add_library(MathFunctions MathFunctions.cxx )
generate_export_header(MathFunctions EXPORT_FILE_NAME
${PROJECT_BINARY_DIR}/exports/mathfunctions_export.h)
target_compile_definitions(MathFunctions PRIVATE "EXPORTING_MYMATH")
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
target_sources(
MathFunctions PUBLIC
FILE_SET HEADERS
BASE_DIRS ${PROJECT_BINARY_DIR}
FILES ${PROJECT_BINARY_DIR}/exports/mathfunctions_export.h
)
But still get the error message:
Step10/MathFunctions/MathFunctions.h:10:10: fatal error: mathfunctions_export.h: No such file or directory
10 | #include "mathfunctions_export.h"
| ^~~~~~~~~~~~~~~~~~~~~~~~
compilation terminated.
Clearly I’m still missing something obvious here
include(GenerateExportHeader)
generate_export_header(MathFunctions EXPORT_FILE_NAME
${CMAKE_CURRENT_BINARY_DIR}/exports/mathfunctions_export.h
)
# cmake-format: off
target_sources(
MathFunctions PUBLIC
FILE_SET HEADERS
BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
FILES ${CMAKE_CURRENT_BINARY_DIR}/exports/mathfunctions_export.h
${CMAKE_CURRENT_SOURCE_DIR}/MathFunctions.h
)
# cmake-format: on
The include path is set to CMAKE_CURRENT_BINARY_DIR
and CMAKE_CURRENT_SOURCE_DIR
.
And the “EXPORTING_MYMATH
” is not longer needed and wrong.
Do not forget to install it:
install(TARGETS ${installable_libs} DESTINATION lib FILE_SET HEADERS)
codefrog
(Jonathan)
June 24, 2024, 5:59pm
9
Thanks @ClausKlein , that works very well, and keeps the exported headers during build local to the library. It also installs perfectly. My final version (hopefully) is as follows:
include(GenerateExportHeader)
# add the library that runs
add_library(MathFunctions MathFunctions.cxx )
generate_export_header(MathFunctions EXPORT_FILE_NAME
${CMAKE_CURRENT_BINARY_DIR}/exports/mathfunctions_export.h)
# state that anybody linking to us needs to include the current source dir
# to find MathFunctions.h, while we don't.
target_include_directories(MathFunctions
INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
)
target_include_directories(MathFunctions PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/exports)
#BASE_DIRS ${PROJECT_BINARY_DIR}
target_sources(
MathFunctions PUBLIC
FILE_SET HEADERS
BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
FILES ${CMAKE_CURRENT_BINARY_DIR}/exports/mathfunctions_export.h
${CMAKE_CURRENT_SOURCE_DIR}/MathFunctions.h
)
# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
set(installable_libs MathFunctions tutorial_compiler_flags)
if(TARGET SqrtLibrary)
list(APPEND installable_libs SqrtLibrary)
endif()
install(TARGETS ${installable_libs} DESTINATION lib FILE_SET HEADERS)
# install include headers
install(FILES MathFunctions.h DESTINATION include)
However I assume there should not be any reason why I can’t change the build to use ‘USE_MYMATH’.
The calls to
should not be needed.
And the last install(FILES ...)
call is also not needed.
@ben.boeckel should we modernize the Tutorial?
2 Likes
codefrog
(Jonathan)
June 25, 2024, 11:02am
12
Thanks for all your help @ClausKlein !
I still seemed to need just one target_include_directories()
. It will not build otherwise.
Have removed the final install(FILES ...)
Installs OK!
This looks a lot tidier :
include(GenerateExportHeader)
# add the library that runs
add_library(MathFunctions MathFunctions.cxx )
generate_export_header(MathFunctions EXPORT_FILE_NAME
${CMAKE_CURRENT_BINARY_DIR}/exports/mathfunctions_export.h)
target_include_directories(MathFunctions PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/exports)
target_sources(
MathFunctions PUBLIC
FILE_SET HEADERS
BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
FILES ${CMAKE_CURRENT_BINARY_DIR}/exports/mathfunctions_export.h
${CMAKE_CURRENT_SOURCE_DIR}/MathFunctions.h
)
# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
set(installable_libs MathFunctions tutorial_compiler_flags)
if(TARGET SqrtLibrary)
list(APPEND installable_libs SqrtLibrary)
endif()
install(TARGETS ${installable_libs} DESTINATION lib FILE_SET HEADERS)
ClausKlein
(Claus Klein)
June 25, 2024, 11:31am
13
I would not use this exports subdirectory!
-- Install configuration: ""
-- Installing: /usr/local/lib/libMathFunctions.dylib
-- Installing: /usr/local/lib/MathFunctions.h
-- Installing: /usr/local/lib/exports/mathfunctions_export.h
-- Installing: /usr/local/lib/libSqrtLibrary.a
-- Installing: /usr/local/bin/Tutorial
-- Installing: /usr/local/include/TutorialConfig.h
bash-5.2$
If you do, you must also change your code:
#pragma once
#include <exports/mathfunctions_export.h>
namespace mathfunctions {
double MATHFUNCTIONS_EXPORT sqrt(double x);
}
This
target_include_directories(MathFunctions PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/exports)
helps you build your code, but does not help the user trying to use your installed files!
codefrog
(Jonathan)
June 26, 2024, 2:06pm
14
Thanks @ClausKlein that’s a very valid point. With just that final change I have:
include(GenerateExportHeader)
# add the library that runs
add_library(MathFunctions MathFunctions.cxx )
generate_export_header(MathFunctions EXPORT_FILE_NAME
${CMAKE_CURRENT_BINARY_DIR}/mathfunctions_export.h)
target_include_directories(MathFunctions PUBLIC ${CMAKE_CURRENT_BINARY_DIR})
target_sources(
MathFunctions PUBLIC
FILE_SET HEADERS
BASE_DIRS ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}
FILES ${CMAKE_CURRENT_BINARY_DIR}/mathfunctions_export.h
${CMAKE_CURRENT_SOURCE_DIR}/MathFunctions.h
)
# link MathFunctions to tutorial_compiler_flags
target_link_libraries(MathFunctions PUBLIC tutorial_compiler_flags)
# install libs
set(installable_libs MathFunctions tutorial_compiler_flags)
if(TARGET SqrtLibrary)
list(APPEND installable_libs SqrtLibrary)
endif()
install(TARGETS ${installable_libs} DESTINATION lib FILE_SET HEADERS)
This builds correctly. And when I install, I get:
-- Install configuration: ""
-- Installing: /usr/local/lib/libMathFunctions.so
-- Installing: /usr/local/lib/mathfunctions_export.h
-- Up-to-date: /usr/local/lib/MathFunctions.h
-- Installing: /usr/local/bin/Tutorial
-- Set non-toolchain portion of runtime path of "/usr/local/bin/Tutorial" to ""
-- Installing: /usr/local/include/TutorialConfig.h
Many thanks!