[CMake] Problem with creating shared library
Damir Porobic
damir_porobic at live.com
Sun Aug 19 09:16:40 EDT 2018
Thanks Sebastián for providing those links!
I've followed the second link that you've provided but somehow I'm still running into issue.
I've changed the directory structure to this:
- kImageAnnotator
- cmake
- kImageAnnotator-config.cmake.in
- example
- main.cpp
- CMakeLists.txt
- include
- kImageAnnotator
- KImageAnnotator.h // the main api header
- src
- KImageAnnotator.cpp
- "And all other .cpp and .h files"
- CMakeLists.txt
- CMakeLists.txt
src/CMakeList.txt looks like this:
add_library(kImageAnnotator ${kimageannotator_SRCS} ${CMAKE_SOURCE_DIR}/include/kImageAnnotator/KImageAnnotator.h)
add_library(kImageAnnotator::kImageAnnotator ALIAS kImageAnnotator)
option(BUILD_SHARED_LIBS "Build shared library" ON)
include(GenerateExportHeader)
generate_export_header(kImageAnnotator
EXPORT_MACRO_NAME KIMAGEANNOTATOR_API
EXPORT_FILE_NAME ${CMAKE_BINARY_DIR}/include/KImageAnnotator.h
)
target_include_directories(kImageAnnotator
PUBLIC
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/include>
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>
$<INSTALL_INTERFACE:include>
PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}
)
set_target_properties(kImageAnnotator PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
)
find_package(Qt5 ${QT_MIN_VERSION} REQUIRED Widgets)
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS CoreAddons I18n WidgetsAddons)
target_link_libraries(kImageAnnotator Qt5::Widgets KF5::CoreAddons KF5::I18n KF5::WidgetsAddons)
include(GNUInstallDirs)
install(TARGETS kImageAnnotator
EXPORT kImageAnnotator-targets
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
INCLUDES DESTINATION ${LIBLEGACY_INCLUDE_DIRS}
)
install(DIRECTORY ${CMAKE_SOURCE_DIR}/include/kImageAnnotator
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(EXPORT kImageAnnotator-targets
FILE kImageAnnotator-targets.cmake
NAMESPACE kImageAnnotator::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/kImageAnnotator
)
include(CMakePackageConfigHelpers)
configure_package_config_file(
${CMAKE_SOURCE_DIR}/cmake/kImageAnnotator-config.cmake.in
${CMAKE_BINARY_DIR}/cmake/kImageAnnotator-config.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/kImageAnnotator
)
write_basic_package_version_file(
${CMAKE_BINARY_DIR}/cmake/kImageAnnotator-config-version.cmake
VERSION ${PROJECT_VERSION}
COMPATIBILITY AnyNewerVersion
)
install(FILES
${CMAKE_BINARY_DIR}/cmake/kImageAnnotator-config.cmake
${CMAKE_BINARY_DIR}/cmake/kImageAnnotator-config-version.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/kImageAnnotator
)
export(EXPORT kImageAnnotator-targets
FILE ${CMAKE_BINARY_DIR}/cmake/kImageAnnotator-targets.cmake
NAMESPACE kImageAnnotator::
)
kImageAnnotator-config.cmake.in looks like this:
include(CMakeFindDependencyMacro)
@PACKAGE_INIT@
# find_dependency(Threads)
find_package(Qt5 ${QT_MIN_VERSION} REQUIRED Widgets)
find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS CoreAddons I18n WidgetsAddons)
if(NOT TARGET kImageAnnotator::kImageAnnotator)
include("${CMAKE_CURRENT_LIST_DIR}/kImageAnnotator-targets.cmake")
endif()
example/CMakeLists.txt looks like this:
add_executable(kImageAnnotator-example ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
target_link_libraries(kImageAnnotator-example PRIVATE kImageAnnotator::kImageAnnotator)
And example/main.cpp looks like this:
#include <QApplication>
#include <kImageAnnotator/KImageAnnotator.h>
int main(int argc, char **argv)
{
QApplication app(argc, argv);
QPixmap pixmap(QSize(500, 500));
pixmap.fill(QColor(Qt::darkGreen));
auto kImageAnnotator = new KImageAnnotator(pixmap);
kImageAnnotator->show();
return app.exec();
}
Still I'm getting following error when trying to build kImageAnnotator-example:
Scanning dependencies of target kImageAnnotator-example
[ 98%] Building CXX object example/CMakeFiles/kImageAnnotator-example.dir/main.cpp.o
[ 98%] Building CXX object example/CMakeFiles/kImageAnnotator-example.dir/kImageAnnotator-example_autogen/mocs_compilation.cpp.o
[100%] Linking CXX executable kImageAnnotator-example
CMakeFiles/kImageAnnotator-example.dir/main.cpp.o: In function `main':
/home/dporobic/projects/kImageAnnotator/example/main.cpp:29: undefined reference to `KImageAnnotator::KImageAnnotator(QPixmap const&)'
collect2: error: ld returned 1 exit status
example/CMakeFiles/kImageAnnotator-example.dir/build.make:98: recipe for target 'example/kImageAnnotator-example' failed
Any idea what I'm doing wrong? It looks like the same issue that I was having earlier.
________________________________
From: Sebastián Mancilla <smancill at jlab.org>
Sent: Wednesday, August 15, 2018 21:48
To: damir_porobic at live.com
Cc: cmake at cmake.org
Subject: Re: [CMake] Problem with creating shared library
You are mixing the config file and the targets file.
The config file is a template that you normally put in cmake/FooConfig.cmake.in<http://FooConfig.cmake.in>
You copy the template into the binary dir:
include(CMakePackageConfigHelpers)
set(INSTALL_CONFIGDIR lib/cmake/Foo)
configure_package_config_file(
"${CMAKE_CURRENT_LIST_DIR}/cmake/FooConfig.cmake.in<http://FooConfig.cmake.in>"
"${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake"
INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
)
It is a good idea to create a version file:
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
And then install both:
install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake"
DESTINATION ${INSTALL_CONFIGDIR}
COMPONENT Devel
)
For the targets is a different file. When you install the library you should use
install(TARGETS Foo EXPORT FooTargets ...)
And then export and install the targets:
# Into the build tree
export(EXPORT FooTargets
FILE "${CMAKE_CURRENT_BINARY_DIR}/FooTargets.cmake"
NAMESPACE Foo::
)
# Into PREFIX
install(EXPORT FooTargets
FILE FooTargets.cmake
NAMESPACE Foo::
DESTINATION ${INSTALL_CONFIGDIR}
COMPONENT Devel
)
Finally, your template FooConfig.cmake.in<http://FooConfig.cmake.in> should look like this:
include(CMakeFindDependencyMacro)
@PACKAGE_INIT@
# list your required dependencies here
find_dependency(Threads)
if(NOT TARGET Foo::Foo)
include("${CMAKE_CURRENT_LIST_DIR}/FooTargets.cmake")
endif()
All this is pretty much the same for any project. Here are the best links explaining it:
https://pabloariasal.github.io/2018/02/19/its-time-to-do-cmake-right/
http://unclejimbo.github.io/2018/06/08/Modern-CMake-for-Library-Developers/
El mié., 15 de ago. de 2018 a la(s) 05:32, Damir Porobic (damir_porobic at live.com<mailto:damir_porobic at live.com>) escribió:
Hi Folks,
I'm trying to write a shared library and run into an issue where I can't find any clues to where the problem is.
I have a project with following structure:
src/
dir1/
file1.h
file1.cpp
dir2/
file2.h
file2.cpp
Now I have this CMakeList:
cmake_minimum_required(VERSION 3.5)
project(kImageAnnotator VERSION 0.0.1 LANGUAGES CXX)
...
add_library(${PROJECT_NAME} SHARED ${kimageannotator_SRCS})
target_link_libraries(${PROJECT_NAME} Qt5::Widgets KF5::CoreAddons KF5::I18n KF5::WidgetsAddons)
target_include_directories(${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> $<INSTALL_INTERFACE:include>)
set_target_properties(${PROJECT_NAME} PROPERTIES VERSION ${PROJECT_VERSION} SOVERSION 1)
set(kimageannotator_CONFIG ${PROJECT_NAME}Config)
install(TARGETS ${PROJECT_NAME} EXPORT ${kimageannotator_CONFIG}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
install(EXPORT ${kimageannotator_CONFIG} DESTINATION share/${kimageannotator_CONFIG}/cmake)
export(TARGETS ${PROJECT_NAME} FILE ${kimageannotator_CONFIG}.cmake)
In another test project, I add the library like this:
...
find_package(kImageAnnotator REQUIRED)
add_executable(testApp main.cpp)
target_link_libraries(testApp Qt5::Widgets kImageAnnotator)
Now when I try to build my test project, I get this:
dporobic at linux ~/projects/testApp/build
$ cmake .. && make
-- Could not set up the appstream test. appstreamcli is missing.
-- Configuring done
-- Generating done
-- Build files have been written to: /home/dporobic/projects/testApp/build
[ 25%] Automatic moc for target testApp
[ 25%] Built target testApp_automoc
Scanning dependencies of target testApp
[ 50%] Building CXX object CMakeFiles/testApp.dir/main.cpp.o
[ 75%] Building CXX object CMakeFiles/testApp.dir/testApp_automoc.cpp.o
[100%] Linking CXX executable testApp
CMakeFiles/testApp.dir/main.cpp.o: In function `main':
main.cpp:(.text+0x8e): undefined reference to `KImageAnnotator::KImageAnnotator(QPixmap const&)'
collect2: error: ld returned 1 exit status
CMakeFiles/testApp.dir/build.make:120: recipe for target 'testApp' failed
make[2]: *** [testApp] Error 1
CMakeFiles/Makefile2:67: recipe for target 'CMakeFiles/testApp.dir/all' failed
make[1]: *** [CMakeFiles/testApp.dir/all] Error 2
Makefile:94: recipe for target 'all' failed
make: *** [all] Error 2
Any idea how I could/should troubleshoot such issue?
Thanks in advance!
Regards,
Damir
--
Powered by www.kitware.com<http://www.kitware.com>
Please keep messages on-topic and check the CMake FAQ at: https://urldefense.proofpoint.com/v2/url?u=http-3A__www.cmake.org_Wiki_CMake-5FFAQ&d=DwICAg&c=lz9TcOasaINaaC3U7FbMev2lsutwpI4--09aP8Lu18s&r=8hmSv9ww5s9qu3iT8h5WMi8-YcKXaJvelxT3fMih7S4&m=1H4kXxGuNG-DAo1qM-u8bdF6AKKHkJoiCuqwZ4QLvtY&s=JJ5RqPyjdlGGc3fT-5nQQM-JcJzwjBZU6ciOQlmEJVs&e=
Kitware offers various services to support the CMake community. For more information on each offering, please visit:
CMake Support: https://urldefense.proofpoint.com/v2/url?u=http-3A__cmake.org_cmake_help_support.html&d=DwICAg&c=lz9TcOasaINaaC3U7FbMev2lsutwpI4--09aP8Lu18s&r=8hmSv9ww5s9qu3iT8h5WMi8-YcKXaJvelxT3fMih7S4&m=1H4kXxGuNG-DAo1qM-u8bdF6AKKHkJoiCuqwZ4QLvtY&s=vUHQvc_7Ovi_5BDjy3JYFOIvTmihTSFOQNndNSpMOnA&e=
CMake Consulting: https://urldefense.proofpoint.com/v2/url?u=http-3A__cmake.org_cmake_help_consulting.html&d=DwICAg&c=lz9TcOasaINaaC3U7FbMev2lsutwpI4--09aP8Lu18s&r=8hmSv9ww5s9qu3iT8h5WMi8-YcKXaJvelxT3fMih7S4&m=1H4kXxGuNG-DAo1qM-u8bdF6AKKHkJoiCuqwZ4QLvtY&s=91AJA3BxTfHAvsi0mAzkszAyUUmE2xfwbLgN_fYvFO4&e=
CMake Training Courses: https://urldefense.proofpoint.com/v2/url?u=http-3A__cmake.org_cmake_help_training.html&d=DwICAg&c=lz9TcOasaINaaC3U7FbMev2lsutwpI4--09aP8Lu18s&r=8hmSv9ww5s9qu3iT8h5WMi8-YcKXaJvelxT3fMih7S4&m=1H4kXxGuNG-DAo1qM-u8bdF6AKKHkJoiCuqwZ4QLvtY&s=isQW6paMIqhUFaejOZ4qfUiSVwNiR1yxoQn4J91yb8o&e=
Visit other Kitware open-source projects at https://urldefense.proofpoint.com/v2/url?u=http-3A__www.kitware.com_opensource_opensource.html&d=DwICAg&c=lz9TcOasaINaaC3U7FbMev2lsutwpI4--09aP8Lu18s&r=8hmSv9ww5s9qu3iT8h5WMi8-YcKXaJvelxT3fMih7S4&m=1H4kXxGuNG-DAo1qM-u8bdF6AKKHkJoiCuqwZ4QLvtY&s=ose8YVW10s6tWkujUCq162vyyipCdlw-MW93qUlqdGk&e=
Follow this link to subscribe/unsubscribe:
https://urldefense.proofpoint.com/v2/url?u=https-3A__cmake.org_mailman_listinfo_cmake&d=DwICAg&c=lz9TcOasaINaaC3U7FbMev2lsutwpI4--09aP8Lu18s&r=8hmSv9ww5s9qu3iT8h5WMi8-YcKXaJvelxT3fMih7S4&m=1H4kXxGuNG-DAo1qM-u8bdF6AKKHkJoiCuqwZ4QLvtY&s=KftR51q4EGgNERicS2QyHvzlrNaqb11IUwwbz1YTjVU&e=
--
Sebastian Mancilla Matta
CCTVal, UTFSM
Valparaíso, Chile
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20180819/b58691c1/attachment-0001.html>
More information about the CMake
mailing list