Use ExternalProject_Add to build the examples in a stand-alone fashion.

This commit is contained in:
Walter Gray 2016-06-06 10:58:50 -07:00
parent 71556295ff
commit 09f6a5c1d2
2 changed files with 90 additions and 59 deletions

View File

@ -2,9 +2,56 @@ if(protobuf_VERBOSE)
message(STATUS "Protocol Buffers Examples Configuring...")
endif()
# Add examples subproject
add_subdirectory(../examples examples)
get_filename_component(examples_dir "../examples" ABSOLUTE)
if(protobuf_VERBOSE)
message(STATUS "Protocol Buffers Examples Configuring done")
endif()
include(ExternalProject)
# Internal utility function: Create a custom target representing a build of examples with custom options.
function(add_examples_build NAME)
ExternalProject_Add(${NAME}
PREFIX ${NAME}
SOURCE_DIR "${examples_dir}"
BINARY_DIR ${NAME}
STAMP_DIR ${NAME}/logs
INSTALL_COMMAND "" #Skip
LOG_CONFIGURE 1
CMAKE_CACHE_ARGS "-Dprotobuf_MSVC_STATIC_RUNTIME:BOOL=${protobuf_MSVC_STATIC_RUNTIME}"
"-DCMAKE_BUILD_TYPE:STRING=${CMAKE_BUILD_TYPE}"
"-Dprotobuf_VERBOSE:BOOL=${protobuf_VERBOSE}"
${ARGN}
)
set_property(TARGET ${NAME} PROPERTY FOLDER "Examples")
set_property(TARGET ${NAME} PROPERTY EXCLUDE_FROM_ALL TRUE)
endfunction()
# Add examples as an external project.
# sub_directory cannot be used because the find_package(protobuf) call would cause failures with redefined targets.
add_examples_build(examples "-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}")
add_dependencies(examples libprotobuf protoc)
option(protobuf_BUILD_EXAMPLES_MULTITEST "Build Examples in multiple configurations. Useful for testing." OFF)
mark_as_advanced(protobuf_BUILD_EXAMPLES_MULTITEST)
if(protobuf_BUILD_EXAMPLES_MULTITEST)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
#Build using the legacy compatiblity module.
add_examples_build(examples-legacy
"-Dprotobuf_DIR:PATH=${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_CMAKEDIR}"
"-Dprotobuf_MODULE_COMPATIBLE:BOOL=TRUE"
)
add_dependencies(examples-legacy libprotobuf protoc)
#Build using the installed library.
add_examples_build(examples-installed
"-Dprotobuf_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}"
)
#Build using the installed library in legacy compatiblity mode.
add_examples_build(examples-installed-legacy
"-Dprotobuf_DIR:PATH=${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_CMAKEDIR}"
"-Dprotobuf_MODULE_COMPATIBLE:BOOL=TRUE"
)
endif()

View File

@ -2,78 +2,62 @@
cmake_minimum_required(VERSION 2.8.12)
# Project
project(addressbook)
project(protobuf-examples)
# Find required protobuf package
find_package(protobuf 3 CONFIG REQUIRED)
find_package(protobuf CONFIG REQUIRED)
if(protobuf_VERBOSE)
message(STATUS "Using Protocol Buffers ${Protobuf_VERSION}")
endif()
file(GLOB SRC_LIST "*.cc")
file(GLOB PROTO_LIST "*.proto")
#
# Code generation
#
if(protobuf_MODULE_COMPATIBLE) # Old school
include_directories(${Protobuf_INCLUDE_DIRS})
protobuf_generate_cpp(PROTO_SRCS PROTO_HDRS ${PROTO_LIST})
else() # New style
set(PROTO_SRCS)
set(PROTO_HDRS)
foreach(FIL ${PROTO_LIST})
get_filename_component(ABS_FIL ${FIL} ABSOLUTE)
get_filename_component(FIL_WE ${FIL} NAME_WE)
list(APPEND PROTO_SRCS "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc")
list(APPEND PROTO_HDRS "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h")
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.cc"
"${CMAKE_CURRENT_BINARY_DIR}/${FIL_WE}.pb.h"
COMMAND protobuf::protoc
ARGS --cpp_out ${CMAKE_CURRENT_BINARY_DIR} -I ${CMAKE_CURRENT_SOURCE_DIR}
${ABS_FIL}
DEPENDS ${ABS_FIL}
COMMENT "Running C++ protocol buffer compiler on ${FIL}"
VERBATIM)
set(CMAKE_INCLUDE_CURRENT_DIR TRUE)
# 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()
include_directories(${CMAKE_CURRENT_BINARY_DIR})
foreach(example add_person list_people)
set(${example}_SRCS ${example}.cc)
set(${example}_PROTOS addressbook.proto)
include(GNUInstallDirs)
#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(FIL ${SRC_LIST})
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})
get_filename_component(FIL_NAME_WE ${FIL} NAME_WE)
set(APP ${FIL_NAME_WE}_cpp)
add_executable(${APP} ${FIL} ${PROTO_SRCS} ${PROTO_HDRS})
#
# Link libraries
#
if(protobuf_MODULE_COMPATIBLE) # Old school
target_link_libraries(${APP} ${Protobuf_LIBRARIES})
else() # New style
target_link_libraries(${APP} protobuf::libprotobuf)
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()
install(TARGETS ${APP}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} COMPONENT ${APP})
#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()