mercredi 27 avril 2022

CMake add_executable() failing to make executable and 3rd party library failing to untar

Problem Background

I am trying to incorporate UnitTest++ into my linux-based C++17 project template. I have done this on windows pretty easily, but I am running into major issues on linux for some reason.

I used Cmake 3.21 on Windows and I am using CMake 3.17.5 on Linux.

I downloaded the UnitTest++ source code from the UnitTest++ Github. and proceeded to throw the tar.gz into my 3rdParty folder in my ProjectTemplate. I have had major trouble getting it to build. So I have stripped out everything except for the one 3rd party library I added and the things that folder affects. So at this point all the main() functions are very simple. I am just expecting to see executables that do nothing.

Problem Points

  • The main executable gets made, but the unit testing executable (testExecutable) does not get made.
  • The build fully finishes with no errors even though an executable failed to be made.
  • The UnitTest++ 3rd party library fails to untar with no errors output.

I have included the actual contents of my cmake and the build output.

Why is the testExecutable not getting made? More importantly, why is my UnitTest++ failing to untar?

Directory Structure

ProjectTemplate
    +3rdParty
        -CMakeLists.txt (3rd party cmake)
        -unittest-cpp-2.0.0.tar.gz
    +build
    +src
        -ClassTemplate.cpp (just a plain class file - compiles fine)
        -ClassTemplate.hpp (just a plain class file - compiles fine)
        -main.cpp (basic int main function)
    +UnitTests
        -CMakeLists.txt (unit test cmake)
        -UnittestcppMain.cpp (basic int main function)
    -CMakeLists.txt (root cmake)
    

CMake Contents

root cmake

cmake_minimum_required(VERSION 3.12)

# ====================================================================================================
#                                           Project Settings
# ====================================================================================================
project(ProjectName  VERSION 1.0.0.0 
                    DESCRIPTION "Project Description"
                    LANGUAGES CXX)

#Compiler Flags (Language default is C++17)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3 -Wall -std=c++17 -pedantic -U_FORTIFY_SOURCE")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3 -Wall -ansi -pedantic -U_FORTIFY_SOURCE")

#Project Source code Definitions
set(SOURCE
    ${CMAKE_SOURCE_DIR}/src/ClassTemplate.cpp
    ${CMAKE_SOURCE_DIR}/src/ClassTemplate.hpp)

#Project Library Definitions
add_library(ExecutableLib ${SOURCE})

#Project Executable Definitions
add_executable(ExecutableName ${CMAKE_SOURCE_DIR}/src/main.cpp)

#Project Include Directory Definitions
target_include_directories(ExecutableLib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/src/)

# ====================================================================================================
#                                      Project Links to Libraries
# ====================================================================================================
target_link_libraries(ExecutableName PRIVATE pthread )
target_link_libraries(ExecutableName PRIVATE ExecutableLib )
target_link_libraries(ExecutableName PRIVATE uuid)

# ====================================================================================================
#                                          Cmake Branch offs
# ====================================================================================================
add_subdirectory(${CMAKE_SOURCE_DIR}/3rdParty)  #Builds 3rd Party Libraries
add_subdirectory(${CMAKE_SOURCE_DIR}/UnitTests) #Builds Unit Tests

3rd party cmake

# ====================================================================================================
#                                          UnitTest++
# ====================================================================================================
set (UTCPP_PATH "${CMAKE_BINARY_DIR}/3rdParty/unittest-cpp-2.0.0")
set (UTCPP_TAR_PATH "${CMAKE_SOURCE_DIR}/3rdParty")
set (UTCPP_TARBALL_NAME "unittest-cpp-2.0.0.tar.gz")
set (UTCPP_FINAL_OBJECT "${UTCPP_PATH}/builds/libUnitTest++.a")
set (UTCPP_STAMP "UTCPP.stamp")

add_custom_target( UTCPP_untar_target ALL DEPENDS ${UTCPP_PATH}/${UTCPP_STAMP})
add_custom_target( UTCPP_build_target ALL DEPENDS ${UTCPP_FINAL_OBJECT})
add_library(UTCPP_3rdParty STATIC IMPORTED GLOBAL)

add_dependencies(UTCPP_build_target UTCPP_untar_target)

#decompresses the tar file
add_custom_command(OUTPUT ${UTCPP_PATH}/${UTCPP_STAMP}
   COMMAND ${CMAKE_COMMAND} -E remove_directory ${UTCPP_PATH}
   COMMAND ${CMAKE_COMMAND} -E tar xf ${UTCPP_TAR_PATH}/${UTCPP_TARBALL_NAME}
   COMMAND ${CMAKE_COMMAND} -E touch ${UTCPP_PATH}/${UTCPP_STAMP}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/3rdParty/
DEPENDS ${UTCPP_TAR_PATH}/${UTCPP_TARBALL_NAME}
COMMENT "Unpacking Unittest++ ${UTCPP_TARBALL_NAME}"
VERBATIM)

#So cmake does not complain about include dir not existing
file(MAKE_DIRECTORY "${UTCPP_PATH}")

#Builds UnitTest++ (unittest++ tar has a 'builds' directory where it expects to do builds)
add_custom_command(
      OUTPUT ${UTCPP_FINAL_OBJECT}
      COMMAND ${CMAKE_COMMAND} -DCMAKE_INSTALL_PREFIX=${UTCPP_PATH}/builds ..;
      COMMAND $(MAKE);
      COMMAND $(MAKE) install;
      WORKING_DIRECTORY ${UTCPP_PATH}/builds/
      COMMENT "Building ${UTCPP_FINAL_OBJECT}")

add_dependencies(UTCPP_3rdParty UTCPP_build_target)
add_dependencies(UTCPP_3rdParty ${UTCPP_FINAL_OBJECT})
set_target_properties(UTCPP_3rdParty PROPERTIES
IMPORTED_LOCATION "${UTCPP_FINAL_OBJECT}"
INTERFACE_INCLUDE_DIRECTORIES "${UTCPP_PATH}")

unit test cmake

message("Made it to this")
add_executable(testExecutable ${CMAKE_CURRENT_SOURCE_DIR}/UnittestcppMain.cpp)
target_link_libraries(testExecutable UTCPP_3rdParty)
target_link_libraries(testExecutable pthread)
target_link_libraries(testExecutable ExecutableLib)

Build Output

Output from cmake generation / configure

[main] Configuring folder: ProjectTemplate 
[proc] Executing command: /usr/bin/cmake3 --no-warn-unused-cli -DCMAKE_EXPORT_COMPILE_COMMANDS:BOOL=TRUE -DCMAKE_BUILD_TYPE:STRING=Debug -DCMAKE_C_COMPILER:FILEPATH=/opt/rh/devtoolset-8/root/usr/bin/gcc -DCMAKE_CXX_COMPILER:FILEPATH=/opt/rh/devtoolset-8/root/usr/bin/g++ -S/path/to/ProjectTemplate -B/path/to/ProjectTemplate/build -G "Unix Makefiles"
[cmake] Not searching for unused variables given on the command line.
[cmake] -- The CXX compiler identification is GNU 8.3.1
[cmake] -- Check for working CXX compiler: /opt/rh/devtoolset-8/root/usr/bin/g++
[cmake] -- Check for working CXX compiler: /opt/rh/devtoolset-8/root/usr/bin/g++ - works
[cmake] -- Detecting CXX compiler ABI info
[cmake] -- Detecting CXX compiler ABI info - done
[cmake] -- Detecting CXX compile features
[cmake] -- Detecting CXX compile features - done
[cmake] Made it to this
[cmake] -- Configuring done
[cmake] -- Generating done
[cmake] -- Build files have been written to: /path/to/ProjectTemplate/build

output from build

[main] Building folder: ProjectTemplate 
[build] Starting build
[proc] Executing command: /usr/bin/cmake3 --build /path/to/ProjectTemplate/build --config Debug --target ExecutableName -j 18 --
[build] Scanning dependencies of target ExecutableLib
[build] [ 25%] Building CXX object CMakeFiles/ExecutableLib.dir/src/ClassTemplate.cpp.o
[build] [ 50%] Linking CXX static library libExecutableLib.a
[build] [ 50%] Built target ExecutableLib
[build] Scanning dependencies of target ExecutableName
[build] [ 75%] Building CXX object CMakeFiles/ExecutableName.dir/src/main.cpp.o
[build] [100%] Linking CXX executable ExecutableName
[build] [100%] Built target ExecutableName
[build] Build finished with exit code 0

Aucun commentaire:

Enregistrer un commentaire