-
Notifications
You must be signed in to change notification settings - Fork 86
Description
I recently attempted to build libcmaes on Windows 11 using Visual Studio 2022 (MSVC) and encountered several issues. After resolving them, I wanted to share the complete build process for other Windows users.
- Windows 11
- Visual Studio 2022
- vcpkg package manager
- CMake
Steps
1. Install Dependencies using vcpkg
First, install the required dependencies using vcpkg:
vcpkg install eigen3:x64-windows
vcpkg install glog:x64-windows
vcpkg install gflags:x64-windows
2. Modify CMakeLists.txt
The original CMakeLists.txt needs to be modified to support MSVC compiler flags. Locate the compiler flags section and replace it with the following:
if(MSVC)
# MSVC compiler flags
set(CMAKE_CXX_FLAGS "/W4")
set(CMAKE_CXX_FLAGS_DEBUG "/Zi /Od")
set(CMAKE_CXX_FLAGS_RELEASE "/O2")
else()
# GCC/Clang compiler flags
set(CMAKE_CXX_FLAGS "-Wall -Wextra")
set(CMAKE_CXX_FLAGS_DEBUG "-g")
set(CMAKE_CXX_FLAGS_RELEASE "-O3")
endif()
3. Modify eigenmvn.h
The file include/libcmaes/eigenmvn.h
needs to be modified to properly handle std::normal_distribution with MSVC. Locate the scalar_normal_dist_op
class and replace it with the following implementation:
template<typename Scalar>
class scalar_normal_dist_op
{
private:
void swap(scalar_normal_dist_op &other) {
std::swap(rng, other.rng);
std::swap(norm, other.norm);
}
public:
static std::mt19937 rng; // The uniform pseudo-random algorithm
mutable std::normal_distribution<Scalar> norm; // gaussian combinator
scalar_normal_dist_op() : norm(Scalar(0), Scalar(1)) {}
scalar_normal_dist_op(const scalar_normal_dist_op& other)
: norm(other.norm) {
}
scalar_normal_dist_op& operator=(const scalar_normal_dist_op& other) {
if (this != &other) {
norm = other.norm;
}
return *this;
}
scalar_normal_dist_op(scalar_normal_dist_op&& other) noexcept
: norm(std::move(other.norm)) {
}
scalar_normal_dist_op& operator=(scalar_normal_dist_op&& other) noexcept {
if (this != &other) {
norm = std::move(other.norm);
}
return *this;
}
template<typename Index>
inline const Scalar operator() (Index, Index = 0) const { return norm(rng); }
inline void seed(const uint64_t &s) { rng.seed(s); }
};
template<typename Scalar>
std::mt19937 scalar_normal_dist_op<Scalar>::rng;
template<typename Scalar>
struct functor_traits<scalar_normal_dist_op<Scalar> >
{ enum { Cost = 50 * NumTraits<Scalar>::MulCost, PacketAccess = false, IsRepeatable = false }; };
4. Build the Library
Now you can build the library:
# Create and enter build directory
mkdir build
cd build
# Configure with CMake
cmake .. -DCMAKE_TOOLCHAIN_FILE=[path to vcpkg]/scripts/buildsystems/vcpkg.cmake -DLIBCMAES_BUILD_TESTS=OFF -DLIBCMAES_BUILD_PYTHON=OFF -DLIBCMAES_USE_OPENMP=OFF -G "Visual Studio 17 2022" -A x64
# Build the library
cmake --build . --config Release
Replace [path to vcpkg]
with your actual vcpkg installation path.
Key Changes Summary
-
Compiler Flags: Added MSVC-specific compiler flags in CMakeLists.txt to handle the
-Wextra
flag issue. -
Dependencies: Used vcpkg for managing dependencies (eigen3, glog, gflags) instead of manual installation.
-
MSVC Compatibility: Modified the
scalar_normal_dist_op
class in eigenmvn.h to:- Add proper constructors and assignment operators
- Handle std::normal_distribution correctly
- Ensure compatibility with MSVC's requirements