Skip to content
Permalink
Browse files

Build libprimesieve as DLL on Windows (#60)

  • Loading branch information...
kimwalisch committed Oct 1, 2018
1 parent 551da68 commit e4f848a90871c6effa3bf5dbc2f80d59d6acc628
Showing with 146 additions and 88 deletions.
  1. +42 −14 CMakeLists.txt
  2. +14 −0 ChangeLog
  3. +16 −3 appveyor.yml
  4. +1 −1 doc/primesieve.1
  5. +2 −2 include/primesieve.h
  6. +2 −2 include/primesieve.hpp
  7. +1 −1 src/CpuInfo.cpp
  8. +31 −29 src/console/cmdoptions.cpp
  9. +37 −36 test/cpu_info.cpp
@@ -1,7 +1,7 @@
cmake_minimum_required(VERSION 3.4)
project(primesieve CXX)
set(PRIMESIEVE_VERSION "7.1")
set(PRIMESIEVE_SOVERSION "9.1.0")
set(PRIMESIEVE_VERSION "7.2")
set(PRIMESIEVE_SOVERSION "9.2.0")

# Build options ######################################################

@@ -12,14 +12,15 @@ option(BUILD_DOC "Build documentation" OFF)
option(BUILD_EXAMPLES "Build example programs" OFF)
option(BUILD_TESTS "Build test programs" OFF)

if(WIN32)
set(BUILD_SHARED_LIBS OFF)
endif()

if(NOT BUILD_SHARED_LIBS AND NOT BUILD_STATIC_LIBS)
message(FATAL_ERROR "One or both of BUILD_SHARED_LIBS or BUILD_STATIC_LIBS must be set to ON")
endif()

if(WIN32 AND BUILD_SHARED_LIBS)
# Export symbols to .def file
set(CMAKE_WINDOWS_EXPORT_ALL_SYMBOLS ON)
endif()

# primesieve binary source files #####################################

set(BIN_SRC src/console/cmdoptions.cpp
@@ -123,15 +124,23 @@ find_package(Threads REQUIRED QUIET)

if(BUILD_SHARED_LIBS)
add_library(libprimesieve SHARED ${LIB_SRC})
add_library(primesieve::primesieve ALIAS libprimesieve)
set_target_properties(libprimesieve PROPERTIES OUTPUT_NAME primesieve)
target_link_libraries(libprimesieve PRIVATE Threads::Threads ${LIBATOMIC})

string(REPLACE "." ";" SOVERSION_LIST ${PRIMESIEVE_SOVERSION})
list(GET SOVERSION_LIST 0 PRIMESIEVE_SOVERSION_MAJOR)
set_target_properties(libprimesieve PROPERTIES SOVERSION ${PRIMESIEVE_SOVERSION_MAJOR})
set_target_properties(libprimesieve PROPERTIES VERSION ${PRIMESIEVE_SOVERSION})

if(WIN32 AND NOT MINGW)
# On Windows the shared library will be named primesieve.dll
# and the associated import library will be named
# primesieve.lib. This is an issue as the static library
# is also named primesieve.lib. Hence we rename the import
# library to primesieve.dll.lib. The Rust programming
# language uses the same naming convention.
set_target_properties(libprimesieve PROPERTIES IMPORT_SUFFIX ".dll.lib")
endif()

target_compile_features(libprimesieve
PUBLIC
cxx_alias_templates
@@ -158,10 +167,8 @@ if(BUILD_STATIC_LIBS)
set_target_properties(libprimesieve-static PROPERTIES OUTPUT_NAME primesieve)
target_link_libraries(libprimesieve-static PRIVATE Threads::Threads ${LIBATOMIC})

if(BUILD_SHARED_LIBS)
if(TARGET libprimesieve)
add_dependencies(libprimesieve-static libprimesieve)
else()
add_library(primesieve::primesieve ALIAS libprimesieve-static)
endif()

target_compile_features(libprimesieve-static
@@ -183,6 +190,27 @@ if(BUILD_STATIC_LIBS)
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
endif()

# Static or shared linking ###########################################

# On Unix-like OSes we use shared linking against libprimesieve by
# default mainly because this is required by Linux distributions.
# On Windows we use static linking by default because the library's
# path is not encoded into the binary. This means that the binary
# will only work if the DLL is in the same directory or a directory
# that is in the PATH environment variable.

if(WIN32 AND TARGET libprimesieve-static)
set(STATIC_LINKING ON)
elseif(NOT TARGET libprimesieve)
set(STATIC_LINKING ON)
endif()

if(STATIC_LINKING)
add_library(primesieve::primesieve ALIAS libprimesieve-static)
else()
add_library(primesieve::primesieve ALIAS libprimesieve)
endif()

# primesieve binary ##################################################

if(BUILD_PRIMESIEVE)
@@ -191,7 +219,7 @@ if(BUILD_PRIMESIEVE)
target_compile_features(primesieve PRIVATE cxx_auto_type)
install(TARGETS primesieve DESTINATION ${CMAKE_INSTALL_BINDIR})

if(BUILD_STATIC_LIBS)
if(TARGET libprimesieve-static)
add_dependencies(primesieve libprimesieve-static)
endif()
endif()
@@ -226,13 +254,13 @@ install(FILES "${CMAKE_CURRENT_BINARY_DIR}/primesieveConfig.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/primesieveConfigVersion.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/primesieve")

if(BUILD_SHARED_LIBS)
if(TARGET libprimesieve)
install(EXPORT primesieveShared
NAMESPACE primesieve::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/primesieve")
endif()

if(BUILD_STATIC_LIBS)
if(TARGET libprimesieve-static)
install(EXPORT primesieveStatic
NAMESPACE primesieve::
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/primesieve")
@@ -1,3 +1,17 @@
Changes in version 7.2, 01/10/2018
==================================

Unreleased, work in progress.

This version finally builds libprimesieve as a shared library i.e.
primesieve.dll on Windows making it easier to use libprimesieve
in other programming languages on Windows. This feature has been
requested by many users for a long time.

* CMakeLists.txt: Add support for primesieve.dll.
* cmdoptions.cpp: Fix DLL linking issue.
* cpu_info.cpp: Fix DLL linking issue.

Changes in version 7.1, 19/08/2018
==================================

@@ -14,10 +14,23 @@ platform:
- x64

build_script:
- if "%platform%" == "x86" cmake -G "Visual Studio 15 2017" -DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON .
- if "%platform%" == "x64" cmake -G "Visual Studio 15 2017 Win64" -DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON .
- mkdir shared_linking
- cd shared_linking
- if "%platform%" == "x86" cmake -G "Visual Studio 15 2017" -DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON -DBUILD_STATIC_LIBS=OFF ..
- if "%platform%" == "x64" cmake -G "Visual Studio 15 2017 Win64" -DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON -DBUILD_STATIC_LIBS=OFF ..
- cmake --build . --config Release
- cd ..
- mkdir static_linking
- cd static_linking
- if "%platform%" == "x86" cmake -G "Visual Studio 15 2017" -DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON ..
- if "%platform%" == "x64" cmake -G "Visual Studio 15 2017 Win64" -DBUILD_EXAMPLES=ON -DBUILD_TESTS=ON ..
- cmake --build . --config Release --target install
- cd ..

test_script:
- cd shared_linking
- copy Release\primesieve.dll test\Release
- ctest -C Release
- test\Release\cpu_info.exe
- cd ..\static_linking
- ctest -C Release
- Release\primesieve.exe --cpu-info
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man 1.47.6.
.TH PRIMESIEVE "1" "August 2018" ""primesieve 7.1"" ""primesieve""
.TH PRIMESIEVE "1" "October 2018" ""primesieve 7.2"" ""primesieve""
.SH NAME
primesieve \- efficient prime number generator
.SH SYNOPSIS
@@ -12,9 +12,9 @@
#ifndef PRIMESIEVE_H
#define PRIMESIEVE_H

#define PRIMESIEVE_VERSION "7.1"
#define PRIMESIEVE_VERSION "7.2"
#define PRIMESIEVE_VERSION_MAJOR 7
#define PRIMESIEVE_VERSION_MINOR 1
#define PRIMESIEVE_VERSION_MINOR 2

#include <primesieve/iterator.h>

@@ -13,9 +13,9 @@
#ifndef PRIMESIEVE_HPP
#define PRIMESIEVE_HPP

#define PRIMESIEVE_VERSION "7.1"
#define PRIMESIEVE_VERSION "7.2"
#define PRIMESIEVE_VERSION_MAJOR 7
#define PRIMESIEVE_VERSION_MINOR 1
#define PRIMESIEVE_VERSION_MINOR 2

#include <primesieve/iterator.hpp>
#include <primesieve/primesieve_error.hpp>
@@ -175,7 +175,7 @@ namespace primesieve {

void CpuInfo::init()
{
typedef BOOL (WINAPI *LPFN_GLPIEX)(LOGICAL_PROCESSOR_RELATIONSHIP,
using LPFN_GLPIEX = BOOL (WINAPI*)(LOGICAL_PROCESSOR_RELATIONSHIP,
PSYSTEM_LOGICAL_PROCESSOR_INFORMATION_EX, PDWORD);

LPFN_GLPIEX glpiex = (LPFN_GLPIEX) GetProcAddress(
@@ -183,65 +183,67 @@ Option makeOption(const string& str)

void optionCpuInfo()
{
if (cpuInfo.hasCpuName())
cout << cpuInfo.cpuName() << endl;
const CpuInfo cpu;

if (cpu.hasCpuName())
cout << cpu.cpuName() << endl;
else
cout << "CPU name: unknown" << endl;

if (cpuInfo.hasCpuCores())
cout << "Number of cores: " << cpuInfo.cpuCores() << endl;
if (cpu.hasCpuCores())
cout << "Number of cores: " << cpu.cpuCores() << endl;
else
cout << "Number of cores: unknown" << endl;

if (cpuInfo.hasCpuThreads())
cout << "Number of threads: " << cpuInfo.cpuThreads() << endl;
if (cpu.hasCpuThreads())
cout << "Number of threads: " << cpu.cpuThreads() << endl;
else
cout << "Number of threads: unknown" << endl;

if (cpuInfo.hasThreadsPerCore())
cout << "Threads per core: " << cpuInfo.threadsPerCore() << endl;
if (cpu.hasThreadsPerCore())
cout << "Threads per core: " << cpu.threadsPerCore() << endl;
else
cout << "Threads per core: unknown" << endl;

if (cpuInfo.hasL1Cache())
cout << "L1 cache size: " << cpuInfo.l1CacheSize() / (1 << 10) << " KiB" << endl;
if (cpu.hasL1Cache())
cout << "L1 cache size: " << cpu.l1CacheSize() / (1 << 10) << " KiB" << endl;

if (cpuInfo.hasL2Cache())
cout << "L2 cache size: " << cpuInfo.l2CacheSize() / (1 << 10) << " KiB" << endl;
if (cpu.hasL2Cache())
cout << "L2 cache size: " << cpu.l2CacheSize() / (1 << 10) << " KiB" << endl;

if (cpuInfo.hasL3Cache())
cout << "L3 cache size: " << cpuInfo.l3CacheSize() / (double) (1 << 20) << " MiB" << endl;
if (cpu.hasL3Cache())
cout << "L3 cache size: " << cpu.l3CacheSize() / (double) (1 << 20) << " MiB" << endl;

if (cpuInfo.hasL1Cache())
if (cpu.hasL1Cache())
{
if (!cpuInfo.hasL1Sharing())
if (!cpu.hasL1Sharing())
cout << "L1 cache sharing: unknown" << endl;
else
cout << "L1 cache sharing: " << cpuInfo.l1Sharing()
<< ((cpuInfo.l1Sharing() > 1) ? " threads" : " thread") << endl;
cout << "L1 cache sharing: " << cpu.l1Sharing()
<< ((cpu.l1Sharing() > 1) ? " threads" : " thread") << endl;
}

if (cpuInfo.hasL2Cache())
if (cpu.hasL2Cache())
{
if (!cpuInfo.hasL2Sharing())
if (!cpu.hasL2Sharing())
cout << "L2 cache sharing: unknown" << endl;
else
cout << "L2 cache sharing: " << cpuInfo.l2Sharing()
<< ((cpuInfo.l2Sharing() > 1) ? " threads" : " thread") << endl;
cout << "L2 cache sharing: " << cpu.l2Sharing()
<< ((cpu.l2Sharing() > 1) ? " threads" : " thread") << endl;
}

if (cpuInfo.hasL3Cache())
if (cpu.hasL3Cache())
{
if (!cpuInfo.hasL3Sharing())
if (!cpu.hasL3Sharing())
cout << "L3 cache sharing: unknown" << endl;
else
cout << "L3 cache sharing: " << cpuInfo.l3Sharing()
<< ((cpuInfo.l3Sharing() > 1) ? " threads" : " thread") << endl;
cout << "L3 cache sharing: " << cpu.l3Sharing()
<< ((cpu.l3Sharing() > 1) ? " threads" : " thread") << endl;
}

if (!cpuInfo.hasL1Cache() &&
!cpuInfo.hasL2Cache() &&
!cpuInfo.hasL3Cache())
if (!cpu.hasL1Cache() &&
!cpu.hasL2Cache() &&
!cpu.hasL3Cache())
{
cout << "L1 cache size: unknown" << endl;
cout << "L2 cache size: unknown" << endl;
Oops, something went wrong.

0 comments on commit e4f848a

Please sign in to comment.
You can’t perform that action at this time.