I have downloaded a github project made it in C++. And I need to generate a solution (.sln) using CMake. But I failed as I've wrote in the post title:
Could NOT find Boost (missing: unit_test_framework) (found version
"1.75.0")
Here is the original CMakeLists.txt:
find_package(Boost COMPONENTS unit_test_framework REQUIRED)
include(CTest)
enable_testing()
add_executable(unit-test unit_test.cpp)
target_link_libraries(unit-test cpool ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
add_test(unit-test unit-test --show_progress=yes --log_format=XML --log_sink=cpool.xml --log_level=all --report_level=no)
add_custom_target(test
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Starting to run unit tests ..."
COMMAND bla bla bla
DEPENDS unit-test USES_TERMINAL
)
Got that error. Then I tried:
SET(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} "C:/Program Files/boost_1_75_0/boost")
SET(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} "C:/Program Files/boost_1_75_0/lib64-msvc-14.1")
FIND_PACKAGE(Boost)
IF (Boost_FOUND)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR})
ADD_DEFINITIONS( "-DHAS_BOOST" )
ENDIF()
find_package(Boost COMPONENTS unit_test_framework REQUIRED)
include(CTest)
enable_testing()
add_executable(unit-test unit_test.cpp)
target_link_libraries(unit-test cpool ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
add_test(unit-test unit-test --show_progress=yes --log_format=XML --log_sink=cpool.xml --log_level=all --report_level=no)
add_custom_target(test
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Starting to run unit tests ..."
COMMAND bla bla bla
DEPENDS unit-test USES_TERMINAL
)
The same error. I don't have much experience in CMake, could you help me to make it ?
P.S. I have installed boost in the following location:
P.S. I have tried also:
set(BOOST_ROOT "C:/Program Files/boost_1_75_0")
find_package(Boost COMPONENTS unit_test_framework REQUIRED)
include(CTest)
enable_testing()
add_executable(unit-test unit_test.cpp)
target_link_libraries(unit-test cpool ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
add_test(unit-test unit-test --show_progress=yes --log_format=XML --log_sink=cpool.xml --log_level=all --report_level=no)
add_custom_target(test
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Starting to run unit tests ..."
COMMAND bla bla bla
DEPENDS unit-test USES_TERMINAL
)
The same outcome.
Related
I tried to used https://github.com/julianxhokaxhiu/SteamworksSDKCI to use steam api on a simple SFML application (helloworld).
I wanted to use cmake to learn it, but I am struggling to understand how the provided CMakeLists and Find*.cmake file are expected to be used.
Currently, I have modified the CMakeLists to change the INSTALL_DIR
INSTALL_DIR "${CMAKE_BINARY_DIR}/../../vendor"
and my CMakeLists is :
cmake_minimum_required(VERSION 3.19)
project(SfmlWithCMake VERSION 1.0)
include(FetchContent)
set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${CMAKE_CURRENT_SOURCE_DIR}/cmake_steam")
# Configure external project
file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_steam)
execute_process(
COMMAND ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR}/cmake_steam
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/cmake_steam
)
# Build external project
execute_process(
COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR}/cmake_steam
)
set(BUILD_SHARED_LIBS OFF)
FetchContent_Declare(
SFML
GIT_REPOSITORY https://github.com/SFML/SFML.git
GIT_TAG 2.5.1
)
FetchContent_MakeAvailable(SFML)
find_package(STEAMWORKSSDK REQUIRED)
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED true)
# Generate config.h
configure_file(config.h.in config.h)
add_executable(
SfmlWithCMake
main.cpp
)
get_target_property(STEAMSDK STEAMWORKSSDK::STEAMWORKSSDK INCLUDE_DIRECTORIES)
target_include_directories(
SfmlWithCMake
PRIVATE
"${PROJECT_BINARY_DIR}"
"${STEAMSDK}"
)
target_link_libraries(
SfmlWithCMake
sfml-graphics
STEAMWORKSSDK::STEAMWORKSSDK
-static gcc stdc++ winpthread -dynamic
)
install(TARGETS SfmlWithCMake DESTINATION bin)
How to get include directories?
I do not succeed to add the steam include to the target_include_directories.
Here the ${STEAMSDK} is my last attempt to get the directory.
If I replace this by ${PROJECT_BINARY_DIR}/vendor/include, everything works.
Also, why does the SFML include are automatically added to my target include directories and not the steam one?
Am I using the Find*.cmake file the right way?
I understood that ExternalProject_Add was performed at build time and thus, as the find_package is needed at configue time, I added the two "execute_process". But, the readme on github only says to do the find package and add the target to target_link_libraries...
Thanks.
The add_custom_command is lisently failing if run from CMakeLists.txt
Is there a way to see in console what's happening when the command is executed?
EDIT: The code:
I tried to run examples from the repository but they didn't work.
The code is modified a little because I was trying to make it work somehow. If the command is run from the terminal it works, but cmake just refuses to work. And there is no output saying why it fails.
cmake_minimum_required(VERSION 3.5)
project(test LANGUAGES CXX)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
find_package(Qt5Core)
find_package(Qt5Gui)
find_package(Qt5Widgets)
# Download automatically, you can also just copy the conan.cmake file
if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake")
message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan")
file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/master/conan.cmake"
"${CMAKE_BINARY_DIR}/conan.cmake")
endif()
include(${CMAKE_BINARY_DIR}/conan.cmake)
conan_cmake_run(CONANFILE conanfile.txt
BASIC_SETUP)
get_filename_component(hw_proto "protos/test.proto" ABSOLUTE)
get_filename_component(hw_proto_path "${hw_proto}" PATH)
# Generated sources
set(hw_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/test.pb.cc")
set(hw_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/test.pb.h")
set(hw_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/test.grpc.pb.cc")
set(hw_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/test.grpc.pb.h")
message("CHECKING GRPC.
PROTOC: ${CONAN_BIN_DIRS_PROTOBUF}/protoc
AND PLUGIN: ${CONAN_BIN_DIRS_GRPC}/grpc_cpp_plugin
and lib dir ${CMAKE_CURRENT_BINARY_DIR} from ${hw_proto}
${hw_proto_srcs}
${hw_proto_hdrs}
${hw_grpc_srcs}
${hw_grpc_hdrs}
${hw_proto}
${hw_proto_path}
")
add_custom_command(
OUTPUT "${hw_proto_srcs}" "${hw_proto_hdrs}" "${hw_grpc_srcs}" "${hw_grpc_hdrs}"
COMMAND ${CONAN_BIN_DIRS_PROTOBUF}/protoc
ARGS --grpc_out="${CMAKE_CURRENT_BINARY_DIR}"
--cpp_out="${CMAKE_CURRENT_BINARY_DIR}"
--proto_path="${hw_proto_path}"
--plugin=protoc-gen-grpc="${CONAN_BIN_DIRS_GRPC}/grpc_cpp_plugin"
test.proto
)
add_executable(test
main.cpp
)
target_link_libraries(test Qt5::Core Qt5::Widgets Qt5::Gui pthread)
target_include_directories(test PRIVATE ${CMAKE_CURRENT_BINARY_DIR})
One way to see all commands being executed is to call cmake with the --verbose option.
I've got a CMakeLists.txt file that handles Doxygen generation for a software project. Its contents are:
find_package(Doxygen)
if (DOXYGEN_FOUND)
set(doxyfile_in ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
set(doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
configure_file(${doxyfile_in} ${doxyfile} #ONLY)
add_custom_target(doc ALL
${DOXYGEN_EXECUTABLE} ${doxyfile}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Generating API documentation with Doxygen" VERBATIM)
endif()
I'd really like to only run doxygen if I'm doing an install build. Is there some straightforward way of communicating that to cmake?
First remove the ALL from add_custom_target().
add_custom_target(doc ALL
by
add_custom_target(doc
Then add
install(CODE
"EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target doc)")
src: https://cmake.org/cmake/help/latest/command/install.html#code
Examples
CMakeList.txt:
cmake_minimum_required (VERSION 3.5)
project(meta VERSION 1.0.0 LANGUAGES NONE)
# ....
enable_language(CXX)
add_executable(app main.cpp)
include(GNUInstallDirs)
set(CMAKE_INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/foo)
install(TARGETS app
EXPORT FooTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
install(EXPORT FooTargets
NAMESPACE foo::
DESTINATION ${CMAKE_INSTALL_CONFIGDIR}
)
# replace by your own code
add_custom_target(doxygen
COMMAND echo Hello Doxygen
VERBATIM
)
install(CODE
"EXECUTE_PROCESS(COMMAND ${CMAKE_COMMAND} --build ${CMAKE_BINARY_DIR} --target doxygen)")
main.cpp
int main() {
return 0;
}
Shell:
$ cmake -H. -Bbuild
...
$ cmake --build build --target install -- DESTDIR=install
Scanning dependencies of target app
[ 50%] Building CXX object CMakeFiles/app.dir/main.cpp.o
[100%] Linking CXX executable app
[100%] Built target app
Install the project...
-- Install configuration: ""
-- Installing: install/usr/local/bin/app
-- Installing: install/usr/local/lib/cmake/foo/FooTargets.cmake
-- Installing: install/usr/local/lib/cmake/foo/FooTargets-noconfig.cmake
Scanning dependencies of target doxygen
Hello Doxygen
Built target doxygen
I've come up with an approach that divides the work between add_custom_command() and add_custom_target():
find_package(Doxygen)
if (DOXYGEN_FOUND)
set(doxyfile_in ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
set(doxyfile ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
configure_file(${doxyfile_in} ${doxyfile} #ONLY)
add_custom_command(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/doxygen.stamp
DEPENDS ${doxyfile}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMAND ${DOXYGEN_EXECUTABLE} ${doxyfile}
COMMAND cmake -E touch ${CMAKE_CURRENT_BINARY_DIR}/doxygen.stamp
COMMENT "Generating API documentation with Doxygen"
VERBATIM)
add_custom_target(doc ALL
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/doxygen.stamp)
endif()
It's not exactly what I originally was asking for, but it's good enough for my purposes. I'm not going to accept this answer just yet, in case someone chimes in with an answer that does more exactly address my initial request.
I'm doing C++ using libcURL. I got the task to test functions in Travis CI. So I used .travis.yml to get libcurl-dev and libssl-dev to connect to the project. I installed them and checked cURL configuration:
SSL support: enabled (OpenSSL)
But as I was trying to make main test file i got list of errors (example)
`Linking CXX executable ../bin/TechProject_example
/usr/local/lib/libcurl.a(libcurl_la-openssl.o): In function ossl_recv:
openssl.c:(.text+0xf3): undefined reference to ERR_clear_error
openssl.c:(.text+0x11c): undefined reference to SSL_read
openssl.c:(.text+0x163): undefined reference to SSL_get_error`
and so on...
The only thing I was able to check is that libcurl is working properly. I placed
--without-ssl flag and got protocol error.
Also I used
`- sudo ln -fs /usr/lib/libcurl.so.4 /usr/local/lib/`
to avoid cmake error. (I'm not very good at UNIX command, so this can be a problem)
So how should properly connect openSSL to C++ project that has <curl/curl.h> ?
EDIT:
Here is CMakeLists.txt:
cmake_minimum_required(VERSION 2.8)
project (TechProject)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
set(HEADERS ${PROJECT_SOURCE_DIR}/include/testclass.h)
set(HEADERS ${PROJECT_SOURCE_DIR}/include/catch.hpp)
set(SOURCES ${PROJECT_SOURCE_DIR}/sources/testclass.cpp)
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
set(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)
include_directories(${PROJECT_SOURCE_DIR}/include)
add_library (${PROJECT_NAME} STATIC ${SOURCES})
add_subdirectory(example)
add_subdirectory(tests)
find_library(FOO_LIB libcurl.a)
target_link_libraries(TechProject "${FOO_LIB}")
And CMakeLists.txt in tests subdir:
cmake_minimum_required(VERSION 2.8)
set(TESTS_FOR_PROJECT TechProject)
project(${TESTS_FOR_PROJECT}_tests)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
option(BUILD_SHARED_LIBS "Build shared instead of static library" OFF)
file(GLOB ${PROJECT_NAME}_sources "${CMAKE_CURRENT_SOURCE_DIR}/source/*.cpp")
find_package(${TESTS_FOR_PROJECT})
include_directories(${${TESTS_FOR_PROJECT}_INCLUDE_DIRS}})
include_directories(${CPM_INCLUDE_DIRS})
add_executable(${PROJECT_NAME} ${${PROJECT_NAME}_sources} ${${PROJECT_NAME}_headers})
target_link_libraries(${PROJECT_NAME} ${TESTS_FOR_PROJECT})
add_custom_command(TARGET ${PROJECT_NAME} PRE_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
${CMAKE_CURRENT_SOURCE_DIR}/fixtures $<TARGET_FILE_DIR:${PROJECT_NAME}>)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${PROJECT_NAME} -s -r compact WORKING_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
Following is the my scenario. I have one top level CMakeList.txt and another 2 internal CMakeList.txt. In top level cmake I have 3 custom targets that are copy, build, copyandbuild. As name specifies make copy copies the source directories (i.e dir1, dir2) to ${CMAKE_SOURCE_DIR}. make build creates libs and executables. make copyandbuild (copy+build).
Running cmake .. from build directory completes successfully.
If I run make copyandbuild it is copying to ${CMAKE_SOURCE_DIR} but at the time of build it is showing error that
No rule to make target `dir1/libmylib.so', needed by `CMaketargetdbuild'. Stop
MyProject
dir1
CMakeLists.txt
dir2
CMakeLists.txt
CMakeLists.txt
It is working if i execute commands in below order.
cmake ..
make copyandbuild
cmake ..
make build
My requirement is it should work with out running cmake and make build again as copyandbuild doing the same work.
Top level CMakeLists.txt:
cmake_minimum_required(VERSION 2.6)
cmake_minimum_required(VERSION 2.6)
set(RE_BUILD make rebuild_cache)
set(OUTPUT_DIR ${CMAKE_SOURCE_DIR}/../)
if(EXISTS ${CMAKE_SOURCE_DIR}/dir1)
message(WARNING "Found dir1 dir")
add_subdirectory(dir1 EXCLUDE_FROM_ALL)
else()
message(WARNING "Couldn't find dir1 directory ")
endif()
if(EXISTS ${CMAKE_SOURCE_DIR}/dir2)
add_subdirectory(dir2 EXCLUDE_FROM_ALL)
else()
message(WARNING "Couldn't find dir2 directory")
endif()
set(MOVE_LIB_COMMAND mv src/myapp . && mv dir1/mylib .)
set(COPY_COMMAND cp -r ../sourceCode1 ../dir1 && cp -r ../sourceCode2 ../dir2)
set(CLEAN_DIR1_COMMAND cmake -E remove_directory ${CMAKE_SOURCE_DIR}/dir1)
set(CLEAN_DIR2_COMMAND cmake -E remove_directory ${CMAKE_SOURCE_DIR}/dir2)
set(SET_SLEEP sync)
#Copy command
add_custom_target(
copy ${COPY_COMMAND}
COMMAND ${RE_BUILD}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
#Compilation
add_custom_target(
build
COMMAND ${MOVE_LIB_COMMAND}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS mylib myapp
)
#copy and compile
add_custom_target(
copyandbuild
COMMAND ${MOVE_LIB_COMMAND}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS copy mylib myapp
)
add_custom_command(TARGET copy POST_BUILD
COMMAND ${SET_SLEEP}
)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")
dir1 CMake is :
cmake_minimum_required(VERSION 2.6)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")
include_directories(
${MY_APP_INCLUDE_DIRS}
)
link_directories(
${MY_APP_LIBDIR}
)
add_library(mylib
SHARED
com/*.cpp
)
target_link_libraries(mylib myapp_lib)
dir2 CMake is :
cmake_minimum_required(VERSION 2.6)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")
include_directories(
${MY_APP_INCLUDE_DIRS}
)
link_directories(
${MY_APP_LIBDIR}
)
You are using CMake in a way that prevents its proper function. By explicitly invoking shell commands in many places, when you could use CMake built in features, you are robbing CMake of any context that it could use to build your programs. Also, using wildcards like *.cpp in CMake is considered bad practice. And you have a number of duplicate statements--you do not need cmake_minimum_required() or setting compiler flags other than at the top level.
In short, your CMakeLists.txt at the top level should look more like this:
cmake_minimum_required(VERSION 2.6)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -std=c++11")
add_subdirectory(dir1 EXCLUDE_FROM_ALL)
You should not need to copy source files around--just build them from where they are, for example your dir1/CMakeLists.txt might be:
add_library(mylib
SHARED
sourceCode1/mylib.cpp
)
Keep it simple. Get it working. Then ask questions if you need to add missing features.