4

Thank you for all who helped! What finally worked was changing:

set(CMAKE_CXX_COMPILER "gcc-10")
set(CMAKE_C_COMPILER "g++-10")

to:

set(CMAKE_CXX_COMPILER "/usr/local/opt/llvm/bin/clang")
set(CMAKE_C_COMPILER "/usr/local/opt/llvm/bin/clang++")

I get the following errors when trying to link boost to my program:

[ 83%] Linking CXX executable cartogram
Undefined symbols for architecture x86_64:
  "__ZN5boost15program_options11to_internalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE", referenced from:
      __ZN5boost15program_options11to_internalINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEESt6vectorIS7_SaIS7_EERKS8_IT_SaISB_EE in main.cpp.o
  "__ZN5boost15program_options16validation_error12get_templateB5cxx11ENS1_6kind_tE", referenced from:
      __ZN5boost15program_options10validators17get_single_stringIcEERKNSt7__cxx1112basic_stringIT_St11char_traitsIS5_ESaIS5_EEERKSt6vectorIS9_SaIS9_EEb in main.cpp.o
  "__ZN5boost15program_options19options_descriptionC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjj", referenced from:
      _main in main.cpp.o
  "__ZN5boost15program_options20invalid_option_valueC1ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE", referenced from:
      __ZN5boost15program_options8validateIicEEvRNS_3anyERKSt6vectorINSt7__cxx1112basic_stringIT0_St11char_traitsIS7_ESaIS7_EEESaISB_EEPT_l in main.cpp.o
  "__ZN5boost15program_options22error_with_option_nameC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_i", referenced from:
      __ZN5boost15program_options10validators17get_single_stringIcEERKNSt7__cxx1112basic_stringIT_St11char_traitsIS5_ESaIS5_EEERKSt6vectorIS9_SaIS9_EEb in main.cpp.o
  "__ZN5boost15program_options3argB5cxx11E", referenced from:
      __ZNK5boost15program_options11typed_valueIbcE4nameB5cxx11Ev in main.cpp.o
      __ZNK5boost15program_options11typed_valueINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEcE4nameEv in main.cpp.o
      __ZNK5boost15program_options11typed_valueIicE4nameB5cxx11Ev in main.cpp.o
  "__ZN5boost15program_options6detail7cmdline21set_additional_parserENS_9function1ISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_ERKSA_EE", referenced from:
      __ZN5boost15program_options25basic_command_line_parserIcE12extra_parserENS_9function1ISt4pairINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_ERKSA_EE in main.cpp.o
  "__ZN5boost15program_options6detail7cmdlineC2ERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE", referenced from:
      __ZN5boost15program_options25basic_command_line_parserIcEC1EiPKPKc in main.cpp.o
  "__ZN5boost15program_options8validateERNS_3anyERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEPS9_i", referenced from:
      __ZNK5boost15program_options11typed_valueINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEcE6xparseERNS_3anyERKSt6vectorIS7_SaIS7_EE in main.cpp.o
  "__ZN5boost15program_options8validateERNS_3anyERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEPbi", referenced from:
      __ZNK5boost15program_options11typed_valueIbcE6xparseERNS_3anyERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISB_EE in main.cpp.o
  "__ZN5boost15program_optionslsERSoRKNS0_19options_descriptionE", referenced from:
      _main in main.cpp.o
  "__ZNK5boost15program_options22abstract_variables_mapixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE", referenced from:
      _main in main.cpp.o
      __Z8read_csvN5boost15program_options13variables_mapEP8MapState in read_csv.cpp.o
  "__ZNK5boost15program_options22error_with_option_name23substitute_placeholdersERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE", referenced from:
      __ZTVN5boost10wrapexceptINS_15program_options20invalid_option_valueEEE in main.cpp.o
      __ZTVN5boost10wrapexceptINS_15program_options16validation_errorEEE in main.cpp.o
      __ZTVN5boost15program_options16validation_errorE in main.cpp.o
      __ZTVN5boost15program_options20invalid_option_valueE in main.cpp.o
  "__ZNK5boost15program_options29value_semantic_codecvt_helperIcE5parseERNS_3anyERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISB_EEb", referenced from:
      __ZTVN5boost15program_options11typed_valueINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEcEE in main.cpp.o
      __ZTVN5boost15program_options11typed_valueIicEE in main.cpp.o
      __ZTVN5boost15program_options11typed_valueIbcEE in main.cpp.o
ld: symbol(s) not found for architecture x86_64
collect2: error: ld returned 1 exit status

However, when running the cmake command, cmake notifies me that it has found boost and the required components:

-- Found Boost: /usr/local/lib/cmake/Boost-1.74.0/BoostConfig.cmake (found suitable version "1.74.0", minimum required is "1.40") found components: program_options

I'm using gcc and g++ version 10.2.0. I configure my CMake file using cmake -DCMAKE_CXX_COMPILER=g++-10 -DCMAKE_C_COMPILER=gcc-10.

I've tried my the following 2 options for linking, however, they both lead to the same error:

target_link_libraries(cartogram CGAL::CGAL Boost::program_options ${FFTW_LIBRARIES}) and target_link_libraries(cartogram CGAL::CGAL ${Boost_LIBRARIES} ${FFTW_LIBRARIES})

I've also tried including add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0) (edit: from Boost Linking problems) before my call to find boost (using: find_package(Boost 1.40 COMPONENTS program_options REQUIRED)).

On a side note, the exact same cmake file works perfectly find on Ubuntu, Linux!

How may I fix this error?

Edit: I'm not even entirely sure whether this is a linking error as when I don't include the boost library to be linked at all (since I believe program options can be used as a header only library), I still get the same errors!

Edit 2: This is the entirety of my CMake code:

# code for findFFTW
configure_file(downloadFindFFTW.cmake.in findFFTW-download/CMakeLists.txt)
execute_process(COMMAND ${CMAKE_COMMAND} -G "${CMAKE_GENERATOR}" .
        RESULT_VARIABLE result
        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/findFFTW-download )
if(result)
    message(FATAL_ERROR "CMake step for findFFTW failed: ${result}")
    else()
    message("CMake step for findFFTW completed (${result}).")
endif()
execute_process(COMMAND ${CMAKE_COMMAND} --build .
        RESULT_VARIABLE result
        WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/findFFTW-download )
if(result)
    message(FATAL_ERROR "Build step for findFFTW failed: ${result}")
endif()

set(findFFTW_DIR ${CMAKE_CURRENT_BINARY_DIR}/findFFTW-src)

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${findFFTW_DIR}")

# As per https://github.com/CGAL/cgal/wiki/How-to-use-CGAL-with-CMake-or-your-own-build-system
cmake_minimum_required(VERSION 3.1)
project(cartogram)

# set(PLATFORM_SPECIFIC_LIBS "-lpthread")
add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)
set(CMAKE_CXX_STANDARD 20)
set(THREADS_PREFER_PTHREAD_FLAG ON)
set(CMAKE_BUILD_TYPE Release)

find_package(CGAL)
find_package(Boost 1.40 COMPONENTS program_options REQUIRED)
find_package(FFTW)
find_package(Threads REQUIRED)

add_executable(cartogram main.cpp
              geo_div.cpp
                map_state.cpp
                read_csv.cpp
                rescale_map.cpp
                write_eps.cpp
                read_geojson.cpp
                fill_with_density.cpp
              blur_density.cpp
              flatten_density.cpp
                ft_real_2d.cpp)

# Boost::program_options ${Boost_LIBRARIES}
target_link_libraries(cartogram
                      CGAL::CGAL
                      ${Boost_LIBRARIES}
                      ${FFTW_LIBRARIES}
                      ${CMAKE_THREAD_LIBS_INIT})

Edit 3: This is what I get when I run cmake -DCMAKE_CXX_COMPILER=g++-10 -DCMAKE_C_COMPILER=gcc-10:

CMake Warning:
  No source or binary directory provided.  Both will be assumed to be the
  same as the current working directory, but note that this warning will
  become a fatal error in future CMake releases.


CMake Deprecation Warning at CMakeLists.txt:1 (cmake_minimum_required):
  Compatibility with CMake < 2.8.12 will be removed from a future version of
  CMake.

  Update the VERSION argument <min> value or use a ...<max> suffix to tell
  CMake that the project does not need compatibility with older versions.


CMake Warning at /usr/local/Cellar/cmake/3.19.2/share/cmake/Modules/Platform/Darwin-Initialize.cmake:303 (message):
  Ignoring CMAKE_OSX_SYSROOT value:

   /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX11.0.sdk

  because the directory does not exist.
Call Stack (most recent call first):
  /usr/local/Cellar/cmake/3.19.2/share/cmake/Modules/CMakeSystemSpecificInitialize.cmake:21 (include)
  CMakeLists.txt:3 (project)


-- Configuring done
-- Generating done
-- Build files have been written to: /Users/adityasinghania/Desktop/gastner/cartogram_cpp-master/cartogram_generator/findFFTW-download
CMake step for findFFTW completed (0).
[ 11%] Performing update step for 'findFFTW_download'
[ 22%] No patch step for 'findFFTW_download'
[ 33%] No configure step for 'findFFTW_download'
[ 44%] No build step for 'findFFTW_download'
[ 55%] No install step for 'findFFTW_download'
[ 66%] No test step for 'findFFTW_download'
[ 77%] Completed 'findFFTW_download'
[100%] Built target findFFTW_download
-- The C compiler identification is GNU 10.2.0
-- The CXX compiler identification is GNU 10.2.0
-- Checking whether C compiler has -isysroot
-- Checking whether C compiler has -isysroot - yes
-- Checking whether C compiler supports OSX deployment target flag
-- Checking whether C compiler supports OSX deployment target flag - yes
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /usr/local/bin/gcc-10 - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Checking whether CXX compiler has -isysroot
-- Checking whether CXX compiler has -isysroot - yes
-- Checking whether CXX compiler supports OSX deployment target flag
-- Checking whether CXX compiler supports OSX deployment target flag - yes
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /usr/local/bin/g++-10 - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Using header-only CGAL
-- Targetting Unix Makefiles
-- Using /usr/local/bin/g++-10 compiler.
-- DARWIN_VERSION=19
-- Mac Leopard detected
-- Found GMP: /usr/local/lib/libgmp.dylib  
-- Found MPFR: /usr/local/lib/libmpfr.dylib  
-- Found Boost: /usr/local/lib/cmake/Boost-1.74.0/BoostConfig.cmake (found suitable version "1.74.0", minimum required is "1.48")  
-- Boost include dirs: /usr/local/include
-- Boost libraries:    
-- Using gcc version 4 or later. Adding -frounding-math
-- Found Boost: /usr/local/lib/cmake/Boost-1.74.0/BoostConfig.cmake (found suitable version "1.74.0", minimum required is "1.40") found components: program_options 
-- Could NOT find PkgConfig (missing: PKG_CONFIG_EXECUTABLE) 
-- Found FFTW: /usr/local/include   
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Success
-- Found Threads: TRUE  
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/adityasinghania/Desktop/gastner/cartogram_cpp-master/cartogram_generator
adisidev
  • 162
  • 1
  • 15
  • 1
    "I've also tried including `add_compile_definitions(_GLIBCXX_USE_CXX11_ABI=0)` before my call to find boost" - Setting `_GLIBCXX_USE_CXX11_ABI` does NOT affect on searching Boost. This setting should affect on compiling of **your executable**. If the error message doesn't change after the setting _GLIBCXX_USE_CXX11_ABI, then probably you have specified it **wrongly**. We need to see more of your code. – Tsyvarev Dec 19 '20 at 09:50
  • shouldn't it be `add_compile_definitions(-D_GLIBCXX_USE_CXX11_ABI=0)` ? – StPiere Dec 19 '20 at 09:56
  • Which snippets of code may be helpful to include in my question so that you guys may help me @Tsyvarev? I also tried adding `-D` at the start of add_compile_definitions, however that led to the following error: `: error: macro names must be identifiers` – adisidev Dec 19 '20 at 10:13
  • 1
    "Which snippets of code may be helpful to include in my question so that you guys may help me" - The code you show now is normally sufficient. (For future questions please take a look into [mcve]). – Tsyvarev Dec 19 '20 at 10:18
  • 1
    Placing any command before `cmake_minimum_required`, as you do with `add_compile_definitions`, is usually wrong. Compiler and linker flags should normally be set after `project` call, when CMake already knows the compiler, the linker and their properties. – Tsyvarev Dec 19 '20 at 10:20
  • Thank you so much for your reply @Tsyvarev! I added the `add_compile_definitions` command after the `project` call! However, this lead to the same error again. Is there anything else I can try? I updated the question to reflect the new code as per your advice. For further information, I've also included what I get when I run `cmake -DCMAKE_CXX_COMPILER=g++-10 -DCMAKE_C_COMPILER=gcc-10`. – adisidev Dec 19 '20 at 11:25
  • 1
    The configuration log doesn't corresponds to your `CMakeLists.txt`. The message `Compatibility with CMake < 2.8.12 will be removed from a future version of CMake.` should not be issued for `VERSION 3.1` and `CMakeLists.txt:3 (project)` doesn't correspond to the line 2, where you have `project()` call. As for very first warning, it is better to perform **out-of-source** builds, where build directory differs from the source ones. (Because you have already performed in-source build, for make out-of-source ones you need to remove `CMakeCache.txt` from the source directory. – Tsyvarev Dec 19 '20 at 14:09
  • Thank you for your response @Tsyvarev! You've been extremely helpful and patient. I made sure that I am running the exact same CMake file. I understand that out-of-source builds are the norm, and I will change my code to do the same. However, I do believe that this would not create the error. The mismatch between the position of `project` may be because of the code for findFFTW which is there before my own code. I have updated my question to represent the same. Thank you so much, once again! – adisidev Dec 19 '20 at 14:59
  • 1
    By setting `set(CMAKE_CXX_FLAGS "-std=c++20 -pthread")` you drop out compiler flags which are set by CMake when it determines the compiler. And this could actually be a reason of weird inconsistences. It is better to not replace but **append** flags. Actually, both `-std=c++20` and `-pthread` has their own, preferred methods for being set. The former one is set via `CMAKE_CXX_STANDARD` variable: https://stackoverflow.com/questions/10851247/how-do-i-activate-c-11-in-cmake. The latter one is set via `find_package(Threads)`: https://stackoverflow.com/questions/1620918/cmake-and-libpthread. – Tsyvarev Dec 20 '20 at 11:16
  • Thank you so much for your help @Tsyvarev! I feel like in this short conversation I've learnt so much about the right way to do CMake! I'd love to know if you have any resources I could look into to learn more CMake. I changed the file as per your latest comment and updated my question as well. However, I unfortunately still get the same error. I also updated what I get after running cmake. What boggles my mind the most is that the CMake file works perfectly fine and compiles everything correctly on an Ubuntu machine! I really don't understand the errors. :( – adisidev Dec 20 '20 at 12:28

2 Answers2

5

The reason why you get these linking errors is probably that you try to link against Boost libraries which were compiled by AppleClang using g++. The standard library implementations of Clang and g++ are ABI-incompatible, i.e. you can't link against a Clang-compiled library using g++.

If you want to use g++ on MacOS, make sure the libraries that you use are also compiled with g++. This might be useful: https://andschwa.com/posts/boost-with-gcc-on-os-x/

yemre
  • 708
  • 3
  • 11
1

My favourite method is using vcpkg.

  1. Install vcpkg using this link
  2. Using the terminal navigate to vcpkg folder.
  3. Next, type ./vcpkg/vcpkg install boost. When this command is finished, run ./vcpkg/vcpkg install integrate; with this, a command on how to integerate boost with your cmake file will appear. Copy and paste it into a text editor for future reference
  4. Run your CMake file with the option -DCMAKE_TOOLCHAIN_FILE=$vcpkgRoot/scripts/buildsystems/vcpkg.cmake (the one given by the earlier command.) Alternatively, if you use visual studio code then running vcpkg integrate install will connect the library automatically to visual studio code.
evandrix
  • 6,041
  • 4
  • 27
  • 38
Motaz Hammouda
  • 122
  • 1
  • 9
  • Thank you for your reply! I'll just try it out and if it works, I'd be more than happy to reward the bounty to you! I believe you should also be able to include the following line in your CMakeLists.txt file if I'm not mistaken: `set(CMAKE_TOOLCHAIN_FILE=$vcpkgRoot\scripts\buildsystems\vcpkg.cmake)` – adisidev Dec 23 '20 at 16:19
  • After typing vcpkg integrate install, I got the cmake option I have to include. However, I tried ensuring the CMAKE_TOOLCHAIN_FILE` is set correctly, by setting it in the cmake file and even setting it as an option. However, none worked and infact `find_package` now throws an error stating that it could NOT find Boost. :( – adisidev Dec 23 '20 at 17:39
  • vcpkg integrate install only works with visual studio and/or visual studio code. If you are not using any of these pelase opt out to use the regular cmake options. How can one do that. 1. set(CMAKE_TOOLCHAIN_FILE=$vcpkgRoot\scripts\buildsystems\vcpkg.cmake) or -DCMAKE_TOOLCHAIN_FILE=$vcpkgRoot/scripts/buildsystems/vcpkg.cmake 2. Copy paste the command from the terminal. A word of warning though. vcpkg install 32 bits packages by default so if you are want to use 64 build system there is an extra step you will need to do namely vcpkg install boost:x64-osx – Motaz Hammouda Dec 24 '20 at 08:42
  • Unfortunately this may not work if vcpkg defaults to building boost:x64-osx with the AppleClang complier but then your primary target is compiled with g++ as directed by your cmake instructions. Vcpkg needs to be told how to use g++ as well, for compiling the dependencies you plan to use. – NKatUT Dec 07 '22 at 19:57