I am sure I did something stupid but one of these things also appears to be platform specific. I don’t generally create cmake scripts for shared libraries from scratch, but am trying for a new project now.
Created an empty class to build into the Core library (multiple libraries naturally) to get the plumbing to work for generating the library and its Debian package. First make certain the toilet flushes, then . . .
On Ubuntu 24.04 with all updates applied and MX Linux with all updates applied the build dies in mostly the same way.
[1/4] Building CXX object src/core/CMakeFiles/BD_Core.dir/bd_object.cpp.o
FAILED: src/core/CMakeFiles/BD_Core.dir/bd_object.cpp.o
/usr/bin/c++ @src/core/CMakeFiles/BD_Core.dir/bd_object.cpp.o.rsp -MD -MT src/core/CMakeFiles/BD_Core.dir/bd_object.cpp.o -MF src/core/CMakeFiles/BD_Core.dir/bd_object.cpp.o.d -o src/core/CMakeFiles/BD_Core.dir/bd_object.cpp.o -c /home/developer/sf_projects/basisdoctrina/src/core/bd_object.cpp
c++: warning: LINK_FLAGS: linker input file unused because linking not done
c++: error: LINK_FLAGS: linker input file not found: No such file or directory
ninja: build stopped: subcommand failed.
The beautified .rsp for Ubuntu has
cat ../basisdoctrina_debian_build/src/core/CMakeFiles/BD_Core.dir/bd_object.cpp.o.rsp
-DBD_Core_EXPORTS
-DBD_PACKAGE_BUILD
-DBD_SHARED
-I/home/developer/sf_projects/basisdoctrina_debian_build/src/core
-I/home/developer/sf_projects/basisdoctrina/src/core
-I/usr/lib/x86_64-linux-gnu/glib-2.0/include
-I/usr/include/glib-2.0 -I/usr/lib/x86_64-linux-gnu/sigc++-2.0/include
-I/usr/include/sigc++-2.0
-I/usr/lib/x86_64-linux-gnu/glibmm-2.4/include
-I/usr/include/glibmm-2.4
-I/home/developer/sf_projects/basisdoctrina/src/core/include/core
-I/home/developer/sf_projects/basisdoctrina_debian_build/include -g -std=c++17 -fPIC LINK_FLAGS
Please note the difference at the end for MX Linux
$ cat ../basisdoctrina_debian_build/src/core/CMakeFiles/BD_Core.dir/bd_object.cpp.o.rsp
-DBD_Core_EXPORTS
-DBD_PACKAGE_BUILD
-DBD_SHARED
-I/home/developer/sf_projects/basisdoctrina_debian_build/src/core
-I/home/developer/sf_projects/basisdoctrina/src/core
-I/usr/lib/x86_64-linux-gnu/glib-2.0/include
-I/usr/include/glib-2.0
-I/usr/lib/x86_64-linux-gnu/sigc++-2.0/include
-I/usr/include/sigc++-2.0
-I/usr/lib/x86_64-linux-gnu/glibmm-2.4/include
-I/usr/include/glibmm-2.4
-I/home/developer/sf_projects/basisdoctrina/src/core/include/core
-I/home/developer/sf_projects/basisdoctrina_debian_build/include -g -fPIC LINK_FLAGS -std=c++17
That had me chasing a Red Herring that was swimming down a rabbit hole for over a day.
Only interesting part of the CMakeLists.txt from the project src dir is as follows
include(CPack)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_INCLUDE_DIRECTORIES_BEFORE ON)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_STANDARD 17)
if (CMAKE_SYSTEM_NAME MATCHES "Darwin")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-undefined,error")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-undefined,error")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,-undefined,error")
elseif (CMAKE_SYSTEM_NAME MATCHES "(OpenBSD|FreeBSD|NetBSD|DragonFly)")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined")
elseif (MSVC)
string (REGEX REPLACE "/W3" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}" )
string (REGEX REPLACE "/W3" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:/utf-8>")
else()
# Linux, Windows (MinGW)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--no-undefined")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--no-undefined")
set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} -Wl,--no-undefined")
if (CMAKE_SYSTEM_NAME MATCHES "Windows")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wa,-mbig-obj")
endif()
endif()
It’s not all that interesting. Rewrote this CMakeLists.txt that is in the core subdirectory of source many times. Obviously missing something the documentation simply hasn’t been able to explain to me.
list(APPEND CORE_INCLUDES
${CMAKE_BINARY_DIR}/include/bd_build_info.h
${CMAKE_SOURCE_DIR}/src/core/bd_object.h
${CMAKE_SOURCE_DIR}/src/3rdparty/BigInt/BigInt.hpp
)
list(APPEND CORE_SOURCES
${CMAKE_SOURCE_DIR}/src/core/bd_object.cpp
)
add_library(BD_Core SHARED ${CORE_SOURCES})
add_library(Bd::BD_Core ALIAS BD_Core)
set_target_properties(BD_Core PROPERTIES
VERSION ${BUILD_ABI}
SOVERSION ${BUILD_MAJOR}
OUTPUT_NAME BD_Core${BUILD_ABI}
)
target_include_directories(BD_Core
PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include/core>
$<INSTALL_INTERFACE:include/core>
${CMAKE_BINARY_DIR}/include
${ZLIB_INCLUDE_DIR}
${SDL3_INCLUDE_DIR}
)
# Raspberry Pi does not have built in atomic support
if (HAVE_LIBATOMIC)
target_link_libraries(BD_Core
PUBLIC
atomic
)
endif()
function_clean_string("${EXTRA_CORE_CXXFLAGS}" EXTRA_CORE_CXXFLAGS)
function_clean_string("${EXTRA_CORE_LDFLAGS}" EXTRA_CORE_LDFLAGS)
target_sources(BD_Core
PRIVATE
${CORE_INCLUDES}
${CORE_SOURCES}
)
set_target_properties(BD_Core
PROPERTIES
COMPILE_FLAGS ${EXTRA_CORE_CXXFLAGS}
LINK_FLAGS ${EXTRA_CORE_LDFLAGS}
CXX_STANDARD 17
CSS_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF
)
target_link_libraries(BD_Core
PRIVATE
${ZLIB_LIBRARIES}
${SDL3_LIBRARIES}
)
if(MSVC)
target_compile_options(BD_Core
PUBLIC
/bigobj
/DNOMINMAX
)
if (${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.13.0")
# ensure method pointers have a unique address
target_link_options(BD_Core
PUBLIC
/OPT:REF,NOICF
)
else()
message(FATAL_ERROR "CMake Version must be at least 3.13.0 for MSVC")
endif()
endif()
#
# If we get around to adding translations we will need to do something with
# the translation files at this time.
#
# Hopefully we will come up with something better than .qrc and rcc
#
get_target_property(OUT BD_Core LINK_LIBRARIES)
message(" *** ")
message(" *** ")
message(" *** ")
message("\tlibraries: ${OUT}")
message("\tEXTRA_CORE_LDFLAGS: ${EXTRA_CORE_LDFLAGS}")
message("\tEXTRA_CORE_CXXFLAGS: ${EXTRA_CORE_CXXFLAGS}")
message("\tZLIB_LIBRARIES: ${ZLIB_LIBRARIES}")
message("\tSDL3_LIBRARIES: ${SDL3_LIBRARIES}")
message("\tCMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
message("\tCMAKE_C_FLAGS: ${CMAKE_C_FLAGS}")
message("\tCMAKE_SHARED_LINKER_FLAGS: ${CMAKE_SHARED_LINKER_FLAGS}")
message("\tCMAKE_EXE_LINKER_FLAGS: ${CMAKE_EXE_LINKER_FLAGS}")
message(" *** ")
message(" *** ")
message(" *** ")
if (UNIX)
set(P_NAME "BD_Core")
set(P_INC_SUBDIR "Core")
set(P_CFLAGS "${EXTRA_CORE_CXXFLAGS}")
set(P_REQUIRES "")
configure_file(
${CMAKE_SOURCE_DIR}/cmake/pkgconfig.cmake
${CMAKE_BINARY_DIR}/pkgconfig/${P_NAME}.pc
@ONLY
)
install(
FILES ${CMAKE_BINARY_DIR}/pkgconfig/${P_NAME}.pc
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/pkgconfig
COMPONENT Devel
)
endif()
# multi-arch Debian has an extra director after /lib
# for 64-bit x86 is is x86_64-linux-gnu
# various ARM platforms will have other directories.
#
if (DEBIAN_FOUND)
install(
TARGETS BD_Core
EXPORT BdLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS}
LIBRARY DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
else()
install(
TARGETS BD_Core
EXPORT BdLibraryTargets ${INSTALL_TARGETS_DEFAULT_ARGS}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
)
endif()
install(FILES ${CMAKE_BINARY_DIR}/include/bd_config.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} )
Please note the big block of cmake debugger statements. They generate the following
***
***
***
libraries: /usr/lib/x86_64-linux-gnu/libz.so;SDL3::SDL3
EXTRA_CORE_LDFLAGS:
EXTRA_CORE_CXXFLAGS:
ZLIB_LIBRARIES: /usr/lib/x86_64-linux-gnu/libz.so
SDL3_LIBRARIES: SDL3::SDL3
CMAKE_CXX_FLAGS:
CMAKE_C_FLAGS:
CMAKE_SHARED_LINKER_FLAGS: -Wl,--no-undefined
CMAKE_EXE_LINKER_FLAGS: -Wl,--no-undefined
***
***
***
So, I have it declared as a shared library. There is exactly one module in it that does nothing. The target link libraries are correct for what this particular library will need . . . but . . .doesn’t create the library so the shell script can go on and create the Debian package.
What am I missing?
For anyone that wants the entire thing, you can clone it from here
debian-build-dependencies.sh will install everything needed, even build the SDL3 library from source and install
build-BasisDoctrina-deb.sh will kick of the build