diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8955551dfeb2..9904855a3d39 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -948,11 +948,12 @@ endif()
 
 if(USE_CPP_PACKAGE)
   add_subdirectory(cpp-package)
+  target_compile_definitions(mxnet PUBLIC MXNET_USE_CPP_PACKAGE=1)
+  if(BUILD_CPP_EXAMPLES)
+    add_subdirectory(example/image-classification/predict-cpp)
+  endif()
 endif()
 
-if(BUILD_CPP_EXAMPLES)
-  add_subdirectory(example/image-classification/predict-cpp)
-endif()
 add_subdirectory(tests)
 
 # ---[ Linter target
diff --git a/cpp-package/CMakeLists.txt b/cpp-package/CMakeLists.txt
index fec86e78e6b8..db64fa99bddf 100644
--- a/cpp-package/CMakeLists.txt
+++ b/cpp-package/CMakeLists.txt
@@ -1,25 +1,52 @@
-if(USE_CPP_PACKAGE)
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
-  set(CPP_PACKAGE_OP_H_HEADER ${CMAKE_CURRENT_LIST_DIR}/include/mxnet-cpp/op.h)
+cmake_minimum_required(VERSION 3.13)
+project(mxnet_cpp C CXX)
 
-  if(MSVC)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /utf-8")
-  endif(MSVC)
+add_library(mxnet_cpp INTERFACE)
 
-  add_custom_target(
-    cpp_package_op_h ALL
-    BYPRODUCTS ${CPP_PACKAGE_OP_H_HEADER}
-    MAIN_DEPENDENCY mxnet
-    DEPENDS mxnet ${CMAKE_CURRENT_SOURCE_DIR}/scripts/OpWrapperGenerator.py
-    COMMAND echo "Running: OpWrapperGenerator.py"
-    COMMAND python OpWrapperGenerator.py $<TARGET_FILE:mxnet>
-    WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scripts
-  )
+set(CPP_PACKAGE_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/include/)
+target_include_directories(mxnet_cpp INTERFACE "${CPP_PACKAGE_INCLUDE_DIR}")
+file(GLOB_RECURSE CPP_PACKAGE_HEADERS
+  "${CPP_PACKAGE_INCLUDE_DIR}/*.h"
+  "${CPP_PACKAGE_INCLUDE_DIR}/*.hpp")
+set(CPP_PACKAGE_OP_H_HEADER ${CMAKE_CURRENT_LIST_DIR}/include/mxnet-cpp/op.h)
+target_sources(mxnet_cpp INTERFACE ${CPP_PACKAGE_HEADERS} ${CPP_PACKAGE_OP_H_HEADER})
+target_link_libraries(mxnet_cpp INTERFACE mxnet ${mxnet_LINKER_LIBS})
 
-  if(BUILD_CPP_EXAMPLES)
-    add_subdirectory(example)
-  endif()
+add_custom_target(
+  cpp_package_op_h ALL
+  BYPRODUCTS ${CPP_PACKAGE_OP_H_HEADER}
+  MAIN_DEPENDENCY mxnet
+  DEPENDS mxnet ${CMAKE_CURRENT_SOURCE_DIR}/scripts/OpWrapperGenerator.py
+  COMMAND echo "Running: OpWrapperGenerator.py"
+  COMMAND python OpWrapperGenerator.py $<TARGET_FILE:mxnet>
+  WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/scripts
+)
+add_dependencies(mxnet_cpp cpp_package_op_h)
 
-  install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
+if(MSVC)
+  target_compile_options(mxnet_cpp INTERFACE "/utf-8")
+endif(MSVC)
 
+if(BUILD_CPP_EXAMPLES)
+  add_subdirectory(example)
+  add_subdirectory(example/inference)
 endif()
+
+install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
diff --git a/cpp-package/example/CMakeLists.txt b/cpp-package/example/CMakeLists.txt
index 643a92d9a3bc..bf9427af03ee 100644
--- a/cpp-package/example/CMakeLists.txt
+++ b/cpp-package/example/CMakeLists.txt
@@ -1,72 +1,59 @@
-if(NOT MSVC)
-  set(UNITTEST_STATIC_LINK ON)
-endif()
-
-set(CPP_EXAMPLE_LIBS
-  ${BEGIN_WHOLE_ARCHIVE} mxnet_static ${END_WHOLE_ARCHIVE}
-  ${BEGIN_WHOLE_ARCHIVE} dmlc ${END_WHOLE_ARCHIVE}
-  ${mxnet_LINKER_LIBS}
-  )
-
-set(CPP_PACKAGE_INCLUDE_DIR ${CMAKE_CURRENT_LIST_DIR}/../include/mxnet-cpp/)
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
 
-set(CPPEX_DEPS cpp_package_op_h)
+# Explicitly set GENERATED property https://gitlab.kitware.com/cmake/cmake/issues/18399
+set_property(SOURCE ${CMAKE_CURRENT_LIST_DIR}/../include/mxnet-cpp/op.h PROPERTY GENERATED 1)
 
-file(GLOB_RECURSE CPP_PACKAGE_HEADERS
-  "${CPP_PACKAGE_INCLUDE_DIR}/*.h"
-  "${CPP_PACKAGE_INCLUDE_DIR}/*.hpp"
-  )
+add_executable(test_regress_label test_regress_label.cpp)
+target_link_libraries(test_regress_label mxnet_cpp)
 
-if (MSVC)
- add_custom_target(
-   cpp_package_deploy_library ALL
-   DEPENDS mxnet
-   COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:mxnet> $<TARGET_FILE_DIR:mlp>
- )
-endif()
-
-include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../include)
+add_executable(lenet lenet.cpp)
+target_link_libraries(lenet mxnet_cpp)
 
-add_executable(test_regress_label test_regress_label.cpp ${CPP_PACKAGE_HAEDERS})
-target_link_libraries(test_regress_label ${CPP_EXAMPLE_LIBS})
-add_dependencies(test_regress_label ${CPPEX_DEPS})
+add_executable(lenet_with_mxdataiter lenet_with_mxdataiter.cpp)
+target_link_libraries(lenet_with_mxdataiter mxnet_cpp)
 
-add_executable(lenet lenet.cpp ${CPP_PACKAGE_HEADERS})
-target_link_libraries(lenet ${CPP_EXAMPLE_LIBS})
-add_dependencies(lenet ${CPPEX_DEPS})
+add_executable(alexnet alexnet.cpp)
+target_link_libraries(alexnet mxnet_cpp)
 
-add_executable(lenet_with_mxdataiter lenet_with_mxdataiter.cpp ${CPP_PACKAGE_HEADERS})
-target_link_libraries(lenet_with_mxdataiter ${CPP_EXAMPLE_LIBS})
-add_dependencies(lenet_with_mxdataiter ${CPPEX_DEPS})
+add_executable(charRNN charRNN.cpp)
+target_link_libraries(charRNN mxnet_cpp)
 
-add_executable(alexnet alexnet.cpp ${CPP_PACKAGE_HEADERS})
-target_link_libraries(alexnet ${CPP_EXAMPLE_LIBS})
-add_dependencies(alexnet ${CPPEX_DEPS})
+add_executable(googlenet googlenet.cpp)
+target_link_libraries(googlenet mxnet_cpp)
 
-add_executable(charRNN charRNN.cpp ${CPP_PACKAGE_HEADERS})
-target_link_libraries(charRNN ${CPP_EXAMPLE_LIBS})
-add_dependencies(charRNN ${CPPEX_DEPS})
+add_executable(inception_bn inception_bn.cpp)
+target_link_libraries(inception_bn mxnet_cpp)
 
-add_executable(googlenet googlenet.cpp ${CPP_PACKAGE_HEADERS})
-target_link_libraries(googlenet ${CPP_EXAMPLE_LIBS})
-add_dependencies(googlenet ${CPPEX_DEPS})
+add_executable(mlp mlp.cpp)
+target_link_libraries(mlp mxnet_cpp)
 
-add_executable(inception_bn inception_bn.cpp ${CPP_PACKAGE_HEADERS})
-target_link_libraries(inception_bn ${CPP_EXAMPLE_LIBS})
-add_dependencies(inception_bn ${CPPEX_DEPS})
+add_executable(mlp_cpu mlp_cpu.cpp)
+target_link_libraries(mlp_cpu mxnet_cpp)
 
-add_executable(mlp mlp.cpp ${CPP_PACKAGE_HEADERS})
-target_link_libraries(mlp ${CPP_EXAMPLE_LIBS})
-add_dependencies(mlp ${CPPEX_DEPS})
+add_executable(mlp_gpu mlp_gpu.cpp)
+target_link_libraries(mlp_gpu mxnet_cpp)
 
-add_executable(mlp_cpu mlp_cpu.cpp ${CPP_PACKAGE_HEADERS})
-target_link_libraries(mlp_cpu ${CPP_EXAMPLE_LIBS})
-add_dependencies(mlp_cpu ${CPPEX_DEPS})
+add_executable(resnet resnet.cpp)
+target_link_libraries(resnet mxnet_cpp)
 
-add_executable(mlp_gpu mlp_gpu.cpp ${CPP_PACKAGE_HEADERS})
-target_link_libraries(mlp_gpu ${CPP_EXAMPLE_LIBS})
-add_dependencies(mlp_gpu ${CPPEX_DEPS})
 
-add_executable(resnet resnet.cpp ${CPP_PACKAGE_HEADERS})
-target_link_libraries(resnet ${CPP_EXAMPLE_LIBS})
-add_dependencies(resnet ${CPPEX_DEPS})
+if(MSVC)
+  add_custom_target(cpp_package_deploy_library ALL
+    DEPENDS mxnet
+    COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:mxnet> $<TARGET_FILE_DIR:mlp>)
+endif()
diff --git a/cpp-package/example/charRNN.cpp b/cpp-package/example/charRNN.cpp
index 94e9455c5941..effaa32bd845 100644
--- a/cpp-package/example/charRNN.cpp
+++ b/cpp-package/example/charRNN.cpp
@@ -29,7 +29,9 @@
  * Rename params file epoch number starts from zero.
  */
 
+#if _MSC_VER
 #pragma warning(disable: 4996)  // VS2015 complains on 'std::copy' ...
+#endif
 #include <cstring>
 #include <iostream>
 #include <fstream>
diff --git a/cpp-package/example/inference/CMakeLists.txt b/cpp-package/example/inference/CMakeLists.txt
new file mode 100644
index 000000000000..0566d28a57df
--- /dev/null
+++ b/cpp-package/example/inference/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+# Explicitly set GENERATED property https://gitlab.kitware.com/cmake/cmake/issues/18399
+set_property(SOURCE ${CMAKE_CURRENT_LIST_DIR}/../../include/mxnet-cpp/op.h PROPERTY GENERATED 1)
+
+add_executable(imagenet_inference "imagenet_inference.cpp")
+target_link_libraries(imagenet_inference mxnet_cpp)
