Motivation
Xcode provides the ability to manipulate whatever compiler/linker toolchain is needed, but default Xcode configuration assumes Mac SDK and adds a number of default flags that do not appear anywhere in the project itself.
If these flags could be disabled/removed, Xcode's native build system could be used to control foreign compilers/toolchains such as xtensa-elf-gcc and surrounding tools, while gaining the benefit of Xcode's code highlighting and clang's analytics. This would be a strongly preferable option to the external makefile option that Xcode supports directly, which does not integrate particularly nicely with the rest of Xcode.
Motivation TL;DR
If Xcode's default flags could be disabled, Xcode could directly support compiling code for the ESP8266 (using CC=xtensa-elf-gcc).
The default flags (which assume Mac OS) are not supported by xtensa-elf-gcc and prevent its use.
The flags are the only reason this does not work.
Example
The most basic compilation produces a clang command with these flags:
-x c
-arch x86_64
-fmessage-length=0
-fdiagnostics-show-note-include-stack
-fmacro-backtrace-limit=0
-std=gnu99
-Wno-trigraphs
-fpascal-strings
-O0
-fno-common
-Wno-missing-field-initializers
-Wno-missing-prototypes
-Werror=return-type
-Wdocumentation
-Wunreachable-code
-Werror=deprecated-objc-isa-usage
-Werror=objc-root-class
-Wno-missing-braces
-Wparentheses
-Wswitch
-Wunused-function
-Wno-unused-label
-Wno-unused-parameter
-Wunused-variable
-Wunused-value
-Wempty-body
-Wconditional-uninitialized
-Wno-unknown-pragmas
-Wno-shadow
-Wno-four-char-constants
-Wno-conversion
-Wconstant-conversion
-Wint-conversion
-Wbool-conversion
-Wenum-conversion
-Wshorten-64-to-32
-Wpointer-sign
-Wno-newline-eof
-DDEBUG=1
-isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.12.sdk
-fasm-blocks
-fstrict-aliasing
-Wdeprecated-declarations
-mmacosx-version-min=10.12
-g
-Wno-sign-conversion
-Winfinite-recursion
-iquote [generated-files.hmap]
-I[own-target-headers.hmap]
-I[all-target-headers.hmap]
-iquote [project-headers.hmap]
-I[Build/Products/Debug/include]
-I[Build/Intermediates/libESP8266.build/Debug/libESP8266.build/DerivedSources/x86_64]
-I[Build/Intermediates/libESP8266.build/Debug/libESP8266.build/DerivedSources]
-F[Build/Products/Debug]
-MMD
-MT dependencies
-MF [Build/Intermediates/libESP8266.build/Debug/libESP8266.build/Objects-normal/x86_64/main.d]
--serialize-diagnostics [Build/Intermediates/libESP8266.build/Debug/libESP8266.build/Objects-normal/x86_64/main.dia]
-c /Users/asher/Projects/Arduino/libESP8266/main.c
-o [main.o]
Obviously a few of these are more or less necessary (-c, -o, the various -Is, etc.) but most ought to be totally optional.
The Question
So where are they coming from? I've tried editing the basic template, and even after reducing all Mac related aspects, the result is the same. Are they added programmatically somewhere? If so, it is (presumably) in DevToolsCore or IDEFoundation?
They come from XCode "Build Settings". You could add your own compiler via "Build Options". Does that not work for you?
You could also configure Alternative Toolchains in XCode (never tried it).
There is an answer, but it's not a convenient one.
Xcode build implementation can be found at:
/Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin
The core definition appears to be assembled from .xcspec files in various plugins that can be found in:
/Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins
In particular, for clang and ld, check out:
/Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins/Clang\ LLVM\ 1.0.xcplugin/Contents/Resources/Clang\ LLVM\ 1.0.xcspec
/Applications/Xcode.app/Contents/PlugIns/Xcode3Core.ideplugin/Contents/SharedSupport/Developer/Library/Xcode/Plug-ins/CoreBuildTasks.xcplugin/Contents/Resources/Ld.xcspec
Depending what you are looking for, you may have to dig. If you're looking for a specific build setting, find it in the Xcode build settings inspector and then search text contents for the corresponding variable name.
Theoretically the .xcspec files allow bundle identifiers and inheritance descriptions to assemble whatever build results you want. As far as I know, these details are not well documented / not documented at all.
Since Apple has restricted Xcode plugins to Apple only, it may not be possible to extend the build definition in a sensible way at the user level. It is possible to modify the default system, but then you end up with only the modified version.
Perhaps others have figured out or will later figure out more about how to take advantage of this setup, in which case I will update the answer to reflect our best knowledge.
Related
I've been looking to modify the build flags under Arduino's IDE 1.x, or even the Arduino CLI (which I haven't used but am willing to adopt) such that I can undefine -std=gnu++11 and instead define -std=gnu++14
I found a question related to this which gives me almost what I need:
Arduino 1.0.6: How to change compiler flag?
But it only shows how to add flags, not to remove them. I found another related post about changing arduino to GNU C++17 but the answer was it's not possible.
In this case, I know it's possible, as I do it in Platform IO in order to use the htcw_gfx library. It works great on most platforms that will run GFX reasonably anyway.
But I just don't know how to fiddle with Arduino to get it to dance the way I need to.
Any help would be greatly appreciated.
You can modify the default compile flags in the hardware/arduino/avr/platform.txt file.
$ grep -n "std" hardware/arduino/avr/platform.txt
23:compiler.c.flags=-c -g -Os {compiler.warning_flags} -std=gnu11 -ffunction-sections -fdata-sections -MMD -flto -fno-fat-lto-objects
28:compiler.cpp.flags=-c -g -Os {compiler.warning_flags} -std=gnu++11 -fpermissive -fno-exceptions -ffunction-sections -fdata-sections -fno-threadsafe-statics -Wno-error=narrowing -MMD -flto
For some linux systems the following would work to automatically do this:
dirname $(realpath $(which arduino)) | xargs -I{} sed -i "s/\(std=gnu++1\)1/\14/" {}/hardware/arduino/avr/platform.txt
But this is not very portable, and will not work if the user has installed Arduino with Snap (as snap has these files mounted RO).
Sources:
https://stackoverflow.com/a/28047811/6946577
https://stackoverflow.com/a/55254754/6946577
I recently installed LLVM v8.0.0 (on RHEL 7.4). I am going through the LLVM Kaleidoscope tutorial to learn how to use the system, but am running into an issue linking.
Per the tutorial (end of chapter 2), I run:
clang++ -g -O3 kld.cpp `llvm-config --cxxflags` -o kld
It compiles, but the linker fails on:
/tmp/kld-f7264f.o:(.data+0x0): undefined reference to `llvm::EnableABIBreakingChecks'
clang-8: error: linker command failed with exit code 1 (use -v to see invocation)
I suspected this may have been an issue with llvm-config, so I also tried using the --ldflags and --system-libs flags, but no luck.
llvm-config --cxxflags gives (reformatted for readability)
-I~/project/llvm-src/include -I~/project/llvm-build/include
-fPIC -fvisibility-inlines-hidden
-std=c++11
-Wall -Wextra -Wno-unused-parameter -Wwrite-strings -Wcast-qual
-Wno-missing-field-initializers -pedantic -Wno-long-long
-Wno-maybe-uninitialized -Wdelete-non-virtual-dtor -Wno-comment
-g
-fno-exceptions -fno-rtti
-D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS
-D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS
Where ~/... is just the path to my home directory (edited for privacy; the actual output is a fullpath). I am working on a shared system that requires I install new software locally.
The tutorial code never references ABI explicitly, so I assume this must be some kind of compiler-flags issue. greping for the missing symbol in non-binary files gives an extern declaration in include/llvm/Config/abi-breaking.h and the real declaration in lib/Support/Error.cpp:
#if LLVM_ENABLE_ABI_BREAKING_CHECKS
int EnableABIBreakingChecks;
#else
int DisableABIBreakingChecks;
#endif
I thought I would try re-compiling, then, with -DLLVM_ENABLE_ABI_BREAKING_CHECKS. That also does that work.
I'm not really clear what the ABI breaking checks are doing in the first place, and this may be way over my C++ comfort level. But how can I silence this error, if I don't need the referenced functionality; or fix it, if i do?
Thanks.
Turns out the answer was hidden in abi-breaking.h:
/* Allow selectively disabling link-time mismatch checking so that header-only
ADT content from LLVM can be used without linking libSupport. */
#if !LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING
I'm not sure if I'll need libSupport down the line, but compiling with LLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING=1 works for the time being.
Add linkage with LLVMSupport library will also solve this problem.
With this CMake snippet:
find_package(LLVM REQUIRED CONFIG)
message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}")
message(STATUS "Using LLVMConfig.cmake in: ${LLVM_DIR}")
add_executable(main main.cpp)
target_link_libraries(main LLVMSupport)
Based on the discussion in llvm irc channel.
Try the following command to compile : clang++ -O3 -c $(llvm-config --cxxflags) source_file.cpp -o obj_code.
Then try linking with this command : clang++ obj_code $(llvm-config --ldflags --libs) -lpthread.
I think linking part doesn't mentioned in the kaleidoscope section. The above solution worked for me.
I don't know the influence and reason why it works. But when I add -DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING, the errors disappear.
clang++ xxx -DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING
ref:
https://www.coder.work/article/6278120
https://blog.csdn.net/qq_37887537/article/details/112790961
We are building an application depending on Boost, and compilation generates a lot of warning "Class member cannot be redeclared" in a Boost header (tag_of.hpp).
To avoid spamming the build log, we decided to include Boost headers as system headers:
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
Our understanding is that this command should put Boost include directory behind a -isystemcompiler flags. Yet it does no such thing, instead putting it alongside 'normal' include directories in the header search path.
The environment is CMake 3.0.0, generating a project file for Xcode 5.1.1.
This seems to be an issue with some others (see last two comments in this answer).
Is there a working way to include headers as system ?
EDIT: Just tested in the same environment, updating CMake to version 3.3.0, and the behaviour is the same.
EDIT: Here is a minimal example that is showing the issue on my environment
cmake_minimum_required(VERSION 3.0)
find_package(Boost 1.49 COMPONENTS)
project(system_dependencies)
add_executable(${PROJECT_NAME} main.cpp)
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${Boost_INCLUDE_DIRS})
The Xcode project file generated from this script places the path to Boost in the build setting: Header search path, instead of appending it behind a -isystem compiler flag. Which is confirmed by the compilation command issued by the IDE:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang
-x c++ -arch x86_64 -fmessage-length=0 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit=0 -Wno-trigraphs -fpascal-strings -O0 -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-return-type -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wno-missing-braces -Wparentheses -Wswitch -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wno-unused-variable -Wunused-value -Wno-empty-body -Wno-uninitialized -Wno-unknown-pragmas -Wno-shadow -Wno-four-char-constants -Wno-conversion -Wno-constant-conversion -Wno-int-conversion -Wno-bool-conversion -Wno-enum-conversion -Wno-shorten-64-to-32 -Wno-newline-eof -Wno-c++11-extensions -DCMAKE_INTDIR=\"Debug\" -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.9.sdk
-fasm-blocks -fstrict-aliasing -Wdeprecated-declarations -Winvalid-offsetof -mmacosx-version-min=10.9 -g -Wno-sign-conversion -I/Users/.../system_dependencies/build/Debug/include
-I/Users/.../SDK/boost/include
......
This issue looks to only occur for the XCode generator, as CMake believes it doesn't support the isystem flag. I would think the best solution is to report this issue on CMake bug tracker.
What set of GCC options provide the best protection against memory corruption vulnerabilities such as Buffer Overflows, and Dangling Pointers? Does GCC provide any type of ROP chain mitigation? Are there performance concerns or other issues that would prevent this GCC option from being on a mission critical application in production?
I am looking at the Debian Hardening Guide as well as GCC Mudflap. Here are the following configurations I am considering:
-D_FORTIFY_SOURCE=2
-fstack-protector --param ssp-buffer-size=4
-fPIE -pie
-Wl,-z,relro,-z,now (ld -z relro and ld -z now)
Are there any improvments that can be made to this set of options? Assume the most recent version of GCC, if you know of any cool upcoming feature, let me know!
Not a GCC option, but compatible with GCC. See our CheckPointer tool, that detects most memory management errors.
There is a significant slowdown in execution; the tool has to track the validity of pointers and allocated storage, and that adds overhead.
This is not a CFLAGSor LDFLAGS answer so maybe not what you're specifically looking for but you should also look into gcc plugins written for hardening purposes. These are used in hardened kernel builds and catch a lot of bad code. You may need need a gcc plugins package for your distribution, apt-cache search gcc | grep plugin or equivalent to find the package name. I believe llvm compiler suite has similar plugins if you're willing to consider using their clang compiler (it's mostly gcc compatible)
See What is the most hardened set of options for GCC compiling C/C++.
So, reasonable options provided bellow.
Warnings:
-Wall -Wextra -Wformat-security -Werror
Hardenings:
-mmitigate-rop -Wstack-protector -fstack-protector-strong -fstack-clash-protection -pie -fPIE -D_FORTIFY_SOURCE=2 -Wl,-z,rel -Wl,dynamicbase -Wl,nxcompat
Good for patching:
-fvtable-verify=std
I'm working on a large collaborative C++ project that is both developed and run on various flavors of Linux, OS X and Windows. We compile across these platforms with GCC, Visual Studio C++ and the Intel C++ compiler. As more and more people start developing code for the project, we're starting to see weird errors in compilation and runtime that are specific to particular compilers on particular operating systems. An example of this is implicit inclusion of headers that certain OS/compiler pairs seem to find for you, accidentally overloading a function from a base class in a derived class.
My goal is to make compilation on GCC more strict and catch more errors across all platforms so that we don't keep running into these problems. Here's my list of flags that I'm thinking about trying out for GCC that I've found via Google and the GCC man pages:
-Wall
-Wextra
-Winit-self
-Wold-style-cast
-Woverloaded-virtual
-Wuninitialized
-Wmissing-declarations
-Winit-self
-ansi
-pedantic
What are the other flags that people use to make GCC (and less importantly Visual Studio C++ and the Intel C++ Compiler) obey a stricter standard of the C++ language? Be specific about which compiler and version you're talking about, as some of these might not be implemented in all versions of all compilers.
Beside the pedantic-error that everyone else suggested, IMO, it's always good to run lint as part of your compile process.
There are some tools out there:
cpplint (free)
gimple lint
coverity
They will save a lot of your time.
You can make pedantic warnings into errors with -pedantic-errors. This will prevent developers from ignoring it. For that matter you could make all warnings into errors as well with -Werror although that can be counter productive in some cases (maybe not in yours though).
Overall, I think, as far as adhering to a strict standard goes, the -pedantic options are the most helpful.
Copy and paste the below line into your master CMake file. The below line comprises almost most useful compiler flags in order to test yourself stricter.
set(CMAKE_CXX_FLAGS "-O0 -fno-elide-constructors -pedantic-errors -ansi -Wextra -Wall -Winit-self -Wold-style-cast -Woverloaded-virtual -Wuninitialized -Wmissing-declarations -Winit-self -std=c++98")
If you don’t use CMake, just copy the flags in double quotes and send them to your compiler.
-pedantic-errors.
See more on gcc(1).
As well as -pendantic, you should also provide a -std switch. If you need a stricter compile then you should know what standard you are trying to conform to. Typically for current C++ this would be -std=c++98. (-ansi performs a similar function in C++ mode, but -std= is more explicit.)
In a similar situation we gave up and moved to the ACE framework, hiding the difference between platforms.
I wrote a blog post on this topic after researching several options. You also need to handle the cases where you are using other libraries, but they are not following strict compilation. Fortunately, there is an easy way to handle them as well. I have been using this extensively in all my projects.
In short, use the following compiler options to turn on very strict mode (below is what I put in CMakeLists.txt):
set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -Wstrict-aliasing -pedantic -fmax-errors=5 -Werror -Wunreachable-code -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wlogical-op -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-promo -Wstrict-null-sentinel -Wstrict-overflow=5 -Wswitch-default -Wundef -Wno-unused -Wno-variadic-macros -Wno-parentheses -fdiagnostics-show-option ${CMAKE_CXX_FLAGS}")
You can read more about how to turn on and off this strict mode for specific portions of code here: http://shitalshah.com/p/how-to-enable-and-use-gcc-strict-mode-compilation/