From f80d8386a2300dc93562a5c3b320dc3b35a7a056 Mon Sep 17 00:00:00 2001 From: Kevin Broadey Date: Mon, 21 Dec 2020 00:31:03 +0000 Subject: [PATCH] KMB: pass top-level project compiler to external project Running "brew install gcc" installs gcc-10 and g++-10 in /usr/local/bin, leaving the XCode CLT gcc and g++ commands in /usr/bin. This results in "cmake .." in the build directory using the old version of the compiler. If instead we run "CC=gcc-10 CXX=g++-10 cmake .." or "cmake -DCMAKE_C_COMPILER=gcc-10 -DCMAKE_CXX_COMPILER=g++-10 .." then the top-level project picks up the new compiler, but when gtest is downloaded and configured by the "make" command, it picks up the old compiler as it uses the default "cc" and "c++" compiler commands. This results in the TextExample link phase failing with undefined symbols because the two compilers use different name-mangling on C++ function names. We can work around the problem by running "CC=gcc-10 CXX=g++-10 make", but this is nasty. The gtest makefiles ought to be generated correctly in the first place. This is achieved by passing the compiler name and flags from the top-level project in the ExternalProject_Add() call for gtest. This technique will have wider application when multiple build directories are generated for a top-level project, supporting different cross-compiler targets. In this case, external projects will need to be compiled with the correct compiler and flags, and working around the problem in the build command won't be practical. Also worth noting that "make" runs the XCode CLT command from /usr/bin. If "brew install make" is used then the command has to be run as "gmake" to get the version in /usr/local/bin. Alternatively, the PATH can be overridden to put the homebrew version at the front using "export PATH=$(brew --prefix make)/libexec/gnubin:$PATH" in the ~/.bash_profile file or similar. --- test/CMakeLists.txt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 40b0b39..ccc85bb 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -6,6 +6,11 @@ ExternalProject_Add(gtest URL https://github.com/google/googletest/archive/release-1.10.0.zip PREFIX ${CMAKE_CURRENT_BINARY_DIR}/gtest INSTALL_COMMAND "" + + # pass the super-project compiler and flags to the external project to avoid + # issues with name-mangling - thanks to https://stackoverflow.com/a/41916106/232452 + CMAKE_ARGS -DCMAKE_C_COMPILER=${CMAKE_C_COMPILER} -DCMAKE_C_FLAGS=${CMAKE_C_FLAGS} + -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} ) ExternalProject_Get_Property(gtest source_dir binary_dir) @@ -31,4 +36,4 @@ add_dependencies(libgmock gtest) include_directories(${source_dir}/googlemock/include) # Then include test directories -add_subdirectory(TestExample) \ No newline at end of file +add_subdirectory(TestExample)