Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Linking against wrong library path #17

Open
hugolm84 opened this issue Dec 5, 2022 · 0 comments · May be fixed by #18
Open

Linking against wrong library path #17

hugolm84 opened this issue Dec 5, 2022 · 0 comments · May be fixed by #18

Comments

@hugolm84
Copy link

hugolm84 commented Dec 5, 2022

Hi!

Using

Node 16.13.1 and CMake 3.24.3 I fail to link against boost libraries via

include(BoostLib)

require_boost_libs("1.69.0" "date_time")
target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES})

I get error:

make[2]: *** No rule to make target '~/.cmake-js/boost/1.69.0/stage/lib/libboost_iostreams-mt-d.a', needed by 'Debug/CppAddon.node'.  Stop.

for both OSX and Linux.

The issue is that BoostLibInstaller.cmake is setting the lib_path:

if((CMAKE_BUILD_TYPE STREQUAL "Debug") OR (CMAKE_BUILD_TYPE STREQUAL "") OR (NOT DEFINED CMAKE_BUILD_TYPE))
    set(lib_path "${install_dir}/${stage_dir}/lib/libboost_${lib_name}-mt-d.a")
else()
    set(lib_path "${install_dir}/${stage_dir}/lib/libboost_${lib_name}-mt.a")
endif()

that is used:

set_target_properties(${boost_lib} PROPERTIES
    IMPORTED_LOCATION "${lib_path}"
    LINKER_LANGUAGE CXX)

However, using the b2 args:

Linux:

link=static;threading=multi;runtime-link=shared;--build-dir=Build;stage;--stagedir=stage;-d+2;--hash;--ignore-site-config;variant=debug;--layout=tagged;-sNO_BZIP2=1;cxxflags=-fPIC;cxxflags=-std=c++11;toolset=gcc

OSX:

link=static;threading=multi;runtime-link=shared;--build-dir=Build;stage;--stagedir=stage;-d+2;--hash;--ignore-site-config;variant=debug;toolset=clang;cxxflags=-fPIC;cxxflags=-std=c++11;cxxflags=-stdlib=libc++;linkflags=-stdlib=libc++;architecture=combined;address-model=32_64;--layout=tagged

will generate binaries like:

Linux:

libboost_chrono-mt-d-x64.a

OSX:

libboost_chrono-mt-d-c32_64.a

Linking will later fail, as the path is set to the non existing libboost_chrono-mt-d.a lib.

I am not sure why these suffixes are added by BOOST build system, but the BoostLibInstaller.cmake can be patched like so:

if(UNIX)
    set(LIBSUFFIX "-x32")
    if(CMAKE_SIZEOF_VOID_P EQUAL 8)
            set(LIBSUFFIX "-x64")
    endif()
endif()
if(APPLE)
    string(REGEX MATCH "address-model\\=([0-9_]+)" model "${b2Args}")
    set(ADDRESS_MODEL ${CMAKE_MATCH_1})
    set(LIBSUFFIX "-c${ADDRESS_MODEL}")
endif()
if((CMAKE_BUILD_TYPE STREQUAL "Debug") OR (CMAKE_BUILD_TYPE STREQUAL "") OR (NOT DEFINED CMAKE_BUILD_TYPE))
    set(lib_path "${install_dir}/${stage_dir}/lib/libboost_${lib_name}-mt-d${LIBSUFFIX}.a")
else()
    set(lib_path "${install_dir}/${stage_dir}/lib/libboost_${lib_name}-mt${LIBSUFFIX}.a")
endif()

which is a bit better than the symlink step users of the BoostLib can use instead:

if (Boost_FOUND)
    # https://github.com/cmake-js/boost-lib/blob/master/cmake/GetBoostLibB2Args.cmake
    get_boots_lib_b2_args()
    string(REGEX MATCH "address-model\\=([0-9_]+)" model "${b2Args}")
    set(ADDRESS_MODEL ${CMAKE_MATCH_1})
    if(APPLE)
        set(ADDRESS_MODEL "c${ADDRESS_MODEL}")
    endif()
    if (NOT ADDRESS_MODEL OR ADDRESS_MODEL STREQUAL "")
        set(ADDRESS_MODEL "x64") # Lets assume x64 for linux
    endif()
    string(REGEX MATCH "variant\\=([A-Za-z0-9_])" variant "${b2Args}")
    set(VARIANT "-${CMAKE_MATCH_1}")

    foreach(lib ${Boost_LIBRARIES})
        set(want_lib "lib${lib}-mt${VARIANT}.a")
        set(have_lib "lib${lib}-mt${VARIANT}-${ADDRESS_MODEL}.a")
        if(NOT EXISTS "${Boost_INCLUDE_DIR}/stage/lib/${want_lib}")
            EXECUTE_PROCESS(COMMAND ln -sf ${have_lib} ${want_lib}
                WORKING_DIRECTORY "${Boost_INCLUDE_DIR}/stage/lib"
            )
            message(STATUS "Symlinked ${Boost_INCLUDE_DIR}/stage/lib/${have_lib} -> ${Boost_INCLUDE_DIR}/stage/lib/${want_lib}")
        endif()
    endforeach()
endif()

Best would be if the b2 output lib did not get prefixed...

@hugolm84 hugolm84 linked a pull request Dec 5, 2022 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant