So I’m working on a project that has build&test on ubuntu-latest and windows-latest.
Ubuntu-latest workflow works without a problem, but the windows-latest returns a linker error:
2024-11-05T10:50:55.6113330Z LINK : fatal error LNK1181: cannot open input file '..\lib\Release\wing_workshop_lib.lib' [D:\a\...\build\apps\WingWorkshop.vcxproj]
Files
I’m not sure what the problem is. But, this is my workflow for windows:
name: CMake build and test on Windows
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
env:
BUILD_TYPE: Release
jobs:
build:
name: build and test
runs-on: windows-latest
steps:
- uses: actions/checkout@v4
- name: Cache dependencies and build tools
uses: actions/cache@v3
with:
path: |
${{ github.workspace }}/build/_deps
C:/ProgramData/ccache
key: deps-${{ runner.os }}-${{ hashFiles('CMakeLists.txt') }}
restore-keys: |
deps-${{ runner.os }}-
# Install ccache (only runs if cache not found)
- name: Install ccache
if: steps.cache.outputs.cache-hit != 'true'
run: choco install ccache -y
- name: Configure CMake
run: >
cmake -B build
-DCMAKE_CXX_COMPILER_LAUNCHER=ccache
-DCMAKE_BUILD_TYPE=${{ env.BUILD_TYPE }}
-S ${{ github.workspace }}
- name: Build
run: cmake --build build --config ${{ env.BUILD_TYPE }}
- name: Test
run: ctest --test-dir build -C ${{ env.BUILD_TYPE }} -L WW --verbose
While my root cmake is:
cmake_minimum_required(VERSION 3.20)
project(WingWorkshop
VERSION 1.0.0
LANGUAGES CXX)
# Only do these if this is the main project, and not if it is included through add_subdirectory
if (CMAKE_PROJECT_NAME STREQUAL PROJECT_NAME)
# Optionally set things like CMAKE_CXX_STANDARD, CMAKE_POSITION_INDEPENDENT_CODE here
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
IF (WIN32)
# set stuff for windows
set(CMAKE_CXX_FLAGS "-Wall ${CMAKE_CXX_FLAGS}")
ELSE ()
set(CMAKE_CXX_FLAGS "-Wall -Wextra -Wno-deprecated-copy -Wno-maybe-uninitialized -Wno-unused -pedantic -O3 -fprofile-arcs -ftest-coverage -Wno-error=float-conversion -fPIC ${CMAKE_CXX_FLAGS}")
ENDIF ()
# Let's ensure -std=c++xx instead of -std=g++xx
set(CMAKE_CXX_EXTENSIONS OFF)
# Let's nicely support folders in IDEs
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Find ccache in the system
find_program(CCACHE_PROGRAM ccache)
# If ccache is found, use it as the compiler launcher
if(CCACHE_PROGRAM)
message(STATUS "ccache found: ${CCACHE_PROGRAM}")
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_PROGRAM}) # For C++ compiler
else()
message(STATUS "ccache not found, proceeding without it.")
endif()
# Testing only available if this is the main app
# Note this needs to be done in the main CMakeLists
# since it calls enable_testing, which must be in the
# main CMakeLists.
include(CTest)
endif ()
add_compile_definitions(_USE_MATH_DEFINES)
# Include CPM for dependency management
include(cmake/CPM.cmake)
# Use CPM to fetch spdlog
CPMAddPackage(
NAME spdlog
GITHUB_REPOSITORY gabime/spdlog
VERSION 1.14.1
OPTIONS "SPDLOG_BUILD_SHARED OFF" # Ensure static library
)
# Use CPM to fetch cxxopts
CPMAddPackage(
NAME cxxopts
GITHUB_REPOSITORY jarro2783/cxxopts
VERSION 3.0.0
)
# Use CPM to fetch openxlsx
CPMAddPackage(
NAME OpenXLSX
GITHUB_REPOSITORY troldal/OpenXLSX
GIT_TAG ededa1e8398305d0983648d3e9f120ff7e228d2b
OPTIONS "OPENXLSX_BUILD_DOCS=OFF" "OPENXLSX_BUILD_TESTS=OFF"
)
# Use CPM to fetch json
CPMAddPackage(
NAME nlohmann_json
GITHUB_REPOSITORY nlohmann/json
GIT_TAG v3.11.2 # You can change this to the latest version if needed
)
# Add Eigen using CPM
CPMAddPackage(
NAME Eigen
GITLAB_REPOSITORY libeigen/eigen
GIT_TAG 3.4
OPTIONS
"EIGEN_BUILD_DOC OFF" # Do not build documentation
"EIGEN_BUILD_PKGCONFIG OFF" # Optional, disables pkg-config
"BUILD_TESTING OFF" # Disable building and running tests
)
# CSV parser.
# Add csv-parser using CPM
CPMAddPackage(
NAME csv-parser
GITHUB_REPOSITORY vincentlaucsb/csv-parser
GIT_TAG 2.3.0 # Replace with the appropriate version you want
OPTIONS "CMAKE_POSITION_INDEPENDENT_CODE ON"
)
# Add PMP library using CPM
# Set EIGEN3_INCLUDE_DIR if it is not already defined
if (NOT DEFINED EIGEN3_INCLUDE_DIR)
set(EIGEN3_INCLUDE_DIR "${Eigen_SOURCE_DIR}/")
endif()
find_package(Eigen 3.4.0 REQUIRED)
# Check if PMP is already included with CPM
CPMAddPackage(
NAME pmp
GITHUB_REPOSITORY pmp-library/pmp-library
GIT_TAG 3.0.0 # Specify the version you need, or leave it out for the latest
OPTIONS
"PMP_BUILD_TESTS OFF" # Prevents building tests
"PMP_BUILD_EXAMPLES OFF" # Prevents building examples
"PMP_BUILD_DOCS OFF" # Prevents building documentation
"PMP_BUILD_VIS OFF"
)
# Pass version number to the code
add_definitions(-DWINGWORKSHOP_VERSION="${PROJECT_VERSION}")
# Subdirectories
add_subdirectory(apps)
add_subdirectory(src)
add_subdirectory(tests)
and my src/CMakeLists:
file(GLOB_RECURSE SOURCES "*.cpp")
# Create the library from the collected source files
add_library(wing_workshop_lib ${SOURCES})
add_library(wing_workshop::lib ALIAS wing_workshop_lib)
target_include_directories(wing_workshop_lib PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/../include)
target_compile_features(wing_workshop_lib PUBLIC cxx_std_20)
target_link_libraries(wing_workshop_lib PUBLIC spdlog::spdlog cxxopts OpenXLSX::OpenXLSX nlohmann_json Eigen3::Eigen csv pmp)
set_target_properties(wing_workshop_lib PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
# IDEs should put the headers in a nice place
source_group(
TREE "${PROJECT_SOURCE_DIR}/include"
PREFIX "Header Files"
FILES ${HEADER_LIST})
and finally my apps/CMakeLists.txt:
add_executable(WingWorkshop app.cpp)
target_link_libraries(WingWorkshop PRIVATE wing_workshop_lib spdlog::spdlog nlohmann_json)
set_target_properties(WingWorkshop PROPERTIES CXX_STANDARD 20)
target_compile_options(WingWorkshop PUBLIC "$<$<COMPILE_LANG_AND_ID:CXX,MSVC>:/permissive->")
set_target_properties(WingWorkshop PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
Again note that it seems to build on ubuntu-latest but not on windows.
What is really the problem?
I don’t really see what the problem would be and how to fix it. The wing_workshop_lin.dll
is created and is added into build/bin
directory. So at least it is created.
But remember that
2024-11-05T10:50:55.6113330Z LINK : fatal error LNK1181: cannot open input file '..\lib\Release\wing_workshop_lib.lib' [D:\a\...\build\apps\WingWorkshop.vcxproj]
So the linker looks for the dll in lib/ folder. I don’t get it.