1
\$\begingroup\$

After wrestling with CMake I now have a fully working solution. It works, however, I completely massacred the CMake File:

This is my main cmake file:

cmake_minimum_required(VERSION 3.17)
project(Odin)

include(ProcessorCount)
ProcessorCount(N)
if(NOT N EQUAL 0)
    set(CMAKE_BUILD_PARALLEL_LEVEL ${N})
endif()

message("Parallelizing with ${N} Cores")

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED YES)
set(CMAKE_CXX_EXTENSIONS NO)

include_directories(Odin/engine)
include_directories(Odin/uci)
include_directories(Odin/util)
include_directories(Odin/util/iters)


# add our cmake modules under cmake/
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")

# Include CPM dependency manager
include(CPM)


if(WIN64)
SET(BOOST_ROOT "C:/Program Files (x86)/boost/boost_1_74_0")
include_directories(${BOOST_ROOT})
include_directories(${BOOST_ROOT}/stage/lib)
endif()

find_package(Boost 1.74.0 REQUIRED serialization)

message(STATUS "---------------------")
message(STATUS "Boost_FOUND: ${Boost_FOUND}")
message(STATUS "Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
message(STATUS "Boost_LIBRARY_DIRS: ${Boost_LIBRARY_DIRS}")
message(STATUS "Boost_LIBRARIES: ${Boost_LIBRARIES}")
message(STATUS "---------------------")

#EndBoost

add_executable(Odin
        Odin/engine/Odin.cc
        Odin/main.cc
        Odin/engine/Board.cc
        Odin/util/Utility.cc
        Odin/util/iters/BoardIterator.cc
        Odin/engine/Node.cc
        Odin/engine/Link.cc
        Odin/engine/Odin.h
        Odin/engine/Board.h
        Odin/engine/Figure.h
        Odin/util/Utility.h
        Odin/engine/Node.h
        Odin/engine/Link.h
        Odin/util/iters/BoardIterator.h)

add_library(Engine
        Odin/engine/Odin.cc
        Odin/main.cc
        Odin/engine/Board.cc
        Odin/util/Utility.cc
        Odin/util/iters/BoardIterator.cc
        Odin/engine/Node.cc
        Odin/engine/Link.cc
        Odin/engine/Odin.h
        Odin/engine/Board.h
        Odin/engine/Figure.h
        Odin/util/Utility.h
        Odin/engine/Node.h
        Odin/engine/Link.h
        Odin/util/iters/BoardIterator.h)


target_link_libraries(Engine PRIVATE Boost::serialization)
target_link_libraries(Odin PRIVATE Boost::serialization)

if(UNIX)
set(CMAKE_CXX_FLAGS "-O3 -march=native")
endif(UNIX)

#Make Tests
#enable testing
enable_testing()

# Pull doctest using CPM
cpmaddpackage("gh:onqtam/doctest#2.4.5")

# add the CMake modules for automatic test discovery so we can use
# doctest_discover_tests() CMake
set(CMAKE_MODULE_PATH "${doctest_SOURCE_DIR}/scripts/cmake"
        ${CMAKE_MODULE_PATH})


add_subdirectory(Testing)

To be honest, sometimes I had no idea what I was doing.

You see that I have to add every file into library and into the executable Odin. This is not that smart. I actually want my idea to still be able to add a .cpp file to the Odin - executable. However my test must still run, and they require me to add all the files twice.

You can find my tests (cmake) here: https://github.com/SuchtyTV/Odin/tree/master/Testing

Here are some questions:

  • How do I walk around this library/executable non-sense?
  • How do I ensure the Release build will be well optimized?
  • Can I download Boost with CPM, if so, how would I do that and how would that look in the cmake file?
  • Any other advices?
\$\endgroup\$
1
\$\begingroup\$

The code is mostly fine, however there are some problems:

SET(BOOST_ROOT "C:/Program Files (x86)/boost/boost_1_74_0")

^ This is wrong, because other developers may have Boost installed into different directory. Remove this line and let the user set BOOST_ROOT during configuration.

include_directories(${BOOST_ROOT})
include_directories(${BOOST_ROOT}/stage/lib)

^ Why is this required? The later find_package(Boost ...) call should set all required directories for you, which you can use in include_directories. This actually shouldn't be required at all, because linking to Boost using target_link_libraries should also set correct include directories.

add_executable(Odin ...
)

add_library(Engine ...
)

^ This looks wrong. First, you can remove code duplication by placing source files list into a variable:

set(SRCS ...
)

add_executable(Odin ${SRCS})
add_library(Engine ${SRCS})

Second, it looks strange that both library and executable consist of same source files. You probably want to keep most files being a part of the library and then link the library to executable. This is achieved by the same target_link_libraries command.

set(CMAKE_MODULE_PATH "${doctest_SOURCE_DIR}/scripts/cmake"
        ${CMAKE_MODULE_PATH})

^ Use list(APPEND ...), just like you did earlier in the code.

\$\endgroup\$
2
  • \$\begingroup\$ Thanks for your answer! I just need to build the tests with the help of the all source files, therefore I do not see another walk around. \$\endgroup\$
    – TVSuchty
    May 29 at 13:00
  • 1
    \$\begingroup\$ You're doing right thing with tests - they consist of single source file and link to the library. Why don't do this for the Odin executable? \$\endgroup\$
    – arrowd
    May 29 at 18:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.