Project

General

Profile

Need CMakeLists.txt that I can use to port project from OSX to Linux (multiple "undefined reference" errors)

Added by Mark Travis almost 2 years ago

TL:DR -> Anyone have a good stand-alone CMakeLists.txt for Ubuntu???

I'm trying to get my project up and running on Linux so that I can use better debugging tools such as Valgrind.

This project runs and compiles perfectly using XCode 13/Monterey/M1 Max.

I set up another machine with Ubuntu 20 (long-term stable version) and installed Wt according to the documentation. Wt installs and I can successfully run the hangman.wt example.

It's been years since I played around with Linux. It's almost identical to OSX under the covers. (Work with me here!)

I do not know CMAKE. I'm a hack at best. I can modify an existing one with options, similar to what is done when you install Wt.

I know I'm doing something stupid. I just don't know enough to know.

My CMakeLists.txt results in all of my binaries being compiled, but the link stage blows up in grand fashion with pages of messages such as "....undefined reference to 'Wt::Dbo::ptr::ptr()'"

so, ** it's not finding any of the Wt libraries** .

Here's my latest attempt at a CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
project(thisproject)

INCLUDE(CheckFunctionExists)
INCLUDE(CheckLibraryExists)

include_directories(/home/mark/Development/myproject/DatabaseFunctions)
include_directories(/home/mark/Development/myproject/NetworkClasses)
include_directories(/home/mark/Development/myproject/WebFrontEnd)
include_directories(/home/mark/Development/myproject/StatisticalFunctions)
include_directories(/usr/local/include/wt/src)

IF(NOT CMAKE_CXX_STANDARD)
SET(CMAKE_CXX_STANDARD 17)
ENDIF(NOT CMAKE_CXX_STANDARD)
SET(CMAKE_CXX_STANDARD_REQUIRED ON)
SET(CMAKE_CXX_EXTENSIONS OFF)

SET(BUILD_SHARED_LIBS ${SHARED_LIBS})

OPTION(DEBUG "Support for debugging, must be enabled also in wt_config.xml" ON)

IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE Debug CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)

IF(DEBUG)
SET(WT_DEBUG_ENABLED 1)
ELSE(DEBUG)
SET(WT_DEBUG_ENABLED 0)
ENDIF(DEBUG)

include (CheckSymbolExists)

SET(MYPROJECT_PROJECT_SOURCE
main.cpp
housekeeping.cpp
DatabaseFunctions/ProjectModel.cpp
DatabaseFunctions/Token.C
StatisticalFunctions/VectorDotProduct.cpp
WebFrontEnd/ChartsWidget.cpp
WebFrontEnd/CsvUtil.Cpp
NetworkClasses/NetworkFunctions.cpp
WebFrontEnd/ChartConfig.Cpp
DatabaseFunctions/MySession.Cpp
DatabaseFunctions/User.Cpp
WebFrontEnd/Splash.cpp
WebFrontEnd/AuthenticatedLeftMenu.cpp
WebFrontEnd/PanelList.C
WebFrontEnd/ControlWidget.cpp
WebFrontEnd/DataLoadWidget.cpp
)

find_library(LIBWT libwtd.so)

find_library(LIBWTDBO libwtdbod.so)

find_library(LIBWTDBOSQLITE3 libwtdbosqlite3d.so)

find_library(LIBWTHTTP libwthttpd.so)

SET(MYPROJECT_PROJECT_TARGET myproject.wt)

ADD_EXECUTABLE(${MYPROJECT_PROJECT_TARGET} ${MYPROJECT_PROJECT_SOURCE})

TARGET_LINK_LIBRARIES(${MYPROJECT_PROJECT_TARGET} INTERFACE "${LIBWTDBO}" INTERFACE "${LIBWTDBOSQLITE3}" INTERFACE "${LIBWT}" INTERFACE "${LIBWTHTTP}")


Replies (8)

RE: Need CMakeLists.txt that I can use to port project from OSX to Linux (multiple "undefined reference" errors) - Added by Christian Meyer almost 2 years ago

Hey

Not Entirely sure if that is your problem, but:

If you installed wt, the Header files are installed as well

You are inluding
include_directories(/usr/local/include/wt/src)
while I do
INCLUDE_DIRECTORIES(/usr/local/include/Wt)

So it is the Capitalisation of the path AND there is no src folder ...

Really hope theres not something else =D

Good Luck!
Christian

RE: Need CMakeLists.txt that I can use to port project from OSX to Linux (multiple "undefined reference" errors) - Added by Mark Travis almost 2 years ago

It's finding the header files. The problem is it can't match the symbols in the linker. It's not finding the shared objects to link with.

RE: Need CMakeLists.txt that I can use to port project from OSX to Linux (multiple "undefined reference" errors) - Added by Christian Meyer almost 2 years ago

Try leaving out the file extensions ...
And remove the lib from the name

I set the Libs like this:

SET(WT_DBO_CONNECTOR
  wtdbo
  wtdbopostgres
  wtdbosqlite3
  wtdbomysql
)

And then

ADD_EXECUTABLE(WtApplication.wt main.cpp)

SET( WT_PROJECT_SOURCE
  defines.h
  Application.h
  Application.cpp
  ConnectionPool.h
  ConnectionPool.cpp
)

target_sources(WtApplication.wt PRIVATE
  ${WT_PROJECT_SOURCE}
)

SET(BOOST_LIBS
  boost_system
  boost_thread
  boost_filesystem
  boost_program_options
)

TARGET_LINK_LIBRARIES(
  WtApplication.wt
  wt
  wthttp
  ${WT_DBO_CONNECTOR}
  ${BOOST_LIBS}
)

and depending of whether you link as shared or static, it uses the correkt extension... if you have built both

I do not have experience with the INTERFACE keyword in cmake ... I also only learn what I need :)

RE: Need CMakeLists.txt that I can use to port project from OSX to Linux (multiple "undefined reference" errors) - Added by Mark Travis almost 2 years ago

I made the changes suggested and learned a lot more about the inner workings of Cmake, and i can see now that cmake finds the libraries.

Here is the latest output. I copied the linker command after it specifies all of the objects in my library starting with the ending where it specifies the libraries to link to....

-L/usr/local/lib -Wl,-rpath,/usr/local/lib /usr/local/lib/libwtdbod.so /usr/local/lib/libwtdbosqlite3d.so /usr/local/lib/libwthttpd.so /usr/local/lib/libwtd.so
/usr/bin/ld: CMakeFiles/myproject.wt.dir/DatabaseFunctions/Token.C.o: in function Token::Token()':
/home/mark/Development/myproject/DatabaseFunctions/Token.C:14: undefined reference to
Wt::Dbo::ptr::ptr()'
/usr/bin/ld: /home/mark/Development/myproject/DatabaseFunctions/Token.C:14: undefined reference to Wt::Dbo::ptr<User>::~ptr()'
/usr/bin/ld: CMakeFiles/myproject.wt.dir/DatabaseFunctions/Token.C.o: in function
Token::Token(std::__cxx11::basic_string, std::allocator > const&, Wt::WDateTime const&)':
/home/mark/Development/myproject/DatabaseFunctions/Token.C:19: undefined reference to Wt::Dbo::ptr<User>::ptr()'
/usr/bin/ld: /home/mark/Development/myproject/DatabaseFunctions/Token.C:19: undefined reference to
Wt::Dbo::ptr::~ptr()'

and it just goes on for pages and pages of "undefined reference" errors.

libwtd.so for instance, is a symlink. Should it point to libwtd.4.7.0.so instead???

RE: Need CMakeLists.txt that I can use to port project from OSX to Linux (multiple "undefined reference" errors) - Added by Mark Travis almost 2 years ago

In playing around with this a bit more, I've come to realize this is a problem linking with a Dbo library.

If I leave out all of the libraries, I get pages and pages of "undefined reference" errors from all areas of Wt. If I put in the 4 main libraries (Wt, Wthttp, Wtdbo, Wtdbosqlite3) then I only get the "undefined reference" errors on Wt::Dbo::ptr and Wt::Dbo::Session and a few other Wt::Dbo objects. About a page total.

I'm linking to the exact same libraries in XCode/macOS and it works perfectly. As mentioned before, I can run the Wt examples, such as Hangman (uses Dbo) and it works perfectly.

This has burned 30 hours this week. At least once I have a good WMakeLists.txt file, I can go multi-platform, which is the eventual direction anyway, so it's not a complete waste of time.

RE: Need CMakeLists.txt that I can use to port project from OSX to Linux (multiple "undefined reference" errors) - Added by Roel Standaert almost 2 years ago

The way you're using CMake is kind of old fashioned. I would recommend that you use find_package for Wt.

Here's a minimal example of a CMakeLists.txt using Wt and Wt::Dbo:

cmake_minimum_required(VERSION 3.16...3.23)
project(hellowt LANGUAGES CXX)

find_package(Wt REQUIRED COMPONENTS Wt HTTP Dbo DboSqlite3)

add_executable(hello.wt hello.cpp)
target_link_libraries(hello.wt PRIVATE Wt::Wt Wt::HTTP Wt::Dbo Wt::DboSqlite3)

If Wt is installed in a non-standard location, you can use -DWt_DIR=/path/to/lib/cmake/wt when configuring.

RE: Need CMakeLists.txt that I can use to port project from OSX to Linux (multiple "undefined reference" errors) - Added by Mark Travis almost 2 years ago

Roel, thanks! Actually, I spent some time really digging in to CMAKE and I now understand how find_package works. Here is my current CMakeLists.txt:

#########################################################

CMAKE_MINIMUM_REQUIRED(VERSION 3.2)

SET(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE true)

PROJECT(myproject)

IF(NOT MULTI_THREADED)
OPTION(MULTI_THREADED "Build multi-threaded httpd deamon (if possible)" ON)
ENDIF(NOT MULTI_THREADED)

SET(LIB_INSTALL_DIR "lib" CACHE STRING
"Name for library directory within ${CMAKE_INSTALL_PREFIX}")

SET(CMAKE_INSTALL_DIR "${LIB_INSTALL_DIR}/cmake" CACHE STRING
"Name for CMake package configuration directory within ${CMAKE_INSTALL_PREFIX}")

OPTION(DEBUG "Support for debugging, must be enabled also in wt_config.xml" ON)

MARK_AS_ADVANCED( CONFIGDIR )

include (CheckSymbolExists)

SET(ZLIB_PREFIX ${USERLIB_PREFIX} CACHE PATH
"Installation prefix of zlib library (overrides USERLIB_PREFIX)")

set(ZLIB_ROOT ${ZLIB_PREFIX})
find_package(ZLIB)

INCLUDE(CheckFunctionExists)
INCLUDE(CheckLibraryExists)

INCLUDE_DIRECTORIES(
${CMAKE_CURRENT_SOURCE_DIR}/DatabaseFunctions
${CMAKE_CURRENT_SOURCE_DIR}/NetworkClasses
${CMAKE_CURRENT_SOURCE_DIR}/WebFrontEnd
${CMAKE_CURRENT_SOURCE_DIR}/StatisticalFunctions
/usr/local/include
)
LINK_DIRECTORIES(/usr/local/lib)

SET(BUILD_SHARED_LIBS ${SHARED_LIBS})

OPTION(DEBUG "Support for debugging, must be enabled also in wt_config.xml" ON)

IF(NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE Debug CACHE STRING
"Choose the type of build, options are: None Debug Release RelWithDebInfo MinSizeRel."
FORCE)
ENDIF(NOT CMAKE_BUILD_TYPE)

#OPTION(CMAKE_CXX_FLAGS_DEBUG -g -O0)
#OPTION(CMAKE_CXX_STANDARD_REQUIRED ON)
#OPTION(CMAKE_EXPORT_COMPILE_COMMANDS ON)
#OPTION(CMAKE_VERBOSE_MAKEFILE ON)
#OPTION(CMAKE_CXX_EXTENSIONS OFF)
#OPTION(CMAKE_CXX_STANDARD 17)
#OPTION(CMAKE_CXX_FLAGS -fsanitize=address)

IF(DEBUG)
SET(WT_DEBUG_ENABLED 1)
ELSE(DEBUG)
SET(WT_DEBUG_ENABLED 0)
ENDIF(DEBUG)

INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})

SET(MYPROJECT_PROJECT_SOURCE
main.cpp
housekeeping.cpp
DatabaseFunctions/ProjectModel.cpp
NetworkClasses/NetworkClasses.cpp
WebFrontEnd/AuthenticatedContent.cpp
DatabaseFunctions/Token.C
WebFrontEnd/AROIStackController.cpp
StatisticalFunctions/VectorDotProduct.cpp
WebFrontEnd/AuthenticatedNavBar.cpp
WebFrontEnd/NonAuthenticatedController.cpp
NetworkClasses/TimeSeriesFunctions.cpp
WebFrontEnd/ChartsWidget.cpp
WebFrontEnd/CsvUtil.Cpp
WebFrontEnd/ChartConfig.Cpp
DatabaseFunctions/AROISession.Cpp
DatabaseFunctions/User.Cpp
WebFrontEnd/AuthenticatedController.cpp
WebFrontEnd/Splash.cpp
WebFrontEnd/ApplicationController.cpp
WebFrontEnd/AuthenticatedLeftMenu.cpp
WebFrontEnd/PanelList.C
WebFrontEnd/ControlWidget.cpp
WebFrontEnd/DataLoadWidget.cpp
)

find_package(Wt CONFIG REQUIRED COMPONENTS Wt HTTP Dbo DboSqlite3)
message(STATUS "Wt package was found: ${Wt_FOUND}")
if(NOT Wt_FOUND)
message(FATAL_ERROR "couldn't find Wt package")
endif(NOT Wt_FOUND)
include_directories(${Wt_INCLUDE_DIRS})

ADD_EXECUTABLE(myproject.wt ${MYPROJECT_PROJECT_SOURCE})

TARGET_LINK_LIBRARIES(myproject.wt Wt::Wt Wt::HTTP Wt::Dbo Wt::DboSqlite3)

##########################

I'll add the LANGUAGES CXX
Is PRIVATE necessary in the target_link_libraries?

The linker is still complaining, mostly about undefined references to Wt::Dbo::ptr::ptr() Wt::Dbo::ptr::obj() and a few other Wt::Dbo instances.
Perhaps there is a template function that is getting mangled somewhere in the Wt::Dbo areas?

RE: Need CMakeLists.txt that I can use to port project from OSX to Linux (multiple "undefined reference" errors) - Added by Mark Travis almost 2 years ago

To anyone following this....

You are not going to believe what it was....

After laboriously going through everything pixel by pixel, I finally realized out of the 61 source files, that the linker was complaining about symbols in three files.

Those three files were in the CMakeLists.txt file! Everything matched from the filesystem to the CMakeLists.txt file letter for letter.

The only thing I could find "out of the ordinary" was three of the files had an uppercase "C" in the file extention. ie. somefile.Cpp
The CMakeLists.txt file also had the listing somefile.Cpp. Like I said, letter for letter the same.

I changed the name in the file system to lowercase cpp and updated CMakeLists.txt with the lowercase cpp AND THE D@#M THING COMPILED AND LINKED!

Freaking Linux....

    (1-8/8)