Skip to content

Commit b11dcd3

Browse files
authored
[WIP] fix windows build (#41)
* timer for windows and new cmake * trigger workflow * windows Timer * replace size_t in ivec with int * remove double return statement in test * change workflow to use ctest
1 parent 5ea67e2 commit b11dcd3

9 files changed

Lines changed: 111 additions & 64 deletions

File tree

.github/workflows/cmake.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,17 @@ jobs:
1111
runs-on: ${{ matrix.os }}
1212
strategy:
1313
matrix:
14-
os: [ubuntu-latest, macos-latest]
14+
os: [ubuntu-latest, macos-latest, windows-latest]
1515
build_type: [Release, Debug]
1616

1717
steps:
1818
- uses: actions/checkout@v3
1919

2020
- name: Configure CMake
21-
run: cmake -B build -S . -DCMAKE_BUILD_TYPE=${{ matrix.build_type }}
21+
run: cmake -B build -S . -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -DCMAKE_VERBOSE_MAKEFILE=ON
2222

2323
- name: Build
2424
run: cmake --build build --config ${{ matrix.build_type }}
2525

2626
- name: Run tests
27-
run: ./build/all_tests
27+
run: cd build && ctest -C ${{ matrix.build_type }} --verbose

CMakeLists.txt

Lines changed: 38 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,23 @@ else()
2020
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
2121
endif()
2222

23-
# Warning flags (always enabled)
24-
add_compile_options(
25-
-Wall # Enable most warnings
26-
-Wextra # Extra warnings
27-
-Wpedantic # Strict ISO C compliance
28-
-Wshadow # Warn about variable shadowing
29-
-Wformat=2 # Extra format string checks
30-
-Wcast-qual # Warn about cast that removes qualifiers
31-
-Wcast-align # Warn about pointer cast alignment issues
32-
-Wunused # Warn about unused variables/functions
33-
-Wdouble-promotion # Warn about float->double promotion
34-
-Wnull-dereference # Warn about null pointer dereference
35-
)
23+
# Warning flags (compiler-specific)
24+
if(MSVC)
25+
add_compile_options(/W4 /WX)
26+
else()
27+
add_compile_options(
28+
-Wall # Enable most warnings
29+
-Wextra # Extra warnings
30+
-Wpedantic # Strict ISO C compliance
31+
-Wshadow # Warn about variable shadowing
32+
-Wformat=2 # Extra format string checks
33+
-Wcast-qual # Warn about cast that removes qualifiers
34+
-Wcast-align # Warn about pointer cast alignment issues
35+
-Wunused # Warn about unused variables/functions
36+
-Wdouble-promotion # Warn about float to double promotion
37+
-Wnull-dereference # Warn about null pointer dereference
38+
)
39+
endif()
3640

3741
# Include directories
3842
include_directories(${PROJECT_SOURCE_DIR}/include)
@@ -43,15 +47,28 @@ file(GLOB_RECURSE SOURCES "src/*.c")
4347

4448
# Create core library
4549
add_library(dnlp_diff ${SOURCES})
46-
target_link_libraries(dnlp_diff m)
4750

48-
# Config-specific compile options
49-
target_compile_options(dnlp_diff PRIVATE
50-
$<$<CONFIG:Debug>:-g -O0>
51-
$<$<CONFIG:Release>:-O3 -DNDEBUG>
52-
$<$<CONFIG:RelWithDebInfo>:-O2 -g -DNDEBUG>
53-
$<$<CONFIG:MinSizeRel>:-Os -DNDEBUG>
54-
)
51+
# Link math library (Unix/Linux only)
52+
if(NOT MSVC)
53+
target_link_libraries(dnlp_diff m)
54+
endif()
55+
56+
# Config-specific compile options (compiler-specific)
57+
if(MSVC)
58+
target_compile_options(dnlp_diff PRIVATE
59+
$<$<CONFIG:Debug>:/Od /Zi>
60+
$<$<CONFIG:Release>:/O2 /DNDEBUG>
61+
$<$<CONFIG:RelWithDebInfo>:/O2 /Zi /DNDEBUG>
62+
$<$<CONFIG:MinSizeRel>:/Os /DNDEBUG>
63+
)
64+
else()
65+
target_compile_options(dnlp_diff PRIVATE
66+
$<$<CONFIG:Debug>:-g -O0>
67+
$<$<CONFIG:Release>:-O3 -DNDEBUG>
68+
$<$<CONFIG:RelWithDebInfo>:-O2 -g -DNDEBUG>
69+
$<$<CONFIG:MinSizeRel>:-Os -DNDEBUG>
70+
)
71+
endif()
5572

5673
# This is needed for clock_gettime on Linux without compiler extensions
5774
if(CMAKE_SYSTEM_NAME STREQUAL "Linux")

include/utils/Timer.h

Lines changed: 50 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,61 @@
1+
/*
2+
* Copyright 2025 Daniel Cederberg
3+
*
4+
* This file is part of the PSLP project (LP Presolver).
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
119
#ifndef TIMER_H
220
#define TIMER_H
321

4-
#include "time.h"
5-
22+
#if defined(_WIN32) || defined(_WIN64)
23+
#include <windows.h>
24+
typedef struct
25+
{
26+
LARGE_INTEGER start, end;
27+
} Timer;
28+
static inline void clock_gettime_monotonic(Timer *timer, int is_start)
29+
{
30+
if (is_start)
31+
{
32+
QueryPerformanceCounter(&timer->start);
33+
}
34+
else
35+
{
36+
QueryPerformanceCounter(&timer->end);
37+
}
38+
}
39+
static inline double get_elapsed_seconds(const Timer *timer)
40+
{
41+
LARGE_INTEGER freq;
42+
QueryPerformanceFrequency(&freq);
43+
return (double) (timer->end.QuadPart - timer->start.QuadPart) /
44+
(double) freq.QuadPart;
45+
}
46+
#define clock_gettime(CLOCK, PTR) \
47+
clock_gettime_monotonic((Timer *) (PTR), ((PTR) == &((Timer *) (PTR))->start))
48+
#define GET_ELAPSED_SECONDS(timer) get_elapsed_seconds(&(timer))
49+
#else
50+
#include <time.h>
651
typedef struct
752
{
853
struct timespec start, end;
954
} Timer;
1055

11-
// Macro to compute elapsed time in seconds
1256
#define GET_ELAPSED_SECONDS(timer) \
13-
(((timer).end.tv_sec - (timer).start.tv_sec) + \
14-
((double) ((timer).end.tv_nsec - (timer).start.tv_nsec) * 1e-9))
15-
16-
#define RUN_AND_TIME(func, timer, time_variable, result_var, ...) \
17-
do \
18-
{ \
19-
clock_gettime(CLOCK_MONOTONIC, &timer.start); \
20-
(result_var) = func(__VA_ARGS__); \
21-
clock_gettime(CLOCK_MONOTONIC, &timer.end); \
22-
(time_variable) += GET_ELAPSED_SECONDS(timer); \
23-
} while (0)
57+
((double) ((timer).end.tv_sec - (timer).start.tv_sec) + \
58+
(double) ((timer).end.tv_nsec - (timer).start.tv_nsec) / 1e9)
59+
#endif
2460

2561
#endif // TIMER_H

include/utils/Vec_macros.h

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -24,17 +24,23 @@
2424
#include <stdlib.h>
2525
#include <string.h>
2626

27+
// Portable UNUSED macro
28+
#if defined(_MSC_VER)
29+
#define PSLP_UNUSED
30+
#else
31+
#define PSLP_UNUSED __attribute__((unused))
32+
#endif
33+
2734
// Macro to define a generic vector class
2835
#define DEFINE_VECTOR(TYPE, TYPE_NAME) \
2936
typedef struct TYPE_NAME##Vec \
3037
{ \
3138
TYPE *data; \
32-
size_t len; \
33-
size_t capacity; \
39+
int len; \
40+
int capacity; \
3441
} TYPE_NAME##Vec; \
3542
\
36-
__attribute__((unused)) static TYPE_NAME##Vec *TYPE_NAME##Vec_new( \
37-
size_t capacity) \
43+
PSLP_UNUSED static TYPE_NAME##Vec *TYPE_NAME##Vec_new(int capacity) \
3844
{ \
3945
assert(capacity > 0); \
4046
TYPE_NAME##Vec *vec = (TYPE_NAME##Vec *) malloc(sizeof(TYPE_NAME##Vec)); \
@@ -68,7 +74,8 @@
6874
{ \
6975
vec->capacity *= 2; \
7076
assert(vec->capacity > 0); \
71-
TYPE *temp = (TYPE *) realloc(vec->data, vec->capacity * sizeof(TYPE)); \
77+
TYPE *temp = \
78+
(TYPE *) realloc(vec->data, (size_t) vec->capacity * sizeof(TYPE)); \
7279
if (temp == NULL) \
7380
{ \
7481
TYPE_NAME##Vec_free(vec); \
@@ -83,17 +90,18 @@
8390
} \
8491
\
8592
static inline void TYPE_NAME##Vec_append_array(TYPE_NAME##Vec *vec, \
86-
const TYPE *values, size_t n) \
93+
const TYPE *values, int n) \
8794
{ \
8895
if (vec->len + n > vec->capacity) \
8996
{ \
90-
size_t new_capacity = vec->capacity > 0 ? vec->capacity : 1; \
97+
int new_capacity = vec->capacity > 0 ? vec->capacity : 1; \
9198
while (vec->len + n > new_capacity) \
9299
{ \
93100
new_capacity *= 2; \
94101
} \
95102
\
96-
TYPE *temp = (TYPE *) realloc(vec->data, new_capacity * sizeof(TYPE)); \
103+
TYPE *temp = \
104+
(TYPE *) realloc(vec->data, (size_t) new_capacity * sizeof(TYPE)); \
97105
if (temp == NULL) \
98106
{ \
99107
TYPE_NAME##Vec_free(vec); \
@@ -105,13 +113,13 @@
105113
vec->capacity = new_capacity; \
106114
} \
107115
\
108-
memcpy(vec->data + vec->len, values, n * sizeof(TYPE)); \
116+
memcpy(vec->data + vec->len, values, (size_t) n * sizeof(TYPE)); \
109117
vec->len += n; \
110118
} \
111-
__attribute__((unused)) static int TYPE_NAME##Vec_contains( \
112-
const TYPE_NAME##Vec *vec, TYPE value) \
119+
PSLP_UNUSED static int TYPE_NAME##Vec_contains(const TYPE_NAME##Vec *vec, \
120+
TYPE value) \
113121
{ \
114-
for (size_t i = 0; i < vec->len; ++i) \
122+
for (int i = 0; i < vec->len; ++i) \
115123
{ \
116124
if (vec->data[i] == value) \
117125
{ \

src/affine/add.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,5 @@ expr *new_add(expr *left, expr *right)
101101
expr_retain(left);
102102
expr_retain(right);
103103

104-
// just for debugging, should be removed
105-
strcpy(node->name, "add");
106-
107104
return node;
108105
}

src/bivariate/const_scalar_mult.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,5 @@ expr *new_const_scalar_mult(double a, expr *child)
110110
mult_node->a = a;
111111
expr_retain(child);
112112

113-
// just for debugging, should be removed
114-
strcpy(node->name, "const_scalar_mult");
115-
116113
return node;
117114
}

src/elementwise_univariate/exp.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,5 @@ expr *new_exp(expr *child)
5151
node->local_jacobian = local_jacobian;
5252
node->local_wsum_hess = local_wsum_hess;
5353

54-
// just for debugging, should be removed
55-
strcpy(node->name, "exp");
5654
return node;
5755
}

src/elementwise_univariate/log.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,5 @@ expr *new_log(expr *child)
5656
node->local_jacobian = local_jacobian;
5757
node->local_wsum_hess = local_wsum_hess;
5858

59-
// just for debugging, should be removed
60-
strcpy(node->name, "log");
6159
return node;
6260
}

tests/wsum_hess/test_hstack.h

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -98,8 +98,6 @@ const char *test_wsum_hess_hstack()
9898

9999
free_expr(hstack_node);
100100
return 0;
101-
102-
return 0;
103101
}
104102

105103
const char *test_wsum_hess_hstack_matrix()
@@ -209,6 +207,4 @@ const char *test_wsum_hess_hstack_matrix()
209207

210208
free_expr(hstack_node);
211209
return 0;
212-
213-
return 0;
214210
}

0 commit comments

Comments
 (0)