Anyone know how to copy the SQLite3.dll into the executable directory using CMAKE? I am able to use sqlite in generated VS project but when i try to run the exe it cannot find the dll.
I am guessing that CMAKE would write a copy command into the post-build events in the VS project settings? But how is that done through CMAKE.
cmake_minimum_required(VERSION 3.10)
add_executable(APP)
target_sources(APP
PRIVATE
include/box.hpp
src/box.cpp
src/main.cpp
)
target_include_directories(APP PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include)
# SQlite
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Modules)
set(SQLite3_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../external/sqlite3/include)
set(SQLite3_LIBRARY ${CMAKE_CURRENT_SOURCE_DIR}/../external/sqlite3/libraries/win10/x64)
find_package (SQLite3)
if (SQLITE3_FOUND)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../external/sqlite3/include)
list(APPEND EXTRA_LIBS ${CMAKE_CURRENT_SOURCE_DIR}/../external/sqlite3/libraries/win10/x64/sqlite3.lib)
endif (SQLITE3_FOUND)
list(APPEND EXTRA_LIBS LIBCORE)
list(APPEND EXTRA_LIBS Boost::filesystem)
target_link_libraries(APP PRIVATE ${EXTRA_LIBS})
# INSTALL
install(TARGETS APP DESTINATION ${PROJECT_BINARY_DIR}/TEMP/bin)
It is possible to use cmake in CMakeLists.txt as a tool and it has file copy functionality
Something like this might be a start
set(source_file "D:/temp/from/sqlite3.dll")
set(target_file "D:\\temp\\to\\sqlite3.dll")
execute_process( COMMAND ${CMAKE_COMMAND} -E copy_if_different "${source_file}" "${target_file}" RESULT_VARIABLE sResult )
CMake tutorial
Related
I want to create one .exe file from the Sunshine GitHub program, I'm new to Cmake and I build that program with its help
git clone https://github.com/loki-47-6F-64/sunshine.git --recursive
cd sunshine && mkdir build && cd build
cmake -G"Unix Makefiles" ..
mingw32-make
It builds and runs correctly and creates .exe, but works only in my system.
On other systems, it gets filesystem errors and shows the path of the system that I build it:
terminate called after throwing an instance of
'std::filesystem::__cxx11::filesystem_error' what(): filesystem
error: cannot copy file: No such file or directory
[E:/sunshine/assets/sunshine.conf] [E:/sunshine/assets/sunshine.conf]
here is its CMakeLists.txt file:
cmake_minimum_required(VERSION 3.0)
project(Sunshine)
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR})
add_subdirectory(third-party/Simple-Web-Server)
set(UPNPC_BUILD_SHARED OFF CACHE BOOL "no shared libraries")
set(UPNPC_BUILD_TESTS OFF CACHE BOOL "Don't build tests for miniupnpc")
set(UPNPC_BUILD_SAMPLE OFF CACHE BOOL "Don't build samples for miniupnpc")
set(UPNPC_NO_INSTALL ON CACHE BOOL "Don't install any libraries build for miniupnpc")
add_subdirectory(third-party/miniupnp/miniupnpc)
include_directories(third-party/miniupnp)
if(WIN32)
# Ugly hack to compile with #include <qos2.h>
add_compile_definitions(
QOS_FLOWID=UINT32
PQOS_FLOWID=UINT32*
QOS_NON_ADAPTIVE_FLOW=2)
endif()
add_subdirectory(third-party/moonlight-common-c/enet)
find_package(Threads REQUIRED)
find_package(OpenSSL REQUIRED)
list(APPEND SUNSHINE_COMPILE_OPTIONS -fPIC -Wall -Wno-missing-braces -Wno-maybe-uninitialized -Wno-sign-compare)
if(WIN32)
file(
DOWNLOAD "https://github.com/TheElixZammuto/sunshine-prebuilt/releases/download/1.0.0/pre-compiled.zip" "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip"
TIMEOUT 60
EXPECTED_HASH SHA256=5d59986bd7f619eaaf82b2dd56b5127b747c9cbe8db61e3b898ff6b485298ed6)
file(ARCHIVE_EXTRACT
INPUT "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled.zip"
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}/pre-compiled)
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static")
if(NOT DEFINED SUNSHINE_PREPARED_BINARIES)
set(SUNSHINE_PREPARED_BINARIES "${CMAKE_CURRENT_BINARY_DIR}/pre-compiled/windows")
endif()
add_compile_definitions(SUNSHINE_PLATFORM="windows")
add_subdirectory(tools) #This is temporary, only tools for Windows are needed, for now
list(APPEND SUNSHINE_DEFINITIONS APPS_JSON="apps_windows.json")
include_directories(third-party/ViGEmClient/include)
set(PLATFORM_TARGET_FILES
sunshine/platform/windows/publish.cpp
sunshine/platform/windows/misc.h
sunshine/platform/windows/misc.cpp
sunshine/platform/windows/input.cpp
sunshine/platform/windows/display.h
sunshine/platform/windows/display_base.cpp
sunshine/platform/windows/display_vram.cpp
sunshine/platform/windows/display_ram.cpp
sunshine/platform/windows/audio.cpp
third-party/ViGEmClient/src/ViGEmClient.cpp
third-party/ViGEmClient/include/ViGEm/Client.h
third-party/ViGEmClient/include/ViGEm/Common.h
third-party/ViGEmClient/include/ViGEm/Util.h
third-party/ViGEmClient/include/ViGEm/km/BusShared.h)
set(OPENSSL_LIBRARIES
libssl.a
libcrypto.a)
set(FFMPEG_INCLUDE_DIRS
${SUNSHINE_PREPARED_BINARIES}/include)
set(FFMPEG_LIBRARIES
${SUNSHINE_PREPARED_BINARIES}/lib/libavcodec.a
${SUNSHINE_PREPARED_BINARIES}/lib/libavdevice.a
${SUNSHINE_PREPARED_BINARIES}/lib/libavfilter.a
${SUNSHINE_PREPARED_BINARIES}/lib/libavformat.a
${SUNSHINE_PREPARED_BINARIES}/lib/libavutil.a
${SUNSHINE_PREPARED_BINARIES}/lib/libpostproc.a
${SUNSHINE_PREPARED_BINARIES}/lib/libswresample.a
${SUNSHINE_PREPARED_BINARIES}/lib/libswscale.a
${SUNSHINE_PREPARED_BINARIES}/lib/libx264.a
${SUNSHINE_PREPARED_BINARIES}/lib/libx265.a
${SUNSHINE_PREPARED_BINARIES}/lib/libhdr10plus.a
z lzma bcrypt libiconv.a)
list(PREPEND PLATFORM_LIBRARIES
libstdc++.a
libwinpthread.a
libssp.a
ksuser
wsock32
ws2_32
d3d11 dxgi D3DCompiler
setupapi
)
set_source_files_properties(third-party/ViGEmClient/src/ViGEmClient.cpp PROPERTIES COMPILE_DEFINITIONS "UNICODE=1;ERROR_INVALID_DEVICE_OBJECT_PARAMETER=650")
set_source_files_properties(third-party/ViGEmClient/src/ViGEmClient.cpp PROPERTIES COMPILE_FLAGS "-Wno-unknown-pragmas -Wno-misleading-indentation -Wno-class-memaccess")
else()
add_compile_definitions(SUNSHINE_PLATFORM="linux")
list(APPEND SUNSHINE_DEFINITIONS APPS_JSON="apps_linux.json")
find_package(X11 REQUIRED)
find_package(FFmpeg REQUIRED)
set(PLATFORM_TARGET_FILES
sunshine/platform/linux/publish.cpp
sunshine/platform/linux/vaapi.h
sunshine/platform/linux/vaapi.cpp
sunshine/platform/linux/misc.h
sunshine/platform/linux/misc.cpp
sunshine/platform/linux/display.cpp
sunshine/platform/linux/audio.cpp
sunshine/platform/linux/input.cpp
third-party/glad/src/egl.c
third-party/glad/src/gl.c
third-party/glad/include/EGL/eglplatform.h
third-party/glad/include/KHR/khrplatform.h
third-party/glad/include/glad/gl.h
third-party/glad/include/glad/egl.h)
set(PLATFORM_LIBRARIES
Xfixes
Xtst
xcb
xcb-shm
xcb-xfixes
Xrandr
${X11_LIBRARIES}
dl
evdev
pulse
pulse-simple
)
set(PLATFORM_INCLUDE_DIRS
${X11_INCLUDE_DIR}
/usr/include/libevdev-1.0
third-party/glad/include)
if(NOT DEFINED SUNSHINE_EXECUTABLE_PATH)
set(SUNSHINE_EXECUTABLE_PATH "sunshine")
endif()
configure_file(gen-deb.in gen-deb #ONLY)
configure_file(sunshine.service.in sunshine.service #ONLY)
endif()
add_subdirectory(third-party/cbs)
set(Boost_USE_STATIC_LIBS ON)
find_package(Boost COMPONENTS log filesystem REQUIRED)
set(SUNSHINE_TARGET_FILES
third-party/moonlight-common-c/reedsolomon/rs.c
third-party/moonlight-common-c/reedsolomon/rs.h
third-party/moonlight-common-c/src/Input.h
third-party/moonlight-common-c/src/Rtsp.h
third-party/moonlight-common-c/src/RtspParser.c
third-party/moonlight-common-c/src/Video.h
sunshine/upnp.cpp
sunshine/upnp.h
sunshine/cbs.cpp
sunshine/utility.h
sunshine/uuid.h
sunshine/config.h
sunshine/config.cpp
sunshine/main.cpp
sunshine/main.h
sunshine/crypto.cpp
sunshine/crypto.h
sunshine/nvhttp.cpp
sunshine/nvhttp.h
sunshine/httpcommon.cpp
sunshine/httpcommon.h
sunshine/confighttp.cpp
sunshine/confighttp.h
sunshine/rtsp.cpp
sunshine/rtsp.h
sunshine/stream.cpp
sunshine/stream.h
sunshine/video.cpp
sunshine/video.h
sunshine/input.cpp
sunshine/input.h
sunshine/audio.cpp
sunshine/audio.h
sunshine/platform/common.h
sunshine/process.cpp
sunshine/process.h
sunshine/network.cpp
sunshine/network.h
sunshine/move_by_copy.h
sunshine/task_pool.h
sunshine/thread_pool.h
sunshine/thread_safe.h
sunshine/sync.h
sunshine/round_robin.h
${PLATFORM_TARGET_FILES})
set_source_files_properties(sunshine/upnp.cpp PROPERTIES COMPILE_FLAGS -Wno-pedantic)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/third-party
${CMAKE_CURRENT_SOURCE_DIR}/third-party/cbs/include
${CMAKE_CURRENT_SOURCE_DIR}/third-party/moonlight-common-c/enet/include
${CMAKE_CURRENT_SOURCE_DIR}/third-party/moonlight-common-c/reedsolomon
${FFMPEG_INCLUDE_DIRS}
${PLATFORM_INCLUDE_DIRS}
)
string(TOUPPER "x${CMAKE_BUILD_TYPE}" BUILD_TYPE)
if("${BUILD_TYPE}" STREQUAL "XDEBUG")
list(APPEND SUNSHINE_COMPILE_OPTIONS -O0 -pedantic -ggdb3)
if(WIN32)
set_source_files_properties(sunshine/nvhttp.cpp PROPERTIES COMPILE_FLAGS -O2)
endif()
else()
add_definitions(-DNDEBUG)
list(APPEND SUNSHINE_COMPILE_OPTIONS -O3)
endif()
if(NOT SUNSHINE_ASSETS_DIR)
set(SUNSHINE_ASSETS_DIR "${CMAKE_CURRENT_SOURCE_DIR}/assets")
endif()
if(NOT SUNSHINE_CONFIG_DIR)
set(SUNSHINE_CONFIG_DIR "${SUNSHINE_ASSETS_DIR}")
endif()
if(NOT SUNSHINE_DEFAULT_DIR)
set(SUNSHINE_DEFAULT_DIR "${SUNSHINE_ASSETS_DIR}")
endif()
list(APPEND CBS_EXTERNAL_LIBRARIES
cbs)
list(APPEND SUNSHINE_EXTERNAL_LIBRARIES
libminiupnpc-static
${CBS_EXTERNAL_LIBRARIES}
${CMAKE_THREAD_LIBS_INIT}
stdc++fs
enet
opus
${FFMPEG_LIBRARIES}
${Boost_LIBRARIES}
${OPENSSL_LIBRARIES}
${PLATFORM_LIBRARIES})
list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_ASSETS_DIR="${SUNSHINE_ASSETS_DIR}")
list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_CONFIG_DIR="${SUNSHINE_CONFIG_DIR}")
list(APPEND SUNSHINE_DEFINITIONS SUNSHINE_DEFAULT_DIR="${SUNSHINE_DEFAULT_DIR}")
add_executable(sunshine ${SUNSHINE_TARGET_FILES})
target_link_libraries(sunshine ${SUNSHINE_EXTERNAL_LIBRARIES})
target_compile_definitions(sunshine PUBLIC ${SUNSHINE_DEFINITIONS})
set_target_properties(sunshine PROPERTIES CXX_STANDARD 17)
target_compile_options(sunshine PRIVATE ${SUNSHINE_COMPILE_OPTIONS})
I think in this file something makes this issue but I don't know.
This is its release file that works correctly and doesn't have my issue:
https://github.com/loki-47-6F-64/sunshine/releases/download/v0.9.0/Sunshine-Windows.zip
How can I create like this?
I fixed My problem by running CMake with one additional parameter.
cmake -G "Unix Makefiles" -DSUNSHINE_ASSETS_DIR=assets ..
exe program needs to know assets and also after that assets folder should be near the exe file like a programmer release.
I am building a project with Cmake and use FetchContent to manage dependencies. For several reasons I cannot depend on system-wide installed packages, so this package helps a lot. It allows me to do things like this:
cmake_minimum_required(VERSION 3.14)
project(dummy LANGUAGES C CXX)
include(FetchContent)
FetchContent_Declare(nlohmann
GIT_REPOSITORY https://github.com/onavratil-monetplus/json
GIT_TAG v3.7.3
)
FetchContent_MakeAvailable(nlohmann)
add_executable(dummy main.cpp)
target_link_libraries(dummy PUBLIC nlohmann_json::nlohmann_json)
Now this works nicely as long as the repo is a cmake project with CMakeLists.txt. I would love to use similar approach for non-cmake projects, such as Botan library. Apparently
FetchContent_Declare(botan
GIT_REPOSITORY https://github.com/onavratil-monetplus/botan
GIT_TAG 2.17.2
)
FetchContent_MakeAvailable(botan)
does not really do the job, the build doesnt run since its not a cmake project. One would consider adding
CONFIGURE_COMMAND "<SOURCE_DIR>/configure.py --prefix=<BINARY_DIR>"
BUILD_COMMAND "cd <SOURCE_DIR> && make"
or something similar to the declare command, yet the FetchContent docs explicitly says that these particular arguments are ignored when passed to FetchContent.
Now the struggle is obvious - how to properly use FetchContent in this scenario? I was considering using ExternalProject_Add after the fetchcontent, yet then fetchcontent seems useless (ExternalProject can download git repo as well). Moreover, I would like to use some of the targets of botan at config time (if it makes sense).
I'm facing the same problem. Since the Botan library does not use the CMake build system internally, we cannot use the Botan "targets". But it is possible to build the Botan library at CMake configure time and use library and header files. Here is my solution (minimal configuration, works only for MS Visual Studio):
cmake_minimum_required (VERSION 3.20)
if(WIN32)
if(NOT (${CMAKE_BUILD_TYPE} STREQUAL "Release"))
message(FATAL_ERROR "This configuration only works for a Release build")
endif()
# set paths
set(BOTAN_LIB_ROOT_DIR "${CMAKE_SOURCE_DIR}/external/botan")
set(BOTAN_LIB_REPOS_DIR "${BOTAN_LIB_ROOT_DIR}/repos")
set(BOTAN_LIB_FCSTUFF_DIR "${BOTAN_LIB_ROOT_DIR}/cmake-fetchcontent-stuff")
set(BOTAN_LIB_INSTALL_DIR "${BOTAN_LIB_ROOT_DIR}-install")
# download and unpack Botan library
include(FetchContent)
FetchContent_Declare(
botan
GIT_REPOSITORY https://github.com/randombit/botan.git
GIT_TAG 2.19.1
PREFIX ${BOTAN_LIB_FCSTUFF_DIR}
SOURCE_DIR ${BOTAN_LIB_REPOS_DIR}
)
set(FETCHCONTENT_QUIET OFF CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(botan)
# find Python3 Interpreter and run build, testing and installation
if(${botan_POPULATED} AND MSVC AND NOT EXISTS "${BOTAN_LIB_INSTALL_DIR}/lib/botan.lib")
find_package(Python3 COMPONENTS Interpreter)
if(NOT ${Python3_Interpreter_FOUND})
message(FATAL_ERROR "Python3 Interpreter NOT FOUND")
endif()
execute_process(
COMMAND ${Python3_EXECUTABLE} configure.py --cc=msvc --os=windows --prefix=${BOTAN_LIB_INSTALL_DIR}
WORKING_DIRECTORY ${BOTAN_LIB_REPOS_DIR}
COMMAND_ECHO STDOUT
)
execute_process(
COMMAND nmake
WORKING_DIRECTORY ${BOTAN_LIB_REPOS_DIR}
COMMAND_ECHO STDOUT
)
execute_process(
COMMAND nmake check
WORKING_DIRECTORY ${BOTAN_LIB_REPOS_DIR}
COMMAND_ECHO STDOUT
)
execute_process(
COMMAND nmake install
WORKING_DIRECTORY ${BOTAN_LIB_REPOS_DIR}
COMMAND_ECHO STDOUT
)
endif()
endif()
add_executable (main "main.cpp")
if(WIN32)
target_include_directories(main PUBLIC "${BOTAN_LIB_INSTALL_DIR}/include/botan-2")
target_link_libraries(main PUBLIC "${BOTAN_LIB_INSTALL_DIR}/lib/botan.lib")
configure_file("${BOTAN_LIB_INSTALL_DIR}/bin/botan.dll"
"${CMAKE_CURRENT_BINARY_DIR}/botan.dll"
COPYONLY
)
install(TARGETS main DESTINATION bin)
install(FILES "${BOTAN_LIB_INSTALL_DIR}/bin/botan.dll" DESTINATION bin)
endif()
Here is the full version: https://github.com/weenchvd/cmake-build-botan-lib
I've the following CMakeLists.txt for creating a little application:
cmake_minimum_required (VERSION 3.5.0)
project (sampleapp)
# Setting project flags
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib)
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/lib)
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/build/bin)
set (CMAKE_INCLUDE_CURRENT_DIR ON)
set (CMAKE_AUTOMOC ON)
# Finding needed packages
find_package (Qt5Widgets REQUIRED)
find_package (Qt5Core REQUIRED)
find_package (Qt5Gui REQUIRED)
# Setting project files
include_directories (${CMAKE_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR})
file (GLOB_RECURSE PROJECT_SRC *.cpp)
# Creating project
add_executable(${PROJECT_NAME} ${PROJECT_SRC})
# Linking dependencies
target_link_libraries (${PROJECT_NAME} somelibrary Qt5::Widgets Qt5::Gui Qt5::Core)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Widgets> $<TARGET_FILE_DIR:${PROJECT_NAME}>)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Gui> $<TARGET_FILE_DIR:${PROJECT_NAME}>)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Core> $<TARGET_FILE_DIR:${PROJECT_NAME}>)
When I run it and then build the application the Qt dlls are copied into target folder. In particular I copy:
Qt5Core.dll
Qt5Gui.dll
Qt5Widgets.dll
When I run the application it does not start anyway because the ICU libraries needed for Qt are not copied. When I start the application, Windows tells me that following libraries are missing:
icuin53.dll
icuuc53.dll
If I copy these libraries manually from Qt insallation folder it works (ok, I've an error regarding "platform plugins windows" missing but it's another story).
Is there a way to copy the icu libraries in a standard way, like the post build commands that I'm using for copying libraries? Or what's the best way to copy them in a transparent way, if possible (CMake can know what are dependencies of Qt and copy them where Qt are needed)?
Instead of copying each dll by hand, you can install all Qt dependencies using windeployqt, the tool provided with Qt for deployment on Windows.
You can first declare windeployqt as an imported executable:
find_package(Qt5
# ...
)
if(Qt5_FOUND AND WIN32 AND TARGET Qt5::qmake AND NOT TARGET Qt5::windeployqt)
get_target_property(_qt5_qmake_location
Qt5::qmake IMPORTED_LOCATION
)
execute_process(
COMMAND "${_qt5_qmake_location}" -query QT_INSTALL_PREFIX
RESULT_VARIABLE return_code
OUTPUT_VARIABLE qt5_install_prefix
OUTPUT_STRIP_TRAILING_WHITESPACE
)
set(imported_location "${qt5_install_prefix}/bin/windeployqt.exe")
if(EXISTS ${imported_location})
add_executable(Qt5::windeployqt IMPORTED)
set_target_properties(Qt5::windeployqt PROPERTIES
IMPORTED_LOCATION ${imported_location}
)
endif()
endif()
Now the imported executable can be used as follows:
add_executable(foo
# ...
)
if(TARGET Qt5::windeployqt)
add_custom_command(TARGET foo
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E remove_directory "${CMAKE_CURRENT_BINARY_DIR}/windeployqt"
COMMAND set PATH=%PATH%$<SEMICOLON>${qt5_install_prefix}/bin
COMMAND Qt5::windeployqt --dir "${CMAKE_CURRENT_BINARY_DIR}/windeployqt" "$<TARGET_FILE:foo>"
)
install(
DIRECTORY
"${CMAKE_CURRENT_BINARY_DIR}/windeployqt/"
DESTINATION ${FOO_INSTALL_RUNTIME_DESTINATION}
)
endif()
I am trying to run the example given in protobuf repo here, the c++ version. I have successfully installed the library and am able to run the Makefile. But on running the CMakeLists.txt, I get this error:
CMake Error at CMakeLists.txt:9 (find_package):
Could not find a package configuration file provided by "protobuf" with any
of the following names:
protobufConfig.cmake
protobuf-config.cmake
Add the installation prefix of "protobuf" to CMAKE_PREFIX_PATH or set
"protobuf_DIR" to a directory containing one of the above files. If
"protobuf" provides a separate development package or SDK, be sure it has
been installed.
-- Configuring incomplete, errors occurred!
See also "/home/cortana/Projects/CppProjects/proto/build/CMakeFiles/CMakeOutput.log".
See also "/home/cortana/Projects/CppProjects/proto/build/CMakeFiles/CMakeError.log".
I have updated my LD_LIBRARY_PATH but this error is still there. How do I remove this error?
EDIT:
CMakeLists.txt:
# Minimum CMake required
cmake_minimum_required(VERSION 2.8.12)
# Project
project(protobuf-examples)
include(FindProtobuf)
# Find required protobuf package
find_package(protobuf CONFIG REQUIRED)
if(protobuf_VERBOSE)
message(STATUS "Using Protocol Buffers ${Protobuf_VERSION}")
endif()
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
set(CMAKE_PREFIX_PATH
${CMAKE_PREFIX_PATH}
${THIRDPARTY_DIR}/protobuf-3.1.0
)
include_directories(${ProtobufIncludePath})
# http://www.cmake.org/Wiki/CMake_FAQ#How_can_I_build_my_MSVC_application_with_a_static_runtime.3F
if(MSVC AND protobuf_MSVC_STATIC_RUNTIME)
foreach(flag_var
CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
if(${flag_var} MATCHES "/MD")
string(REGEX REPLACE "/MD" "/MT" ${flag_var} "${${flag_var}}")
endif(${flag_var} MATCHES "/MD")
endforeach()
endif()
foreach(example add_person list_people)
set(${example}_SRCS ${example}.cc)
set(${example}_PROTOS addressbook.proto)
#Code Generation
if(protobuf_MODULE_COMPATIBLE) #Legacy Support
protobuf_generate_cpp(${example}_PROTO_SRCS ${example}_PROTO_HDRS ${${example}_PROTOS})
list(APPEND ${example}_SRCS ${${example}_PROTO_SRCS} ${${example}_PROTO_HDRS})
else()
foreach(proto_file ${${example}_PROTOS})
get_filename_component(proto_file_abs ${proto_file} ABSOLUTE)
get_filename_component(basename ${proto_file} NAME_WE)
set(generated_files ${basename}.pb.cc ${basename}.pb.h)
list(APPEND ${example}_SRCS ${generated_files})
add_custom_command(
OUTPUT ${generated_files}
COMMAND protobuf::protoc
ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} -I ${CMAKE_CURRENT_SOURCE_DIR} ${proto_file_abs}
COMMENT "Generating ${generated_files} from ${proto_file}"
VERBATIM
)
endforeach()
endif()
#Executable setup
set(executable_name ${example}_cpp)
add_executable(${executable_name} ${${example}_SRCS} ${${example}_PROTOS})
if(protobuf_MODULE_COMPATIBLE) #Legacy mode
target_include_directories(${executable_name} PUBLIC ${PROTOBUF_INCLUDE_DIRS})
target_link_libraries(${executable_name} ${PROTOBUF_LIBRARIES})
else()
target_link_libraries(${executable_name} protobuf::libprotobuf)
endif()
endforeach()
EDIT 2:
After trying for 2 hours, I couldn't fix the CMakeLists.txt provided by google examples. I wrote this basic one and it works for me:
PROJECT(protopuff)
CMAKE_MINIMUM_REQUIRED (VERSION 3.5)
SET(CMAKE_CXX_FLAGS "-g -Wall -Werror -std=c++11")
INCLUDE(FindProtobuf)
FIND_PACKAGE(Protobuf REQUIRED)
INCLUDE_DIRECTORIES(${PROTOBUF_INCLUDE_DIR})
PROTOBUF_GENERATE_CPP(PROTO_SRC PROTO_HEADER addressbook.proto)
ADD_LIBRARY(proto ${PROTO_HEADER} ${PROTO_SRC})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
ADD_EXECUTABLE(${CMAKE_PROJECT_NAME}_add add_person.cc)
ADD_EXECUTABLE(${CMAKE_PROJECT_NAME}_list list_people.cc)
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME}_add proto ${PROTOBUF_LIBRARY})
TARGET_LINK_LIBRARIES(${CMAKE_PROJECT_NAME}_list proto ${PROTOBUF_LIBRARY})
Your problem is here:
find_package(protobuf CONFIG REQUIRED)
The name should start with uppercase: Protobuf. And that is the reason why your version is working; because in there, you have used correct case (last code snippet line 6):
find_package(Protobuf REQUIRED)
Here cmake documentation for find_package
The command searches for a file called <name>Config.cmake or <lower-case-name>-config.cmake for each name specified.
in this thread fraser solved the problem but if you need to develop according to protobuf CMake config and find_package command in CMake for finding protobuf libraries. your protobuf library must be compiled with CMake and do not use configure routine .
after compile protobuf with CMake , a config file named protobuf-config.cmake will be generated into the prefix/lib/CMake/protobuf directory.
The CmakeList.txt that is provided by the OP works on Linux but it does NOT work on Windows.
There is a way to make the actual CMakeList.txt work without any changes. The problem is that it requires the CONFIG parameter and that part is not documented anywhere. We need to provide the path to that config using -Dprotobuf_DIR parameter while generating the project.
On Windows, wherever you have installed protobuf, it will have bin, cmake, include, lib folders. We need to give the path of this cmake folder as an argument, like following:
cmake -G "Visual Studio 16 2019" -A x64 -B _build2 -Dprotobuf_DIR=C:/protobuf/install/cmake
This will build a solution file in the current directory.
I have been getting a CMakeLists.txt together to compile what right now is an SFML sample in preparation to do my own source code. It feels like a hack, even though it works (Mac Makefile, VS nmake, VS solution) right now.
The main repository is at https://github.com/iaefai/Spider-Fish/
Any suggestions are welcome.
cmake_minimum_required(VERSION 2.8)
PROJECT(Spider-Fish)
FIND_PACKAGE(OpenGL REQUIRED)
FIND_PACKAGE(SFML REQUIRED)
IF (WIN32)
# Windows
link_directories(${SFML_INCLUDE_DIR}/../lib)
set(RESOURCE_HANDLER ${CMAKE_CURRENT_SOURCE_DIR}/src/windows/resources.cpp)
# link_directories(${FIND_SFML_LIB_PATHS})
ELSEIF(APPLE)
# Mac
SET(RESOURCE_HANDLER ${CMAKE_CURRENT_SOURCE_DIR}/src/mac/resources.mm)
SET(MACOSX_BUNDLE_GUI_IDENTIFER "com.iaefai.Spider-Fish")
SET(MACOSX_BUNDLE_BUNDLE_NAME ${PROJECT_NAME})
if (NOT CMAKE_OSX_ARCHITECTURES)
set(CMAKE_OSX_ARCHITECTURES "i386;x86_64"
CACHE STRING "Build architectures for OSX" FORCE)
endif()
if(EXISTS /Developer/SDKs/MacOSX10.7.sdk)
set(CMAKE_OSX_SYSROOT "/Developer/SDKs/MacOSX10.7.sdk"
CACHE STRING "Defaults to 10.7" FORCE)
else()
# use default SDK
endif()
find_library(COCOA_LIB Cocoa)
SET(EXTRA_LIBS ${COCOA_LIB} ${OPENGL_LIBRARIES})
ELSE()
# Linux // Assumed??
ENDIF()
#include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include})
include_directories(${SFML_INCLUDE_DIR})
SET(RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/assets/background.jpg
${CMAKE_CURRENT_SOURCE_DIR}/assets/blur.sfx
${CMAKE_CURRENT_SOURCE_DIR}/assets/colorize.sfx
${CMAKE_CURRENT_SOURCE_DIR}/assets/edge.sfx
${CMAKE_CURRENT_SOURCE_DIR}/assets/fisheye.sfx
${CMAKE_CURRENT_SOURCE_DIR}/assets/nothing.sfx
${CMAKE_CURRENT_SOURCE_DIR}/assets/pixelate.sfx
${CMAKE_CURRENT_SOURCE_DIR}/assets/sansation.ttf
${CMAKE_CURRENT_SOURCE_DIR}/assets/sprite.png
${CMAKE_CURRENT_SOURCE_DIR}/assets/wave.jpg
${CMAKE_CURRENT_SOURCE_DIR}/assets/wave.sfx)
SET (SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/src/Shader.cpp)
#SET (HEADERS include/resources.h)
add_executable(${PROJECT_NAME} ${SOURCES} ${RESOURCE_HANDLER})
The biggest hack seems to be the stuff to copy resources. That would be ideal to have a special command that could do that on multiplatform. Not entirely certain how to do that — I suspect a set_target_resources would be a good name.
IF (APPLE)
set_target_properties(${PROJECT_NAME}
PROPERTIES
MACOSX_BUNDLE_INFO_PLIST ${CMAKE_CURRENT_SOURCE_DIR}/src/mac/Spider-Fish-Info.plist
MACOSX_BUNDLE TRUE)
# add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND echo copying resources...
#${RESOURCES}
COMMAND mkdir -p ./${PROJECT_NAME}.app/Contents/Resources
COMMAND cp ${RESOURCES} ./${PROJECT_NAME}.app/Contents/Resources
)
# add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD COMMAND echo ${PROJECT_NAME}.app/Contents/Resources)
ENDIF (APPLE)
IF (WIN32)
set_target_properties(${PROJECT_NAME}
PROPERTIES
WIN32_EXECUTABLE FALSE)
I would worry about this custom stuff on windows because of how specialized it is getting.
set(EXTRA_LIBS sfml-main ${OPENGL_LIBRARIES})
# note we can add stuff to ADDITIONAL_MAKE_CLEAN_FILES
string(COMPARE EQUAL ${CMAKE_GENERATOR} "NMake Makefiles" NMAKE)
if (NMAKE)
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND echo copying dlls...
COMMAND copy ${SFML_INCLUDE_DIR}\\..\\bin\\*.dll .
COMMAND echo copying resources... from ${CMAKE_CURRENT_SOURCE_DIR}
COMMAND -mkdir resources
COMMAND copy \"${CMAKE_CURRENT_SOURCE_DIR}\\assets\\*.*\" resources)
else ()
add_custom_command(TARGET ${PROJECT_NAME} POST_BUILD
COMMAND echo copying dlls...
COMMAND copy ${SFML_INCLUDE_DIR}\\..\\bin\\*.dll .
COMMAND echo copying resources... from ${CMAKE_CURRENT_SOURCE_DIR}
# Visual Studio does not support the '-' to ignore errors
COMMAND rmdir /s /q resources
COMMAND mkdir resources
COMMAND copy \"${CMAKE_CURRENT_SOURCE_DIR}\\assets\\*.*\" resources)
endif (NMAKE)
ENDIF (WIN32)
#if (APPLE)
target_link_libraries(${PROJECT_NAME}
sfml-system
sfml-window
sfml-network
sfml-graphics
sfml-audio
${EXTRA_LIBS})
#endif (APPLE)
Have you tried using the INSTALL command instead of the custom post build steps.