Setting up stdlib path while compiling with mingw on linux - c++

I am trying to build my c++ CMake project on linux with mingw. CMakeLists.txt consists of (for understanding):
Setting up project info:
project(<project name> LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
Setting up TRY_COMPILE target type:
set(CMAKE_TRY_COMPILE_TARGET_TYPE "STATIC_LIBRARY")
Setting up boost:
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
find_package(Boost COMPONENTS system program_options REQUIRED)
Including subdirectories in which there is nothing about mingw:
add_subdirectory(<some_subdirectory>)
...
At the time of build process I see the following compilation command in the log:
/usr/bin/x86_64-w64-mingw32-g++ -I/usr/include -I<user include 1> -I<user include 2> -O3 -DNDEBUG -std=gnu++20 -MD -MT CMakeFiles/common.dir/<source>.cpp.o -MF <source>.cpp.o.d -o <source>.cpp.o -c <project path>/<source>.cpp
After that goes a compiler error message with the following beginning:
[build] In file included from /usr/x86_64-w64-mingw32/include/c++/12.2.0/cstdint:41,
[build] from /usr/x86_64-w64-mingw32/include/c++/12.2.0/bits/char_traits.h:731,
[build] from /usr/x86_64-w64-mingw32/include/c++/12.2.0/ios:40,
[build] from /usr/x86_64-w64-mingw32/include/c++/12.2.0/ostream:38,
[build] from <project path>/<source>.hpp:5,
[build] from <project path>/<source>.cpp:1:
[build] /usr/include/stdint.h:90:33: error: conflicting declaration «typedef long unsigned int uintptr_t»
[build] 90 | typedef unsigned long int uintptr_t;
[build] | ^~~~~~~~~
...
According to the internet this error message is connected with the different mingw standard library implementation.
I guess in a compile command there should somehow be -I/usr/x86_64-w64-mingw32/include on a place of -I/usr/include in a compilation command. If I am right there, the question is "How to change standard include directory for mingw build spicifically?". If I am not right there, then how to solve the problem with project building?
PS: The project builds using both clang++ and g++.

You probably need a toolchain file for your cross-compiler.
But I'd suggest using quasi-msys2, which takes care of this, and also gives you access to prebuilt libraries for MinGW (Boost in your case).
Install dependencies (this assumes Ubuntu, for other distributions adjust as needed)
# Install Clang and LLD
bash -c "$(wget -O - https://apt.llvm.org/llvm.sh)"
# Install other dependencies
sudo apt install make wget tar zstd gpg wine
Install and run quasi-msys2:
git clone https://github.com/holyblackcat/quasi-msys2
cd quasi-msys2/
make install _gcc _boost
env/shell.sh
cd ..
Now build your repo:
git clone https://github.com/gogagum/archiever
cd archiever/
git checkout dev
git submodule update --init --recursive
cmake -B build/
cmake --build build/ -j4
I tried running the test app too:
cd build/numerical/
./numerical_encoder.exe --input-file Makefile # This uses Wine automatically

Related

Problem building C++ binary using vcpkg and cmake in Github action macos-12

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.

C++ Cmake doesn't set compiler language standard on Travis CI server

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

gtest installed with conan: undefined reference to `testing::internal::GetBoolAssertionFailureMessage`

I use cmake to build my project and conan to install Google Test as dependency:
conanfile.txt
[requires]
gtest/1.7.0#lasote/stable
[generators]
cmake
[imports]
bin, *.dll -> ./build/bin
lib, *.dylib* -> ./build/bin
CMakeLists.txt
PROJECT(MyTestingExample)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
INCLUDE(conanbuildinfo.cmake)
CONAN_BASIC_SETUP()
ADD_EXECUTABLE(my_test test/my_test.cpp)
TARGET_LINK_LIBRARIES(my_test ${CONAN_LIBS})
test/my_test.cpp
#include <gtest/gtest.h>
#include <string>
TEST(MyTest, foobar) {
std::string foo("foobar");
std::string bar("foobar");
ASSERT_STREQ(foo.c_str(), bar.c_str()); // working
EXPECT_FALSE(false); // error
}
Build
$ conan install --build=missing
$ mkdir build && cd build
$ cmake .. && cmake --build .
I can use ASSERT_STREQ, but if I use EXPECT_FALSE I get an unexpected error:
my_test.cpp:(.text+0x1e1): undefined reference to `testing::internal::GetBoolAssertionFailureMessage[abi:cxx11](testing::AssertionResult const&, char const*, char const*, char const*)'
collect2: error: ld returned 1 exit status
What's wrong with my configuration?
The issue is that you are installing conan dependencies using the default settings (which is build type Release):
$ conan install --build=missing
# equivalent to
$ conan install -s build_type=Release ... --build=missing
The default settings can be seen in your conan.conf file
Then, you are using cmake in a nix system with the default build type which is Debug, which is a single-conf environment (opposed to multi-configuration Debug/Release environments, as Visual Studio), so when you are doing:
$ cmake .. && cmake --build .
# equivalent to
$ cmake .. -DCMAKE_BUILD_TYPE=Debug && cmake --build .
The incompatibility of Debug/Release build leads to that unresolved issue. So the solution would be to use the same build type that matches your installed dependencies:
$ cmake .. -DCMAKE_BUILD_TYPE=Release && cmake --build .
If using multi-configuration environments like Visual Studio, the correct way would be:
$ cmake .. && cmake --build . --config Release
On my side, I get this issue because being on Redhat 7 then with an old libstdc++.
Too old for conan default packages binaries/libraries.
I have fixed that by rebuilding gtest with '--build gtest' arg.

Cmake:build YASM source files

I am using CMake 3.4.1 to generate and build Visual Studio 2013 64bit C++ solution.One of the project also contains .asm files which we compile in VisualStudio with yasm assembler as lib.How do I configure CMake to use yasm for those files?I haven't found any documentation with example of how to set it up.
Have a look a the following example:
cmake_minimum_required(VERSION 3.0)
project(YasmCmake)
find_program(YASM_EXE NAMES yasm)
add_custom_command(OUTPUT hello.o COMMAND ${YASM_EXE}
ARGS -f elf64 -o hello.o ${CMAKE_CURRENT_SOURCE_DIR}/hello.asm)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
add_library(Hello hello.o)
set_target_properties(Hello PROPERTIES LINKER_LANGUAGE CXX)
Of course you need to specify the flags for yasm depending on your platform.

c++ compile multiple cpp files using cmakefile.txt in linux

I am quite new to linux and c++.. i have couple of cpp file and cmakefile.txt in my source folder. how can i compile in ubuntu with g++ (multiple cpp files)
I have this CMakeList.txt
project(Test)
# link_libraries($Nest_LIBRARIES})
subdirs(
#
engine
options
ui
# jni
)
#build the Test library
add_library(test STATIC
options/command_line_options.cpp
options/options_map.cpp
utility/timer.cpp
utility/generics/any.cpp
util/hdfs.cpp
logger/logger.cpp
logger/backtrace.cpp
)
requires_core_deps(test)
INSTALL(TARGETS
test ARCHIVE DESTINATION lib)
This is CMake (tutorial). Some say it simplifies build process.
Create makefiles from CMake metafiles: cmake . -G "Unix
Makefiles"
Run make: make -j2 install