On macOS I'm trying to build my own small library based on fmt, while installing it with vcpkg and building the project with cmake.
CMakeLists.txt
cmake_minimum_required(VERSION 3.19.1)
set(CMAKE_TOOLCHAIN_FILE ~/vcpkg/scripts/buildsystems/vcpkg.cmake)
project(MYLIB)
set (CMAKE_CXX_STANDARD 14)
find_package(fmt REQUIRED)
include_directories(~/vcpkg/installed/x64-osx/include)
add_library(mylib mylib.cpp)
mylib.cpp
#include "mylib.h"
#include <fmt/core.h>
float add(float a, float b)
{
fmt::print("Hello MYLIB, world!\n");
return (a + b);
}
With the above I can build the static flavor of it. But it fails while trying to build the SHARED version with
add_library(mylib SHARED mylib.cpp)
which led to:
user#users-MacBook-Pro build % rm -Rf *
zsh: sure you want to delete all 4 files in /Users/user/mylib/build [yn]? y
user#users-MacBook-Pro build % cmake ..
-- The C compiler identification is AppleClang 12.0.0.12000032
-- The CXX compiler identification is AppleClang 12.0.0.12000032
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/user/mylib/build
user#users-MacBook-Pro build % make
Scanning dependencies of target mylib
[ 50%] Building CXX object CMakeFiles/mylib.dir/mylib.cpp.o
[100%] Linking CXX shared library libmylib.dylib
Undefined symbols for architecture x86_64:
"fmt::v8::vprint(fmt::v8::basic_string_view<char>, fmt::v8::basic_format_args<fmt::v8::basic_format_context<fmt::v8::appender, char> >)", referenced from:
add(float, float) in mylib.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]: *** [libmylib.dylib] Error 1
make[1]: *** [CMakeFiles/mylib.dir/all] Error 2
make: *** [all] Error 2
Related
Why does Cmake find the library but I can't include it?
I am trying to use the gsl library in C++ but I get gsl/gsl_sf_bessel.h: No such file or directory when I run cmake --build even though it says -- Found GSL: /usr/include (found version "2.7.1") in the terminal after running cmake ...
I am using Ubuntu 22.04
I installed gsl with sudo apt-get install libgsl-dev and it is in /usr/include.
I think it might be a problem with the compiler I am using but I'm not sure how to check.
My CMakeLists.txt file
cmake_minimum_required(VERSION 3.5.1)
project(mujoco_gym)
set(CMAKE_CXX_STANDARD 14)
# It prevents the decay to C++98 when the compiler does not support C++14
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# It disables the use of compiler-specific extensions
# e.g. -std=c++14 rather than -std=gnu++14
set(CMAKE_CXX_EXTENSIONS OFF)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
find_package(GSL REQUIRED)
link_libraries(GSL::gsl)
include_directories(${PROJECT_SOURCE_DIR})
file(GLOB SOURCE_FILES mujoco_gym.cpp)
add_executable(${CMAKE_PROJECT_NAME} ${SOURCE_FILES})
target_link_libraries (
${CMAKE_PROJECT_NAME}
${GSL_LIBRARIES}
)
My .cpp file.
#include<stdbool.h> //for bool
#include "stdlib.h"
#include "string.h"
#include <iostream>
#include <gsl/gsl_sf_bessel.h>
int main()
{
double x = 5.0;
std::cout << gsl_sf_bessel_j0(x);
return 0;
}
Cmake and build in the terminal
$ cmake ..
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /home/iii/miniconda3/envs/tf/bin/x86_64-conda-linux-gnu-cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /home/iii/miniconda3/envs/tf/bin/x86_64-conda-linux-gnu-c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found PkgConfig: /usr/bin/pkg-config (found version "0.29.2")
-- Found GSL: /usr/include (found version "2.7.1")
-- Configuring done
-- Generating done
-- Build files have been written to: /home/iii/.mujoco/mujoco210/sample/build
$ cmake --build . --config Release
[ 50%] Building CXX object CMakeFiles/mujoco_gym.dir/mujoco_gym.cpp.o
/home/iii/.mujoco/mujoco210/sample/mujoco_gym.cpp:21:10: fatal error: gsl/gsl_sf_bessel.h: No such file or directory
21 | #include <gsl/gsl_sf_bessel.h>
| ^~~~~~~~~~~~~~~~~~~~~
compilation terminated.
gmake[2]: *** [CMakeFiles/mujoco_gym.dir/build.make:76: CMakeFiles/mujoco_gym.dir/mujoco_gym.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/mujoco_gym.dir/all] Error 2
gmake: *** [Makefile:91: all] Error 2
$
I installed vcpkg on macOS and I'm trying to build a simple library that depends on fmt, which I installed with vcpkg.
mylib.h
float add(float a, float b);
mylib.cpp
#include "mylib.h"
#include <iostream>
#include <fmt/core.h>
float add(float a, float b)
{
fmt::print("Hello MYLIB, world!\n");
return (a + b);
}
CMakeLists.txt contents:
cmake_minimum_required(VERSION 3.19.1)
project(MYLIB)
find_package(fmt REQUIRED)
add_library(mylib mylib.cpp)
Then
user#users-MacBook-Pro build % cmake -B . -DCMAKE_TOOLCHAIN_FILE=~/vcpkg/scripts/buildsystems/vcpkg.cmake -S ..
-- The C compiler identification is AppleClang 12.0.0.12000032
-- The CXX compiler identification is AppleClang 12.0.0.12000032
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc - skipped
-- Detecting C compile features
-- Detecting C compile features - done
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ - skipped
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/user/mylib/build
user#users-MacBook-Pro build % make
Scanning dependencies of target mylib
[ 50%] Building CXX object CMakeFiles/mylib.dir/mylib.cpp.o
/Users/user/mylib/mylib.cpp:5:10: fatal error: 'fmt/core.h' file not found
#include <fmt/core.h>
^~~~~~~~~~~~
1 error generated.
make[2]: *** [CMakeFiles/mylib.dir/mylib.cpp.o] Error 1
make[1]: *** [CMakeFiles/mylib.dir/all] Error 2
make: *** [all] Error 2
What am I missing?
I tried the same on Windows and it works fine. On Windows though we run vcpkg integrate install which does not exist on macOS. Is this related to the problem?
Looks like it's necessary to
include_directories(~/vcpkg/installed/x64-osx/include)
You are using the variable CMAKE_TOOLCHAIN_FILE incorrectly. set(CMAKE_TOOLCHAIN_FILE ... in CMakeLists.txt has no effect. The variable should be set on the command line, see the manuals CMAKE_TOOLCHAIN_FILE, Using vcpkg with CMake
cmake .. -DCMAKE_TOOLCHAIN_FILE=~/vcpkg/scripts/buildsystems/vcpkg.cmake
The file CMakeLists.txt is also wrong, find_package(fmt REQUIRED) is missing, that should download and install fmt by invoking vcpkg install fmt under the hood.
After all you should link your project with the lib
target_link_libraries(MYLIB PRIVATE fmt::fmt)
I've been trying to compile a simple OpenMP program using AppleClang on Mac OS X 10.14.5 Mojave with the CLion IDE.
main.cpp:
#include <omp.h>
#include <iostream>
int main() {
std::cout << omp_get_max_threads() << std::endl;
return 1;
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.14)
project(OpenMPTest)
set(CMAKE_CXX_STANDARD 17)
add_executable(OpenMPTest main.cpp)
find_package(OpenMP)
if (OPENMP_FOUND)
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif()
CMake output:
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake -DCMAKE_BUILD_TYPE=Debug -G "CodeBlocks - Unix Makefiles" /Users/bully/CLionProjects/OpenMPTest
-- The C compiler identification is AppleClang 10.0.1.10010046
-- The CXX compiler identification is AppleClang 10.0.1.10010046
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc
-- Check for working C compiler: /Library/Developer/CommandLineTools/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++
-- Check for working CXX compiler: /Library/Developer/CommandLineTools/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Found OpenMP_C: -Xclang -fopenmp (found version "3.1")
-- Found OpenMP_CXX: -Xclang -fopenmp (found version "3.1")
-- Found OpenMP: TRUE (found version "3.1")
-- Configuring done
-- Generating done
-- Build files have been written to: /Users/bully/CLionProjects/OpenMPTest/cmake-build-debug
When I build the project, I receive a linker error:
====================[ Build | all | Debug ]=====================================
/Applications/CLion.app/Contents/bin/cmake/mac/bin/cmake --build /Users/bully/CLionProjects/OpenMPTest/cmake-build-debug --target all -- -j 2
Scanning dependencies of target OpenMPTest
[ 50%] Building CXX object CMakeFiles/OpenMPTest.dir/main.cpp.o
[100%] Linking CXX executable OpenMPTest
Undefined symbols for architecture x86_64:
"_omp_get_max_threads", referenced from:
_main 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]: *** [OpenMPTest] Error 1
make[1]: *** [CMakeFiles/OpenMPTest.dir/all] Error 2
make: *** [all] Error 2
How come this does not work? From the command line I can run clang++ main.cpp -lomp successfully after installing the library headers with open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg.
message(STATUS "Linker flags:" "${OpenMP_EXE_LINKER_FLAGS}") prints:
-- Linker flags:
If I replace the CMAKE_EXE_LINKER_FLAGS setter with set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -lomp") compilation with linking works. Why do I have to specify this manually? What's the preferred way of getting this to work in a platform-independent way? -fopenmp yields clang: error: unsupported option '-fopenmp'. gcc and MSVC on Linux and Windows respectively played nice with the CMake OpenMP configuration but Mac OS X does not.
As commented by Tsyvarev, the solution is to use the "updated" way of including OpenMP in CMake:
cmake_minimum_required(VERSION 3.14)
project(OpenMPTest)
set(CMAKE_CXX_STANDARD 17)
add_executable(OpenMPTest main.cpp)
find_package(OpenMP REQUIRED) # Find the package
target_link_libraries(${PROJECT_NAME} ${OpenMP_CXX_LIBRARIES}) # Link against it for C++
This compiled on Windows, Ubuntu and Mac OS X using their platform's default compilers respectively.
The accepted answer here is not recommended even though it also has the most upvotes.
I fruitlessly tried to distribute a basic Qt console application by using CMake.
Let's consider these 2 files:
main.cpp
#include <QDebug>
int main(int argc, char *argv[])
{
qDebug() << "Hello Wolrd!";
return 0;
}
CMakeLists.txt
cmake_minimum_required(VERSION 2.8.12)
project(HelloWorld)
set(CMAKE_AUTOMOC ON)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5Widgets REQUIRED)
add_executable(${PROJECT_NAME} main.cpp)
qt5_use_modules(${PROJECT_NAME} Widgets)
Next I compile the main.cpp file doing:
$ cmake .
-- The C compiler identification is AppleClang 10.0.1.10010046
-- The CXX compiler identification is AppleClang 10.0.1.10010046
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc
-- Check for working C compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++
-- Check for working CXX compiler: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Configuring done
-- Generating done
-- Build files have been written to: /path/to/HelloWorld
$ make
Scanning dependencies of target HelloWorld_autogen
[ 25%] Automatic MOC for target HelloWorld
[ 25%] Built target HelloWorld_autogen
Scanning dependencies of target HelloWorld
[ 50%] Building CXX object CMakeFiles/HelloWorld.dir/HelloWorld_autogen/mocs_compilation.cpp.o
[ 75%] Building CXX object CMakeFiles/HelloWorld.dir/main.cpp.o
[100%] Linking CXX executable HelloWorld
[100%] Built target HelloWorld
And I get a HelloWorld binary file.
The problem comes when I try to execute the latter file on another computer which don't have Qt installed. I get this bellow error:
dyld: Library not loaded: #rpath/QtWidgets.framework/Versions/5/QtWidgets
Referenced from: /path/to/HelloWorld/./HelloWorld
Reason: image not found
./test.sh: line 4: 68737 Abort trap: 6 ./HelloWorld
What is missing to make this working as a standalone application?
Environment:
MacOs Mojave (10.14.4)
Qt 5.10.1
The easiest approach is to link Qt statically. Check out the documentation about deploying for macOS.
Be aware that Qt is licensed under the LGPL, which may have implications for static linking. Check out this FAQ for details.
You could also use bundles and frameworks, but I'm not sure how well that works with console applications.
I am trying to compile the conv-net library in my mac osx yosemite with xcode. I even set the flags to libstdc++ still it is not linking properly.
i still get undefined symbols for architecture x86_64.
any help much appreciated.
sh-3.2# ./compile.sh
Building conv-net library
-- The C compiler identification is AppleClang 6.0.0.6000056
-- The CXX compiler identification is AppleClang 6.0.0.6000056
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Configuring done
WARNING: Target "testimg" requests linking to directory "/usr/local/Cellar/opencv/2.4.9/lib". Targets may link only to libraries. CMake is dropping the item.
WARNING: Target "testimg" requests linking to directory "/usr/local/Cellar/opencv/2.4.9/lib". Targets may link only to libraries. CMake is dropping the item.
WARNING: Target "testmnist" requests linking to directory "/usr/local/Cellar/opencv/2.4.9/lib". Targets may link only to libraries. CMake is dropping the item.
WARNING: Target "testmnist" requests linking to directory "/usr/local/Cellar/opencv/2.4.9/lib". Targets may link only to libraries. CMake is dropping the item.
-- Generating done
-- Build files have been written to: /var/tmp/conv-net-0.1-prealpha_buildroot
Scanning dependencies of target cvconvnet
[ 11%] Building CXX object CMakeFiles/cvconvnet.dir/src/cvsubsamplingplane.cpp.o
[ 22%] Building CXX object CMakeFiles/cvconvnet.dir/src/cvconvolutionplane.cpp.o
[ 33%] Building CXX object CMakeFiles/cvconvnet.dir/src/cvgenericplane.cpp.o
[ 44%] Building CXX object CMakeFiles/cvconvnet.dir/src/cvsourceplane.cpp.o
[ 55%] Building CXX object CMakeFiles/cvconvnet.dir/src/cvrbfplane.cpp.o
[ 66%] Building CXX object CMakeFiles/cvconvnet.dir/src/cvmaxplane.cpp.o
[ 77%] Building CXX object CMakeFiles/cvconvnet.dir/src/cvconvnetparser.cpp.o
[ 88%] Building CXX object CMakeFiles/cvconvnet.dir/src/cvfastsigmoid.cpp.o
[100%] Building CXX object CMakeFiles/cvconvnet.dir/src/cvconvnet.cpp.o
/Users/prabhubalakrishnan/Desktop/conv-net/src/cvconvnet.cpp:169:1: warning: control reaches end of non-void function [-Wreturn-type]
}
^
1 warning generated.
Linking CXX static library libcvconvnet.a
[100%] Built target cvconvnet
Scanning dependencies of target testimg
Linking CXX executable testimg
Undefined symbols for architecture x86_64:
"_main", referenced from:
implicit entry/start for main executable
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]: *** [testimg] Error 1
make[1]: *** [CMakeFiles/testimg.dir/all] Error 2
make: *** [all] Error 2
cp: testimg: No such file or directory
cp: testmnist: No such file or directory
ls: illegal option -- I
usage: ls [-ABCFGHLOPRSTUWabcdefghiklmnopqrstuwx1] [file ...]
This is my make file
cmake_minimum_required(VERSION 3.0)
PROJECT (CvConvolutionalNet)
set (CMAKE_CXX_FLAGS " -stdlib=libstdc++")
# IF() ENDIF() statements
SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true)
# Specify build-type as Debug if not specified already
IF (NOT CMAKE_BUILD_TYPE)
SET(CMAKE_BUILD_TYPE Debug)
ENDIF ()
# Produce verbose makefiles
# SET(CMAKE_VERBOSE_MAKEFILE ON)
# Sources for library
SET(CVCONVNET_SRCS
src/cvsubsamplingplane.cpp
src/cvconvolutionplane.cpp
src/cvgenericplane.cpp
src/cvsourceplane.cpp
src/cvrbfplane.cpp
src/cvmaxplane.cpp
src/cvconvnetparser.cpp
src/cvfastsigmoid.cpp
src/cvconvnet.cpp
)
# Sources for test files
SET(TESTIMG_SRCS tst/)
SET(TESTMNIST_SRCS tst/)
set (CV_H /usr/local/Cellar/opencv/2.4.9/include/opencv)
set (HIGHGUI_H src/include )
set (LIBCV /usr/local/Cellar/opencv/2.4.9/lib )
set (LIBHIGHGUI /usr/local/Cellar/opencv/2.4.9/lib )
# Here are common paths (in addition to default paths)
SET (INCLUDE_SEARCH_PATH
/usr/local/include /usr/include /usr/include/opencv/
/usr/include/opencv/ c:/program\ files/opencv/include
)
SET (LIBRARY_SEARCH_PATH
/usr/local/lib /usr/lib c:/program\ files/opencv/lib c:/windows/system32
)
# Find OpenCV and Expat
FIND_PATH(CV_H NAMES cv.h PATHS ${INCLUDE_SEARCH_PATH} )
FIND_PATH(HIGHGUI_H NAMES highgui.h PATHS ${INCLUDE_SEARCH_PATH} )
FIND_PATH(EXPAT_H NAMES expat.h PATHS ${INCLUDE_SEARCH_PATH} )
FIND_LIBRARY(LIBCV NAMES cv PATHS ${LIBRARY_SEARCH_PATH} )
FIND_LIBRARY(LIBHIGHGUI NAMES highgui PATHS ${LIBRARY_SEARCH_PATH} )
FIND_LIBRARY(LIBEXPAT NAMES expat PATHS ${LIBRARY_SEARCH_PATH} )
INCLUDE_DIRECTORIES(include/ ${CV_H} ${HIGHGUI_H} ${EXPAT_H})
# Here is out library
ADD_LIBRARY(cvconvnet STATIC ${CVCONVNET_SRCS})
# Here are our test programs
ADD_EXECUTABLE(testimg ${TESTIMG_SRCS})
ADD_EXECUTABLE(testmnist ${TESTMNIST_SRCS})
# Compiler options are different for Release and Debug
IF (CMAKE_BUILD_TYPE MATCHES Release)
# Highly optimized + cancel all assert()s
ADD_DEFINITIONS(-O3 -DNDEBUG)
ELSE ()
# Include debug info, profiling info, some text output
ADD_DEFINITIONS(-O -pg -g -DDEBUG)
# Set profiling for linker too
SET_TARGET_PROPERTIES(testmnist PROPERTIES LINK_FLAGS "-pg")
ENDIF ()
# We should link our test programs to libraries
TARGET_LINK_LIBRARIES(testimg cvconvnet ${LIBCV} ${LIBHIGHGUI} ${LIBEXPAT})
TARGET_LINK_LIBRARIES(testmnist cvconvnet ${LIBCV} ${LIBHIGHGUI} ${LIBEXPAT})
I fixed it by adding -c option in the compiler flags and it worked !!!!
The add_executable command takes a target name and a list of source files to be compiled. When you are creating a target for testimg you are passing it directory.
Use file(GLOB ...) command to gather all source files from directory into a list variable and pass it to add_executable call.