Skip to content

[Work in Progress] Enable CMake build on Windows #1011

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 16 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 35 additions & 8 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,40 @@ set(INSTALL_BIN_DIR "${CMAKE_INSTALL_PREFIX}/bin" CACHE PATH "Installation direc
set(INSTALL_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib" CACHE PATH "Installation directory for libraries")
set(INSTALL_INC_DIR "${CMAKE_INSTALL_PREFIX}/include" CACHE PATH "Installation directory for headers")

function(install_windows_deps)
# Bootstrap vcpkg from CMake and auto-install deps in case if we are missing
# deps on Windows. Respect the target architecture variable.
set(VCPKG_TARGET_ARCHITECTURE
${ARCH}
PARENT_SCOPE)
message("Installing build tools and dependencies...")
set(ENV{ARCH} ${ARCH})
execute_process(
COMMAND ${CMAKE_SOURCE_DIR}/tools/setup-buildtools.cmd)
set(CMAKE_TOOLCHAIN_FILE
${CMAKE_SOURCE_DIR}/tools/vcpkg/scripts/buildsystems/vcpkg.cmake
PARENT_SCOPE)
endfunction()

# Autodetect vcpkg toolchain
if(DEFINED ENV{VCPKG_ROOT} AND NOT DEFINED CMAKE_TOOLCHAIN_FILE)
set(CMAKE_TOOLCHAIN_FILE
"$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake"
CACHE STRING "")
endif()

if(VCPKG_CHAINLOAD_TOOLCHAIN_FILE)
include("${VCPKG_CHAINLOAD_TOOLCHAIN_FILE}")
endif()

if (DEFINED CMAKE_TOOLCHAIN_FILE AND WIN32)
find_package(GTest)
if(NOT (GTEST_FOUND OR GTest_FOUND))
install_windows_deps()
endif()
find_package(GTest REQUIRED)
endif()

# Begin Uncomment for i386 build
#set(CMAKE_SYSTEM_PROCESSOR i386)
#set(CMAKE_C_FLAGS -m32)
Expand Down Expand Up @@ -254,13 +288,6 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
option(BUILD_APPLE_HTTP "Build Apple HTTP client" YES)
endif()

if(BUILD_UNIT_TESTS OR BUILD_FUNC_TESTS)
message("Adding gtest")
add_library(gtest STATIC IMPORTED GLOBAL)
message("Adding gmock")
add_library(gmock STATIC IMPORTED GLOBAL)
endif()

if(BUILD_APPLE_HTTP)
add_definitions(-DAPPLE_HTTP=1)
endif()
Expand Down Expand Up @@ -295,7 +322,7 @@ endif()
# Packaging
################################################################################################

if (BUILD_PACKAGE)
if (BUILD_PACKAGE AND (NOT WIN32))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor nit: what is the reason to check for NOT WIN32 - was it failing something if you don't add it? I wonder if we could eventually add logic in here under the if (BUILD_PACKAGE) to produce a package, e.g. nuget or alike, even if we build on Windows. My selfish interest - is we'd likely need this CMake flow for our organization telemetry.

if (${CMAKE_PACKAGE_TYPE} STREQUAL "deb")
# FIXME: hardcode it for 64-bit Linux for now
set(INSTALL_LIB_DIR ${CMAKE_INSTALL_PREFIX}/lib/${CPACK_DEBIAN_ARCHITECTURE}-linux-gnu)
Expand Down
32 changes: 32 additions & 0 deletions docs/building-with-vcpkg-cmake-windows.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Building 1DS C++ SDK with cmake on Windows

### Pre-requisite:

- VS 2017/2019
- Chocolatey Package Manager
- CMake 3.1.0 or higher

### Steps:

1. Clone the repo

PS C:\> git clone https://github.com/microsoft/cpp_client_telemetry.git


2. Fetch the submodules (specifically the vcpkg port):

PS C:\cpp_client_telemetry> git submodule update --init

3. Create CMake configuration

PS C:\cpp_client_telemetry> mkdir build
PS C:\cpp_client_telemetry> cd build
PS C:\cpp_client_telemetry\build> cmake -DCMAKE_TOOLCHAIN_FILE=..\tools\vcpkg\scripts\buildsystems\vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows ..

4. Run CMake build

PS C:\cpp_client_telemetry\build> cmake --build .

This should build the 1DS C++ library, along with the functional and unit tests in `build` folder
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we add instructions on how to add it to another projects CMake as well? Like add_directory(<path to cpp_client_telemetry>)?



9 changes: 8 additions & 1 deletion lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,14 @@ if(PAL_IMPLEMENTATION STREQUAL "CPP11")
elseif(PAL_IMPLEMENTATION STREQUAL "WIN32")
# Win32 Desktop for now.
# TODO: define a separate PAL for Win10 cmake build
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../zlib ${CMAKE_CURRENT_SOURCE_DIR}/../sqlite)
if (CMAKE_TOOLCHAIN_FILE)
find_package(SQLite3 REQUIRED)
find_package(ZLIB REQUIRED)
include_directories( ${ZLIB_INCLUDE_DIRS})
include_directories(${SQLite3_INCLUDE_DIRS})
else()
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../zlib ${CMAKE_CURRENT_SOURCE_DIR}/../sqlite)
endif()
add_definitions(-D_UNICODE -DUNICODE -DZLIB_WINAPI -DWIN32 -DMATSDK_PLATFORM_WINDOWS=1 -DMATSDK_SHARED_LIB=1 -D_UTC_SDK -D_CRT_SECURE_NO_WARNINGS -DUSE_BOND -D_WINDOWS -D_USRDLL -DWINVER=_WIN32_WINNT_WIN7)
remove_definitions(-D_MBCS)
list(APPEND SRCS
Expand Down
47 changes: 41 additions & 6 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
include_directories(. ${CMAKE_CURRENT_SOURCE_DIR}/../lib/include/public ${CMAKE_CURRENT_SOURCE_DIR}/../lib/include/mat ${CMAKE_CURRENT_SOURCE_DIR}/../lib/decoder ${CMAKE_CURRENT_SOURCE_DIR}/../sqlite )

include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../third_party/googletest/googletest/include
${CMAKE_CURRENT_SOURCE_DIR}/../third_party/googletest/googlemock/include
)
message("-->Lalit tests")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove?


include_directories(../lib)

Expand All @@ -14,10 +10,49 @@ set(TESTS_COMMON_SRCS
../../lib/decoder/PayloadDecoder.cpp
)

if (BUILD_FUNC_TESTS OR BUILD_UNIT_TEST)
if (WIN32 AND CMAKE_TOOLCHAIN_FILE)
find_package(gtest REQUIRED)
find_package(SQLite3 REQUIRED)
find_package(ZLIB REQUIRED)

# GMOCK is not included as part of GTEST package installed through vcpkg,
# so needs to be configured separately
find_library(GOOGLE_MOCK gmock REQUIRED)
find_library(GOOGLE_MOCK_MAIN gmock_main REQUIRED)
find_library(GOOGLE_MOCKD gmockd REQUIRED)
find_library(GOOGLE_MOCK_MAIND gmock_maind REQUIRED)

# GMOCK doesn't work with static linking.
add_definitions(-DGTEST_LINKED_AS_SHARED_LIBRARY)

message("GTEST_INCLUDE_DIRS = ${GTEST_INCLUDE_DIRS}")
message("GTEST_BOTH_LIBRARIES = ${GTEST_BOTH_LIBRARIES}")
message("GOOGLE_MOCK = ${GOOGLE_MOCK} ${GOOGLE_MOCK_MAIN}")
message("SQLite3_LIBRARIES = ${SQLite3_LIBRARIES} ${SQLite3_INCLUDE_DIRS}")
message("ZLIB_LIBRARIES = ${ZLIB_LIBRARIES}")

#Include headers to be used both for unit and functional tests
include_directories( ${GTEST_INCLUDE_DIRS} )
include_directories( ${GMOCK_INCLUDE_DIRS} )
include_directories( ${ZLIB_INCLUDE_DIRS} )
include_directories(${SQLite3_INCLUDE_DIRS} )

else()
message("Adding gtest")
add_library(gtest STATIC IMPORTED GLOBAL)
message("Adding gmock")
add_library(gmock STATIC IMPORTED GLOBAL)
include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/../third_party/googletest/googletest/include
${CMAKE_CURRENT_SOURCE_DIR}/../third_party/googletest/googlemock/include
)
endif()
endif()

if(BUILD_FUNC_TESTS)
add_subdirectory(functests)
endif()

if(BUILD_UNIT_TESTS)
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/unittests)
add_subdirectory(unittests)
Expand Down
46 changes: 29 additions & 17 deletions tests/functests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,24 +46,36 @@ else()
endif()

if(PAL_IMPLEMENTATION STREQUAL "WIN32")
# Link against prebuilt libraries on Windows
message("--- WIN32: Linking against prebuilt libraries")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/gtest")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/gmock")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/zlib")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/sqlite")
# link_directories(${CMAKE_BINARY_DIR}/gtest/ ${CMAKE_BINARY_DIR}/gmock/ ${CMAKE_BINARY_DIR}/zlib/ ${CMAKE_BINARY_DIR}/sqlite/)
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../../zlib )
target_link_libraries(FuncTests
mat
wininet.lib
${CMAKE_BINARY_DIR}/gtest/gtest.lib
${CMAKE_BINARY_DIR}/gmock/gmock.lib
${CMAKE_BINARY_DIR}/zlib/zlib.lib
${CMAKE_BINARY_DIR}/sqlite/sqlite.lib
)
if (NOT CMAKE_TOOLCHAIN_FILE)
# Link against prebuilt libraries on Windows
message("--- WIN32: Linking against prebuilt libraries")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/gtest")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/gmock")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/zlib")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/sqlite")
# link_directories(${CMAKE_BINARY_DIR}/gtest/ ${CMAKE_BINARY_DIR}/gmock/ ${CMAKE_BINARY_DIR}/zlib/ ${CMAKE_BINARY_DIR}/sqlite/)
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../../zlib )
target_link_libraries(FuncTests
mat
wininet.lib
${CMAKE_BINARY_DIR}/gtest/gtest.lib
${CMAKE_BINARY_DIR}/gmock/gmock.lib
${CMAKE_BINARY_DIR}/zlib/zlib.lib
${CMAKE_BINARY_DIR}/sqlite/sqlite.lib
)
else()
target_link_libraries(FuncTests
mat
wininet.lib
crypt32.lib
${GTEST_BOTH_LIBRARIES}
${GOOGLE_MOCK} ${GOOGLE_MOCKD}
${GOOGLE_MOCK_MAIN} ${GOOGLE_MOCK_MAIND}
${SQLite3_LIBRARIES}
${ZLIB_LIBRARIES}
)
endif()
else()

# Prefer linking to more recent local sqlite3
if(EXISTS "/usr/local/lib/libsqlite3.a")
set (SQLITE3_LIB "/usr/local/lib/libsqlite3.a")
Expand Down
49 changes: 32 additions & 17 deletions tests/unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,9 @@ set(SRCS
ZlibUtilsTests.cpp
)

set_source_files_properties(${SRCS} PROPERTIES COMPILE_FLAGS -Wno-deprecated-declarations)
if (NOT WIN32)
set_source_files_properties(${SRCS} PROPERTIES COMPILE_FLAGS -Wno-deprecated-declarations)
endif()

if (APPLE)
if (BUILD_IOS)
Expand Down Expand Up @@ -90,22 +92,35 @@ else()
endif()

if(PAL_IMPLEMENTATION STREQUAL "WIN32")
# Link against prebuilt libraries on Windows
message("--- WIN32: Linking against prebuilt libraries")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/gtest")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/gmock")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/zlib")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/sqlite")
# link_directories(${CMAKE_BINARY_DIR}/gtest/ ${CMAKE_BINARY_DIR}/gmock/ ${CMAKE_BINARY_DIR}/zlib/ ${CMAKE_BINARY_DIR}/sqlite/)
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../../zlib )
target_link_libraries(UnitTests
mat
wininet.lib
${CMAKE_BINARY_DIR}/gtest/gtest.lib
${CMAKE_BINARY_DIR}/gmock/gmock.lib
${CMAKE_BINARY_DIR}/zlib/zlib.lib
${CMAKE_BINARY_DIR}/sqlite/sqlite.lib
)
if (NOT CMAKE_TOOLCHAIN_FILE)
# Link against prebuilt libraries on Windows
message("--- WIN32: Linking against prebuilt libraries")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/gtest")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/gmock")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/zlib")
message("--- WIN32: ... ${CMAKE_BINARY_DIR}/sqlite")
# link_directories(${CMAKE_BINARY_DIR}/gtest/ ${CMAKE_BINARY_DIR}/gmock/ ${CMAKE_BINARY_DIR}/zlib/ ${CMAKE_BINARY_DIR}/sqlite/)
include_directories( ${CMAKE_CURRENT_SOURCE_DIR}/../../zlib )
target_link_libraries(UnitTests
mat
wininet.lib
${CMAKE_BINARY_DIR}/gtest/gtest.lib
${CMAKE_BINARY_DIR}/gmock/gmock.lib
${CMAKE_BINARY_DIR}/zlib/zlib.lib
${CMAKE_BINARY_DIR}/sqlite/sqlite.lib
)
else()
target_link_libraries(UnitTests
mat
wininet.lib
crypt32.lib
${GTEST_BOTH_LIBRARIES}
${GOOGLE_MOCK} ${GOOGLE_MOCKD}
${GOOGLE_MOCK_MAIN} ${GOOGLE_MOCK_MAIND}
${SQLite3_LIBRARIES}
${ZLIB_LIBRARIES}
)
endif()
else()

# Prefer linking to more recent local sqlite3
Expand Down
20 changes: 10 additions & 10 deletions tests/unittests/EventPropertiesTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ TEST(EventPropertiesTests, Construction)
EXPECT_THAT(ep.GetProperties(), SizeIs(1));
EXPECT_THAT(ep.GetPiiProperties(), IsEmpty());
EXPECT_TRUE(std::get<0>(ep.TryGetLevel()));
EXPECT_THAT(std::get<1>(ep.TryGetLevel()), DIAG_LEVEL_OPTIONAL);
EXPECT_THAT(std::get<1>(ep.TryGetLevel()), (uint8_t)DIAG_LEVEL_OPTIONAL);
}

TEST(EventPropertiesTests, Name)
Expand All @@ -45,21 +45,21 @@ TEST(EventPropertiesTests, DiagnosticLevel)
EventProperties epOptional("Optional", DIAG_LEVEL_OPTIONAL);
EXPECT_THAT(epOptional.GetName(), Eq("Optional"));
EXPECT_TRUE(std::get<0>(epOptional.TryGetLevel()));
EXPECT_THAT(std::get<1>(epOptional.TryGetLevel()), DIAG_LEVEL_OPTIONAL);
EXPECT_THAT(std::get<1>(epOptional.TryGetLevel()), (uint8_t)DIAG_LEVEL_OPTIONAL);

epOptional.SetLevel(DIAG_LEVEL_REQUIRED);
EXPECT_TRUE(std::get<0>(epOptional.TryGetLevel()));
EXPECT_THAT(std::get<1>(epOptional.TryGetLevel()), DIAG_LEVEL_REQUIRED);
EXPECT_THAT(std::get<1>(epOptional.TryGetLevel()), (uint8_t)DIAG_LEVEL_REQUIRED);

EventProperties epRequired("Required", DIAG_LEVEL_REQUIRED);
EXPECT_THAT(epRequired.GetName(), Eq("Required"));
EXPECT_TRUE(std::get<0>(epRequired.TryGetLevel()));
EXPECT_THAT(std::get<1>(epRequired.TryGetLevel()), DIAG_LEVEL_REQUIRED);
EXPECT_THAT(std::get<1>(epRequired.TryGetLevel()), (uint8_t)DIAG_LEVEL_REQUIRED);

EventProperties epCustom("Custom", 55);
EXPECT_THAT(epCustom.GetName(), Eq("Custom"));
EXPECT_TRUE(std::get<0>(epCustom.TryGetLevel()));
EXPECT_THAT(std::get<1>(epCustom.TryGetLevel()), 55);
EXPECT_THAT(std::get<1>(epCustom.TryGetLevel()), (uint8_t)55);
}

TEST(EventPropertiesTests, Timestamp)
Expand Down Expand Up @@ -203,7 +203,7 @@ TEST(EventPropertiesTests, TryGetLevel_NotTheRightType_ReturnsFalseAndZero)
properties.SetProperty(COMMONFIELDS_EVENT_LEVEL, "Not a number");
auto result = properties.TryGetLevel();
EXPECT_FALSE(std::get<0>(result));
EXPECT_EQ(std::get<1>(result), 0);
EXPECT_EQ(std::get<1>(result), (uint8_t)0);
}

TEST(EventPropertiesTests, TryGetLevel_ValueLargerThanUint8_ReturnsFalseAndZero)
Expand All @@ -212,7 +212,7 @@ TEST(EventPropertiesTests, TryGetLevel_ValueLargerThanUint8_ReturnsFalseAndZero)
properties.SetProperty(COMMONFIELDS_EVENT_LEVEL, 257);
auto result = properties.TryGetLevel();
EXPECT_FALSE(std::get<0>(result));
EXPECT_EQ(std::get<1>(result), 0);
EXPECT_EQ(std::get<1>(result), (uint8_t)0);
}

TEST(EventPropertiesTests, TryGetLevel_ValueLessThanZero_ReturnsFalseAndZero)
Expand All @@ -221,7 +221,7 @@ TEST(EventPropertiesTests, TryGetLevel_ValueLessThanZero_ReturnsFalseAndZero)
properties.SetProperty(COMMONFIELDS_EVENT_LEVEL, -1);
auto result = properties.TryGetLevel();
EXPECT_FALSE(std::get<0>(result));
EXPECT_EQ(std::get<1>(result), 0);
EXPECT_EQ(std::get<1>(result), (uint8_t)0);
}

TEST(EventPropertiesTests, TryGetLevel_ValidValue_ReturnsTrueAndCorrectValue)
Expand All @@ -230,7 +230,7 @@ TEST(EventPropertiesTests, TryGetLevel_ValidValue_ReturnsTrueAndCorrectValue)
properties.SetProperty(COMMONFIELDS_EVENT_LEVEL, 42);
auto result = properties.TryGetLevel();
EXPECT_TRUE(std::get<0>(result));
EXPECT_EQ(std::get<1>(result), 42);
EXPECT_EQ(std::get<1>(result), (uint8_t)42);
}

TEST(EventPropertiesTests, TryGetLevel_ValueSetBySetLevel_ReturnsTrueAndCorrectValue)
Expand All @@ -239,5 +239,5 @@ TEST(EventPropertiesTests, TryGetLevel_ValueSetBySetLevel_ReturnsTrueAndCorrectV
properties.SetLevel(42);
auto result = properties.TryGetLevel();
EXPECT_TRUE(std::get<0>(result));
EXPECT_EQ(std::get<1>(result), 42);
EXPECT_EQ(std::get<1>(result), (uint8_t)42);
}
Loading