c++ccmakeautomoc

CMake with AUTOMOC is removing my implementations


I want to use CMake to build this QHttp project, I wrote a minimum set of CMakeLists.txt for build the basic-server example but is not linking.

I created an OBJECT library for the 3rdparty library http-parser linked with the qhttp project and then link with the example project. I've tried other configurations with ever the same problem but this is the more readable.

Maybe the files are in diferent locations from original project but the code is essentialy the same.

My CMakeLists.txt

3rdparty/CMakeLists.txt

cmake_minimum_required(VERSION 3.13)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

add_library(http-parser STATIC)

target_sources(http-parser
    PRIVATE
    http-parser/contrib/parsertrace.c
    http-parser/contrib/url_parser.c
    http-parser/http_parser.c
    PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/http-parser/include/http_parser.h
    )

target_include_directories(http-parser PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/http-parser/include)

Root CmakeLists.txt

cmake_minimum_required(VERSION 3.13)
project(qhttp VERSION 1.0.1 LANGUAGES CXX)

set(CMAKE_CXX_STANDARD 14)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)

set(CMAKE_VERBOSE_MAKEFILE ON)

find_package(Qt5 COMPONENTS Network Core REQUIRED)

add_subdirectory(3rdparty)

add_library(${PROJECT_NAME} SHARED)
target_sources(${PROJECT_NAME}
    PRIVATE
    include/qhttpabstracts.hpp
    include/qhttpserverconnection.hpp
    include/qhttpserverrequest.hpp
    include/qhttpserverresponse.hpp
    include/qhttpserver.hpp
    src/qsslserver.h
    src/qhttpabstracts.cpp
    src/qhttpserverconnection.cpp
    src/qhttpserverrequest.cpp
    src/qhttpserverresponse.cpp
    src/qhttpserver.cpp
    src/qsslserver.cpp
    src/private/httpparser.hxx)

target_link_libraries(qhttp
    PUBLIC
    Qt5::Network Qt5::Core
    http-parser)

target_include_directories(${PROJECT_NAME}
    PUBLIC
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    $<INSTALL_INTERFACE:include/qhttp>
    PRIVATE
    ${CMAKE_CURRENT_SOURCE_DIR}/src)

add_subdirectory(example)

The basic-server

cmake_minimum_required(VERSION 3.13)

add_executable(basic-server basic-server/main.cpp)
target_link_libraries(basic-server qhttp)

The error

For any reason it isn't linking well and the compiler send me the next message:

/usr/bin/cmake -E cmake_link_script CMakeFiles/basic-server.dir/link.txt --verbose=1
/usr/bin/g++     CMakeFiles/basic-server.dir/basic-server/main.cpp.o CMakeFiles/basic-server.dir/basic-server_autogen/mocs_compilation.cpp.o  -o basic-server -Wl,-rpath,[...]/build-qhttp-Desktop-Default ../libqhttp.so.1.0.1 /usr/lib/x86_64-linux-gnu/libQt5Network.so.5.11.3 /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.11.3 
/usr/bin/ld: ../libqhttp.so.1.0.1: undefined reference to `http_method_str'
/usr/bin/ld: ../libqhttp.so.1.0.1: undefined reference to `http_parser_init'
/usr/bin/ld: ../libqhttp.so.1.0.1: undefined reference to `http_parser_execute'
collect2: error: ld returned 1 exit status

Edit: More Info

The reason that I get undefined references I think is because there are no symbols in the built library as you can see.

nm libhttp-parser.a 

mocs_compilation.cpp.o:

The code is correct because I built it with QMake. It has the correct:

#ifdef __cplusplus
extern "C" {
#endif

But CMake is not generating the building right.

In the other hand, if I build only the http-parser with its CMakeLists.txt I get:

nm libhttp-parser.a  

parsertrace.c.o:
[...]
                 U _GLOBAL_OFFSET_TABLE_
0000000000005953 T http_body_is_final
000000000000515c T http_errno_description
0000000000005115 T http_errno_name
0000000000004f0a T http_message_needs_eof
0000000000005021 T http_method_str
00000000000053fa t http_parse_host
00000000000051a3 t http_parse_host_char
000000000000037e T http_parser_execute
000000000000504f T http_parser_init
0000000000005679 T http_parser_parse_url
00000000000058dc T http_parser_pause
00000000000050f0 T http_parser_settings_init
0000000000005654 T http_parser_url_init
0000000000005973 T http_parser_version
0000000000004fa7 T http_should_keep_alive
0000000000000120 d http_strerror_tab
[...]

There are the symbols. What is the problem with my CMake top projects? Is the MOC throwing my code to trash?


Solution

  • Finally I've found the problem. The problem is that AUTOMOC hide the real error that is unable to determine linker language with C++.

    Easily resolved with:

    project(qhttp VERSION 1.0.1 LANGUAGES C CXX)
    

    or

    project(qhttp VERSION 1.0.1)