Xrvitd / RFEPS

Code of RFEPS: Reconstructing Feature-line Equipped Polygonal Surface. ACM Transactions on Graphics, SIGGRAPH Asia 2022 Paper.
https://ruixu.me/html/RFEPS/index.html
GNU Affero General Public License v3.0
59 stars 8 forks source link

Make it runnable on Mac please #3

Closed rakhimovv closed 1 year ago

rakhimovv commented 1 year ago

Hello! Thanks for your work

I recently tried to run the code on mac with no success

First I removed the line set(CMAKE_TOOLCHAIN_FILE C:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake) from CMakeLists.txt Second I replaced everywhere #include <sys/io.h> with #include <sys/uio.h> Third I fixed another error https://stackoverflow.com/questions/23284473/fatal-error-eigen-dense-no-such-file-or-directory and replace <Eigen\Dense> with <Eigen/Dense> in imports Fourth in MAIN/MyRPD.hpp replaced gamma with Gamma otherwise a lot of errors and conflicts, because gamma is already specified in math.h

But finnaly I meet the following problem that I can't solve:

[  8%] Built target PQP
[ 12%] Built target Algorithm
[ 42%] Built target Optimization
[ 52%] Built target BaseShape
[ 56%] Built target PointCloudProcessing
[ 59%] Built target Draw
[ 64%] Built target Integral
[ 70%] Built target Tessellation2D
[ 77%] Built target Model
[ 80%] Built target Reconstruction
[ 85%] Built target Tessellation3D
[ 91%] Built target Geodesic
[ 96%] Built target CVTLike
[ 98%] Linking CXX executable MAIN
Undefined symbols for architecture x86_64:
  "_omp_set_num_threads", referenced from:
      Comput_RPD(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in main.cpp.o
      RFEPSTest(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool) in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [MAIN/MAIN] Error 1
make[1]: *** [MAIN/CMakeFiles/MAIN.dir/all] Error 2
make: *** [all] Error 2

Could you please test your code on Mac platform please

Xrvitd commented 1 year ago

Hi Rakhimov, thanks for your interest in this work, I don't currently have a mac but I have had success running it on a macbook with the M2 chip. You encounter the error "Undefined symbols for architecture x86_64: "_omp_set_num_threads"" is a command to control the number of threads in openmp. You can delete all "_omp_set_num_threads()", but this program will only run on a single core. Or you can try to install the openmp library for mac. We have tested it normally on an AMD 5950x hackintosh, but other macs (M1/M2 chip macbook) will run very slowly, we strongly recommend using windows for testing.

rakhimovv commented 1 year ago

Thanks for the clarifications, yes, I would like to use OpenMP. My mac uses Intel chip.

I installed OpenMP:

brew install libomp
brew link libomp --force

Then I added these lines to CMakeLists.txt:

# OpenMP (optional)
find_package(OpenMP COMPONENTS C CXX)
if(OpenMP_FOUND)
  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
  if(${CMAKE_VERSION} VERSION_LESS "3.7")
    message(STATUS "Found OpenMP")
  else()
    # We could use OpenMP_CXX_VERSION starting from CMake 3.9, but this value is only available on first run of CMake (see https://gitlab.kitware.com/cmake/cmake/issues/19150),
    # so we use always OpenMP_CXX_SPEC_DATE, which is available since CMake 3.7.
    message(STATUS "Found OpenMP, spec date ${OpenMP_CXX_SPEC_DATE}")
  endif()
  if(MSVC)
    if(MSVC_VERSION EQUAL 1900)
      set(OPENMP_DLL VCOMP140)
    elseif(MSVC_VERSION MATCHES "^191[0-9]$")
      set(OPENMP_DLL VCOMP140)
    elseif(MSVC_VERSION MATCHES "^192[0-9]$")
      set(OPENMP_DLL VCOMP140)
    endif()
    if(OPENMP_DLL)
      set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DELAYLOAD:${OPENMP_DLL}D.dll")
      set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DELAYLOAD:${OPENMP_DLL}.dll")
    else()
      message(WARNING "Delay loading flag for OpenMP DLL is invalid.")
    endif()
  endif()
else()
  message(STATUS "Not found OpenMP")
endif()

so now OpenMP is found. But I got another error:

[ 98%] Building CXX object MAIN/CMakeFiles/MAIN.dir/main.cpp.o
In file included from /Users/ruslan/Desktop/RFEPS/MAIN/main.cpp:22:
/Users/ruslan/Desktop/RFEPS/MAIN/MyRPD_rnn.hpp:485:37: warning: illegal character encoding in string literal [-Winvalid-source-encoding]
                cout << "max : " << maxk << " min <A3><BA>" << mink << endl;
                                                  ^~~~~~~~
/Users/ruslan/Desktop/RFEPS/MAIN/main.cpp:524:21: warning: implicit conversion from 'double' to 'alglib::ae_int_t' (aka 'long') changes value from 1.0E-6 to 0 [-Wliteral-conversion]
                ae_int_t maxits = 0.000001;
                         ~~~~~~   ^~~~~~~~
2 warnings generated.
[100%] Linking CXX executable MAIN
Undefined symbols for architecture x86_64:
  "___kmpc_dispatch_init_4", referenced from:
      _.omp_outlined..306 in main.cpp.o
      _.omp_outlined..322 in main.cpp.o
  "___kmpc_dispatch_next_4", referenced from:
      _.omp_outlined..306 in main.cpp.o
      _.omp_outlined..322 in main.cpp.o
  "___kmpc_for_static_fini", referenced from:
      _.omp_outlined. in main.cpp.o
  "___kmpc_for_static_init_4", referenced from:
      _.omp_outlined. in main.cpp.o
  "___kmpc_fork_call", referenced from:
      Comput_RPD(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in main.cpp.o
      RFEPSTest(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool) in main.cpp.o
  "_omp_set_num_threads", referenced from:
      Comput_RPD(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >) in main.cpp.o
      RFEPSTest(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >, bool) in main.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [MAIN/MAIN] Error 1
make[1]: *** [MAIN/CMakeFiles/MAIN.dir/all] Error 2
make: *** [all] Error 2

I have not found how to fix it, but I guess somehow one needs to "target link libraries", somehow link OpenMP to main.cpp but I have no idea how to do that.. I tried with no success:

if (OPENMP_found)
    target_link_libraries(${PROJECT_NAME} Algorithm BaseShape Draw Geodesic Integral Model Optimization PointCloudProcessing PQP Reconstruction Tessellation2D Tessellation3D MAIN OpenMP::OpenMP_CXX)
endif()
bearprin commented 1 year ago

@rakhimovv

Hi,

try the below sentences in the REFPS/MAIN/CMakeLists.txt:

target_link_libraries(MAIN PUBLIC Algorithm BaseShape Draw Geodesic Integral Model Optimization PointCloudProcessing PQP Reconstruction Tessellation2D Tessellation3D CVTLike OpenMP::OpenMP_CXX)

directly without if and specify the link type and target 'MAIN'

Also, you may need to change the path used in the function RFEPSTest

rakhimovv commented 1 year ago

Hi @bearprin ! Thanks for suggestion. But unfortunately I get another error:

CMake Error at CMakeLists.txt:107 (target_link_libraries):
  The plain signature for target_link_libraries has already been used with
  the target "MAIN".  All uses of target_link_libraries with a target must be
  either all-keyword or all-plain.

  The uses of the plain signature are here:

   * MAIN/CMakeLists.txt:4 (target_link_libraries)

p.s. Changing PUBLIC to PRIVATE did not help

bearprin commented 1 year ago

@rakhimovv

Well, you can only use the target_link_libraries once for the target 'MAIN'

You may need to merge target_link_libraries to one. The link type is not the reason for the issue

rakhimovv commented 1 year ago

@bearprin yeah, I got it

but there is no other line running target_link_libraries in CMakeLists.txt

Apologies, I just have almost no experience building cpp projects

rakhimovv commented 1 year ago

full file:


cmake_minimum_required(VERSION 3.17)
project(RFEPS)

# Default Build_type RELEASE
set(CMAKE_BUILD_TYPE RELEASE)
# CXX STANDARD
set(CMAKE_CXX_STANDARD 17)
# Set Version
set(VERSION 1.0)
# Set lib output directory
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${PROJECT_SOURCE_DIR}/lib)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${PROJECT_SOURCE_DIR}/lib)
#set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)

option(CMAKE_INSTALL_PREFIX "RFEPS install PATH" /usr/local)
# include header from project_source_dir
include_directories(${PROJECT_SOURCE_DIR}/include)

# Get Eigen3
find_package(Eigen3 REQUIRED)
if (Eigen3_FOUND)
    message(STATUS "${EIGEN3_VERSION_STRING}")
    include_directories(${EIGEN3_INCLUDE_DIR})
endif ()

# Get Boost
find_package(Boost REQUIRED)
if (Boost_FOUND)
    message(STATUS "BOOST FOUNDED")
    include_directories(${Boost_INCLUDE_DIRS})
endif ()

# Get CGAL
find_package(CGAL REQUIRED)
if (CGAL_FOUND)
    include(${CGAL_USE_FILE})
else ()
    message("ERROR: this program requires CGAL and will not be compiled.")
endif ()

# OpenMP (optional)
find_package(OpenMP COMPONENTS C CXX)
if(OpenMP_FOUND)
  set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
  if(${CMAKE_VERSION} VERSION_LESS "3.7")
    message(STATUS "Found OpenMP")
  else()
    # We could use OpenMP_CXX_VERSION starting from CMake 3.9, but this value is only available on first run of CMake (see https://gitlab.kitware.com/cmake/cmake/issues/19150),
    # so we use always OpenMP_CXX_SPEC_DATE, which is available since CMake 3.7.
    message(STATUS "Found OpenMP, spec date ${OpenMP_CXX_SPEC_DATE}")
  endif()
  if(MSVC)
    if(MSVC_VERSION EQUAL 1900)
      set(OPENMP_DLL VCOMP140)
    elseif(MSVC_VERSION MATCHES "^191[0-9]$")
      set(OPENMP_DLL VCOMP140)
    elseif(MSVC_VERSION MATCHES "^192[0-9]$")
      set(OPENMP_DLL VCOMP140)
    endif()
    if(OPENMP_DLL)
      set(CMAKE_SHARED_LINKER_FLAGS_DEBUG "${CMAKE_SHARED_LINKER_FLAGS_DEBUG} /DELAYLOAD:${OPENMP_DLL}D.dll")
      set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DELAYLOAD:${OPENMP_DLL}.dll")
    else()
      message(WARNING "Delay loading flag for OpenMP DLL is invalid.")
    endif()
  endif()
else()
  message(STATUS "Not found OpenMP")
endif()

if(WIN32 AND NOT MINGW)
  if(NOT DEFINED CMAKE_DEBUG_POSTFIX)
    set(CMAKE_DEBUG_POSTFIX "d")
  endif()
  if(NOT DEFINED CMAKE_RELWITHDEBINFO_POSTFIX)
    set(CMAKE_RELWITHDEBINFO_POSTFIX "rd")
  endif()
  if(NOT DEFINED CMAKE_MINSIZEREL_POSTFIX)
    set(CMAKE_MINSIZEREL_POSTFIX "s")
  endif()
endif()

# sub_directory
add_subdirectory(include)
add_subdirectory(src)
add_subdirectory(MAIN)

install(TARGETS Algorithm BaseShape Draw Geodesic Integral Model Optimization PointCloudProcessing PQP Reconstruction Tessellation2D Tessellation3D CVTLike
    EXPORT ${PROJECT_NAME}Targets
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION bin
    PUBLIC_HEADER DESTINATION include
    )   
install(DIRECTORY ./include/ DESTINATION include
        FILES_MATCHING PATTERN "*.h")
configure_file(${PROJECT_NAME}-config.cmake.in ${PROJECT_NAME}-config.cmake @ONLY)
install(EXPORT ${PROJECT_NAME}Targets
    FILE ${PROJECT_NAME}-config.cmake
    NAMESPACE ${PROJECT_NAME}::
    DESTINATION lib/cmake/${PROJECT_NAME}
    )

target_link_libraries(MAIN PRIVATE Algorithm BaseShape Draw Geodesic Integral Model Optimization PointCloudProcessing PQP Reconstruction Tessellation2D Tessellation3D CVTLike OpenMP::OpenMP_CXX)
bearprin commented 1 year ago

@rakhimovv

You send the code in the list under the REFPS directory.

Delete the last line and follow the below to link in the lib under REFPS/MAIN/CMakeLists.txt:

@rakhimovv

Hi,

try the below sentences in the REFPS/MAIN/CMakeLists.txt:

target_link_libraries(MAIN PUBLIC Algorithm BaseShape Draw Geodesic Integral Model Optimization PointCloudProcessing PQP Reconstruction Tessellation2D Tessellation3D CVTLike OpenMP::OpenMP_CXX)

directly without if and specify the link type and target 'MAIN'

Also, you may need to change the path used in the function RFEPSTest

rakhimovv commented 1 year ago

Did not notice it. Now it works! Thank you a lot @bearprin @Xrvitd !