I am developing an own open source programming language interpreter project and I can make silly mistakes as I am not sophisticated in Cmake and I am trying Travis CI for the first time. My project compiles on my PC (running Ubuntu 16.04LTS, GCC 8.1 and Cmake 3.12.0-rc2) from bash terminal by executing scripts/build_all.sh and tests are executed by scripts/run_tests.sh.
Build script creates a cmake-build-debug directory, runs cmake and than builds and executes simple cmake-build-debug/lexertl_gen/lexert_gen.out program to generate a header file in my include folder for the main project. After that it builds the main project alongside with it's tests all under compiler option std=gnu++2a.
Here are all my CMakeLists.txt (the problem is described bellow):
Root CMakeLists.txt
cmake_minimum_required(VERSION 3.9.0)
set(INCLUDE_ROOT "/usr/local/include")
set(BOOST_ROOT "${INCLUDE_ROOT}/boost_1_67_0")
set(LEXERTL_ROOT "${INCLUDE_ROOT}/lexertl")
set(GTEST_ROOT "${INCLUDE_ROOT}/googletest")
set(CMAKE_CXX_FLAGS "-g -std=gnu++2a -Werror \
-Wno-error=variadic-macros \
-Werror=implicit-fallthrough")
file(GLOB SOURCES "src/*.cpp")
include_directories(include ${BOOST_ROOT} ${LEXERTL_ROOT} ${GTEST_ROOT})
add_library(calamity_core ${SOURCES})
project(lexer.out)
add_executable(${PROJECT_NAME} main_lexer.cpp)
target_link_libraries(${PROJECT_NAME} m calamity_core)
project(parser.out)
add_executable(${PROJECT_NAME} main_parser.cpp)
target_link_libraries(${PROJECT_NAME} m calamity_core)
project(tests.out)
add_subdirectory(tests)
project(lexertl_gen.out)
add_subdirectory(lexertl_gen)
tests/CMakeLists.txt
cmake_minimum_required(VERSION 3.9.0)
set(CMAKE_CXX_FLAGS "-g -std=gnu++2a -Werror \
-Wno-error=variadic-macros \
-Werror=implicit-fallthrough")
add_subdirectory(/usr/local/include/googletest ../gtets-build)
add_executable(${PROJECT_NAME} tests.cpp)
target_link_libraries(${PROJECT_NAME} gtest gtest_main gmock calamity_core)
lexertl_gen/CMakeLists.txt
cmake_minimum_required(VERSION 3.9.0)
set(CMAKE_CXX_FLAGS "-g -std=gnu++2a -Werror \
-Wno-error=variadic-macros \
-Werror=implicit-fallthrough")
set(SOURCES ../src/token.cpp
../src/var_substring.cpp
../src/cui.cpp
../src/message_exception.cpp)
add_executable(lexertl_gen.out main_lexertl_gen.cpp ${SOURCES})
Ultimately, I decided to add Travis CI to my project. I wrote a bootstrap.sh script to install and configure all dependencies (I also install GCC 8.1, because default GCC 4.8.4 installed on Travis CI server doesn't support gnu++2a). This script works well, but when it comes to running scripts/build_all.sh on Travis CI server GCC fails to set gnu++2a for compiling my main project with tests, it complains about using inline variables, std::is_integral and other modern C++ stuff, explicitly mentioning that those features are supported under std=c++17 or std=gnu++17. Here is the link to my latest unsuccessful build on Travis CI.
I don't get it, as I updated GCC and my first simple code generator program runs well (though if I remove set(CMAKE_CXX_FLAGS ...) from tests/CMakeLists.txt this program compiles on my PC but doesn't compile on Travis CI server either). What's wrong am I doing here? Is it because of the Cmake 3.9 which Travis uses?
My .travis.yml configuration file:
language: cpp
sudo: required
dist: trusty
compiler:
- g++
os:
- linux
script:
- ./bootstrap.sh; cd scripts; ./build_all.sh; ./run_tests.sh
env:
global:
- LANG="en_US.UTF-8"
matrix:
include:
- os: linux
addons:
apt:
compiler: gcc
sources:
- ubuntu-toolchain-r-test
packages:
- g++-8
env: COMPILER=g++-8
Link to my project on GitHub. (sorry for empty README.md)
Well I've finally solved a problem by making CMAKE_CXX_FLAGS a cache variable:
set(CMAKE_CXX_FLAGS "-g -std=gnu++2a -Werror \
-Wno-error=variadic-macros \
-Werror=implicit-fallthrough"
CACHE STRING "compiler flags")
Though I don't think it is a beautiful solution and I still can't understand why it compiled on my PC but not on Travis CI
Related
Works fine building on Linux and Windows.
But in macos I get:
/usr/local/bin/g++-11 -isysroot /Applications/Xcode_13.4.1.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX12.3.sdk -Wl,-search_paths_first -Wl,-headerpad_max_install_names CMakeFiles/Calculator_Test.dir/src/speedtest.cpp.o CMakeFiles/Calculator_Test.dir/src/tests.cpp.o -o Calculator_Test ../libCalculator.a ../vcpkg_installed/x64-osx/debug/lib/libCatch2d.a ../vcpkg_installed/x64-osx/debug/lib/manual-link/libCatch2Maind.a ../vcpkg_installed/x64-osx/debug/lib/libCatch2d.a
Undefined symbols for architecture x86_64:
"__ZN5Catch24translateActiveExceptionB5cxx11Ev", referenced from:
__ZN5Catch9Benchmark9Benchmark3runINSt6chrono3_V212steady_clockEEEvv in speedtest.cpp.o
"__ZN5Catch9Benchmark6Detail15analyse_samplesEdjN9__gnu_cxx17__normal_iteratorIPdSt6vectorIdSaIdEEEES8_", referenced from:
__ZN5Catch9Benchmark6Detail7analyseINSt6chrono8durationIdSt5ratioILl1ELl1000000000EEEEN9__gnu_cxx17__normal_iteratorIPS7_St6vectorIS7_SaIS7_EEEEEENS0_14SampleAnalysisIT_EERKNS_7IConfigENS0_11EnvironmentISG_EET0_SN_ in speedtest.cpp.o
Running the following works fine and without error:
cmake --preset=${{ matrix.preset }} -B build -DCalculator_Test=1 -DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11 -DCMAKE_VERBOSE_MAKEFILE=1
"preset" is just setting the CMAKE_TOOLCHAIN_FILE to the one provided by vcpkg and the cmake generator to "Unix Makefiles"
From CMakeLists.txt used:
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
...
find_package(Catch2 CONFIG REQUIRED)
target_link_libraries(Calculator_Test
PRIVATE
Calculator
Catch2::Catch2 Catch2::Catch2WithMain
)
But when compiling is when it fails
cmake --build build
My question is why does it fail and how to fix it?
Is it C++20 that is the problem or is it CMake, vcpkg or something I must do on macos. I'm no macos expert :(
Solved the problem by setting the environmental variables to the correct compiler before setting up vcpkg.
In the github actions yml file:
- name: Set C++/C compiler on macOs
shell: bash
run: echo "CC=gcc-11" >> $GITHUB_ENV; echo "CXX=g++-11" >> $GITHUB_ENV; cat "$GITHUB_ENV"
if: runner.os == 'macOs'
The build step (without specifying the c/c++ compiler):
cmake --preset=${{ matrix.preset }} -B build -DCalculator_Test=1 -DCMAKE_VERBOSE_MAKEFILE=1
My assumptions is that the linking of the dependency binaries failed earlier due to being compiled with a different compiler than the application itself.
I'm on a linux machine, trying to build a project using cmake that does out of source builds. For code coverage, I looked into gcov and followed a simple tutorial that generate appropriate files for a sample helloWorld.cpp program. The only requirement were to compile with -fprofile-arcs -ftest-coverage flags & link with -lgcov flag, which can be done altogether with -coverage flag.
Now here comes the tricky part. I have a CMakeLists.txt wit contents as shown below:
cmake_minimum_required (VERSION 2.8)
project (SomeName)
SET(GCC_COVERAGE_COMPILE_FLAGS "-g -O0 -coverage -fprofile-arcs -ftest-coverage")
SET(GCC_COVERAGE_LINK_FLAGS "-coverage -lgcov")
SET( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )
SET( CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}" )
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
include_directories(include)
set(CATCH_HEADER_PATH ${PROJECT_SOURCE_DIR}/test/catch.hpp)
add_executable(runTest ${PROJECT_SOURCE_DIR}/test/test.cpp ${CATCH_HEADER_PATH})
So I've included appropriate compile time flags as well as linker flags too and appended them correctly. Another thing to note is set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin) line which says that executables will be generated inside bin directory.
Now everything works as intended except that coverage files aren't generated properly. I follow these steps :
mkdir build && cd build
cmake ..
make -j4
./bin/runTest
and no other file is generated inside bin folder. However on more inspection I found out that there is another location build/CMakeFiles/runTest.dir/test where test.cpp.o resides initially and after the final step ./bin/runTest, two new files - test.cpp.gcda & test.cpp.gcno are generated.
I've already tried copying test/test.cpp to build/CMakeFiles/runTest.dir/test and running gcov test.cpp but it fails stating - test.gcno:cannot open notes file
A mismatch in gcov and gcc version was making this happen. gcc symlink /usr/bin/gcc was set to newest gcc, same for g++ but gcov in $PATH was still pointing to older version of gcov.
I'm trying to build my C++ project which includes Pjsip library on Centos 7 using CMake and Qt IDE without success. I built Pjsip for Centos using steps defined in readme.txt :
./configure
make dep && make
After that configured CMakeLists.txt with this configuration:
cmake_minimum_required(VERSION 3.0)
set(CMAKE_INSTALL_PREFIX /opt)
project(hello-pjsip)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -DSERVER_REMOTE_LOGGING -ggdb -Wno-unused-local-typedefs")
# Set the compilers as the default GCC for Centos 7 doesn't support all C++11 features
set(CMAKE_CXX_COMPILER /opt/rh/devtoolset-7/root/bin/g++)
set(CMAKE_C_COMPILER /opt/rh/devtoolset-7/root/bin/gcc)
# PJ library
include_directories(~/pjproject/pjlib/include)
link_directories(~/pjproject/pjlib/lib)
include_directories(~/pjproject/pjlib-util/include)
link_directories(~/pjproject/pjlib-util/lib)
include_directories(~/pjproject/pjnath/include)
include_directories(~/pjproject/pjnath/src)
link_directories(~/pjproject/pjnath/lib)
# Source files
set (SOURCE_FILES
main.h
main.cpp
)
# Library files
set (LIBRARY_FILES
pj-x86_64-unknown-linux-gnu
pjnath-x86_64-unknown-linux-gnu
pjlib-util-x86_64-unknown-linux-gnu
)
add_executable(hello-pjsip ${SOURCE_FILES})
target_link_libraries(hello-pjsip ${LIBRARY_FILES})
After running build received these errors:
I tried to recompile pjsip library with different options but no success, same errors every time. Could someone help me?
PJ had bug, solved 5 months ago. This solved problem:
https://trac.pjsip.org/repos/changeset/5599
I am trying to build my CMake project I was last working on a few months ago, but I get the following error message:
make[3]: *** No rule to make target `/usr/lib/libboost_unit_test_framework-mt.so', needed by `test/baumwelchtests'. Stop.
Indeed, this file does not exist in /usr/lib, there is only libboost_unit_test_framework.so. What is the difference between normal version and the -mt version? I am pretty sure the -mt version was removed after one of the recent system upgrades (I am running Debian Testing, so there were quite a few changes after the latest stable release). How can I get my stuff to compile?
My CMakeLists.txt looks like this:
# Include subdirectories for headers
find_package( Boost REQUIRED COMPONENTS unit_test_framework regex)
include_directories(${BaumWelch_SOURCE_DIR}/../../grzesLib/src
${BaumWelch_SOURCE_DIR}/src
${Boost_INCLUDE_DIRS})
if(CMAKE_COMPILER_IS_GNUCXX)
add_definitions(-g -std=c++11 -Wall -Werror -Wextra -pedantic -Wuninitialized)
endif()
# Create the unit tests executable
add_executable(
baumwelchtests stockestimationtests.cpp forecasttest.cpp lagstest.cpp hiddenmarkovmodeltest.cpp stateindextest.cpp baumiterationtest.cpp baumwelchtest.cpp sampleparameters.cpp sdetest.cpp hmmgenerator.h
# Key includes for setting up Boost.Test
testrunner.cpp
# Just for handy reference
exampletests.cpp
)
# Link the libraries
target_link_libraries( baumwelchtests ${Boost_LIBRARIES} baumwelchlib grzeslib)
-mt stands for mutlithreaded.
You can force CMake to link against regular boost libraries by setting set(Boost_USE_MULTITHREADED OFF)
But most likely you just need to install libboost-test-dev
I've compiled a C++ static library by using CMake as my building tool and I want to link it to my iOS app.
I created a simple 'Empty' application in Xcode and linked my library called libengine.a to it.
I tried to compile my iOS project and the linker gave me this warning:
ignoring file /Users/.../build/engine/libengine.a,
file was built for archive which is not the architecture being linked (i386):
/Users/.../build/engine/libengine.a
As I understand it, I need to compile my library for ARM processors. The problem is I don't know how.
I think CMake really lacks good tutorials.
Anyways, my CMake scripts are attached below.
Any help would be greatly appreciated.
Thanks, Tal.
Here is my main CMake script:
cmake_minimum_required(VERSION 2.8)
project(movie-night)
if (DEFINED PLATFORM)
include(toolchains/ios.cmake)
endif()
add_definitions(-Wall)
set(DEBUG)
if (DEFINED DEBUG)
add_definitions(-g)
endif()
if (DEFINED RELEASE)
add_definitions(-O3)
endif()
add_subdirectory(engine)
add_subdirectory(ui)
add_subdirectory(test)
Here is my toolchains/ios.cmake file:
set(CMAKE_SYSTEM_NAME Darwin)
set(CMAKE_SYSTEM_PROCESSOR arm)
Just use this toolchain file: http://code.google.com/p/ios-cmake/ and use it as
cmake -DCMAKE_TOOLCHAIN_FILE=path_to_your_toolchain_file
Then, in CMakeLists.txt:
SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -arch armv7")
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -arch armv7")
By following cmake-toolchains documentation I did like below:
cmake -G Xcode -B build \
-DCMAKE_SYSTEM_NAME=iOS \
-DCMAKE_Swift_COMPILER_FORCED=true \
-DCMAKE_OSX_DEPLOYMENT_TARGET=11.0
Note: That assignment CMAKE_OSX_DEPLOYMENT_TARGET=11.0 is not a mistake when targeting iOS.
I've been using an updated version of the iOS CMake toolchain for quite a while: https://github.com/leetal/ios-cmake
This creates an Xcode project which you can drag into an existing iOS project if necessary.
I wrote a blog post with more details: https://blog.tomtasche.at/2019/05/how-to-include-cmake-project-in-xcode.html
There is a second version of iOS.cmake located at:
https://ceres-solver.googlesource.com
Note: You may find that both versions of iOS.cmake will only build x86 versions of your project. CMake now sets CMAKE_OSX_SYSROOT to the (latest) Mac OS X SDK available on your system. You can fix this by modifying your copy of iOS.cmake to always set CMAKE_OSX_SYSROOT. You can do this by commenting out a couple of lines your copy of iOS.cmake:
# -- Under CMake 3.4.2, CMAKE_OSX_SYSROOT is automatically defined to point to the latest Mac OS X SDK. --
# -- So, the iOS SDK is never found. Grab the correct CMAKE_OS_SYSROOT and ignore any prior setting. --
# If user did not specify the SDK root to use, then query xcodebuild for it.
# if (NOT CMAKE_OSX_SYSROOT)
execute_process(COMMAND xcodebuild -version -sdk ${XCODE_IOS_PLATFORM} Path
OUTPUT_VARIABLE CMAKE_OSX_SYSROOT
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
message (STATUS "Using SDK: ${CMAKE_OSX_SYSROOT} for platform: ${IOS_PLATFORM}")
message (STATUS "be sure the previous line points to the correct SDK")
# endif ( )